Problem with GAS assembler and LD linker

Programming, for all ages and all languages.
Post Reply
stevencrc
Posts: 2
Joined: Tue Aug 18, 2009 4:33 pm

Problem with GAS assembler and LD linker

Post by stevencrc »

Hi,

I wrote some line of code in asm in NASM:

mov bx,ax

I converted to binary code using: nasm -o test.bin test.s

using ndisasm test.bin, the resulting binary code is: 89C3, it says in ndisasm mov bx ax
(00000000 89C3 mov bx,ax)

and I wrote the exact line of code in GAS syntax:

movw %ax,%bx

I converted to binary code using: gas -o test2.o test2.s && ld --oformat binary -s -o test2.bin test2.s

using ndisasm test2.bin, the resulting binary code is 6689C3 (that is bad), it says in ndisasm mov ebx eax
(00000000 6689C3 mov ebx,eax)

What's happening?? Why GAS and LD are making bad machine code?

Please, I need help...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problem with GAS assembler and LD linker

Post by Combuster »

There are several things in play here
- GAS has its own syntax, which is not the intel syntax. It throws around weird symbols, invents different names for opcodes, and switches operands
- GAS is built for one platform. It will by default emit code for a unix machine, so if you run 32 bit linux, GAS will make code to run in 32 bits mode. If you run 64-bit linux, GAS will emit 64-bit code.
NASM on the other hand is older, and while capable of emitting both 16, 32 and 64 bit code from the same binary, it defaults to 16-bit. You are making a flat binary, which is often used to make DOS (=16 bit) .com files.
- The processor has 16 and 32 (and 64) bits modes. Thee opcodes are shared, but the register sizes are not to save space. Instead, they added prefixes (opcodes 66 and 67) which tell the CPU to swap the instruction from the current mode to the other mode (32->16 or 16->32) GAS needs to execute a 16-bit instruction in 32-bit mode, so it adds the prefix. When a 16-bit disassembler sees that prefix, it will think the next instruction is 32-bits.

So when you next try to interpret 32-bits code as if it were 16-bits code, the result will be off.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
f2
Member
Member
Posts: 311
Joined: Mon Jun 15, 2009 10:01 am
Location: France

Re: Problem with GAS assembler and LD linker

Post by f2 »

stevencrc wrote: movw %ax,%bx
...
(00000000 6689C3 mov ebx,eax)
Add ".code16" at the beginning of your code.

Code: Select all

     .code16
     movw %ax,%bx
"Open source seems to embrace the dark side of human nature." - Ville Turjanmaa
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: Problem with GAS assembler and LD linker

Post by qw »

berkus wrote:Exactly, gas is by default in 32-bit code, while nasm is using good ole 16-bit as default.
When assembling to BIN files.
stevencrc
Posts: 2
Joined: Tue Aug 18, 2009 4:33 pm

Re: Problem with GAS assembler and LD linker

Post by stevencrc »

Thanks for all, was the 32 bit code generated by GAS, I fixed adding .code16.

Thanks for all you are great!! ;)
Post Reply