1
votes

the assembly code is

mov eax, 0x3a14a5
jmp eax

GAS produces an opcode of

0xB8, 0xA5, 0x14, 0x3A, 0x00 
0xFF, 0xE0

while NASM produces and opcode of

0x66, 0xB8, 0xA5, 0x14, 0x3A, 0x00 
0x66, 0xFF, 0xE0

So you see NASM preappends a 0x66 before the code. Within my program (which I won't go into details about), the GAS opcode works correctly, and the NASM code causes a crash indicating that these two opcodes are not equal. Why does NASM preappend the 0x66 and how can I get rid of it?

update: The bits 32 directive worked. Thanks for the quick reply, links, and explanations!

2

2 Answers

3
votes

Put a bits 32 directive at the beginning of your assembly file, and NASM should generate the same machine code as GAS for this instruction.

More info in the NASM manual:

In BITS 32 mode ... 32-bit instructions require no prefixes, whereas instructions using 16-bit data need an 0x66 and those working on 16-bit addresses need an 0x67.

3
votes

http://www.posix.nl/linuxassembly/nasmdochtml/nasmdoca.html:

The codes o16 and o32 indicate that the given form of the instruction should be assembled with operand size 16 or 32 bits. In other words, o16 indicates a 66 prefix in BITS 32 state, but generates no code in BITS 16 state; and o32 indicates a 66 prefix in BITS 16 state but generates nothing in BITS 32

MOV instruction encoding:

MOV reg32,imm32 ; o32 B8+r id

So apparently you are in bits 16 mode. Try prepending your file with a bits flag, eg.

bits 32