Author Topic: Difference between MASM and NASM for the MOV opcode.  (Read 11758 times)

Offline dlebansais

  • Jr. Member
  • *
  • Posts: 3
Difference between MASM and NASM for the MOV opcode.
« on: January 04, 2018, 02:20:21 PM »
I'm trying to port my code from MASM to NASM, and trying to obtain exactly the same generated binary (or as close as possible). But I've ran into an issue with MOV r/m32,imm32.

I wrote a sample code test.asm to demonstrate my problem, compiled for Win64:

Code: [Select]
; MASM

PUBLIC test_data
PUBLIC test_function

.data
test_data dword -1

.code

test_function PROC

mov         test_data,0

test_function ENDP

END

Code: [Select]
; NASM

GLOBAL test_data
GLOBAL test_function

SECTION .data

test_data dd -1

SECTION .text

test_function:
mov dword [test_data], 0

Using DUMPBIN on Windows 64 bits I can see I'm getting the following output:

Code: [Select]
/*This is an excerpt of the result of "ml64 /nologo /c /W3 /Zf /Zi test.asm" */
test_function:
  0000000000000000: C7 05 00 00 00 00  mov         dword ptr [test_data],0
                    00 00 00 00

RAW DATA #1
  00000000: C7 05 00 00 00 00 00 00 00 00                    Ç.........

Code: [Select]
/*This is an excerpt of the result of "nasm -f win64 test.asm" */
test_function:
  0000000000000000: C7 04 25 00 00 00  mov         dword ptr [.data],0
                    00 00 00 00 00

RAW DATA #2
  00000000: C7 04 25 00 00 00 00 00 00 00 00                 Ç.%........

As you can see, NAMS outputs C7 04 25 when MASM outputs C7 05. I don't worry too much about the difference, but it prevents me from comparing binaries, and the same issue happens on most instructions. MOV is just an example.

For the life of me, I cannot get NASM to give me the same output. I've been trying to fix it for hours, and searched this forum but unsuccessfully. Does anyone have a suggestion?


Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Difference between MASM and NASM for the MOV opcode.
« Reply #1 on: January 04, 2018, 06:07:14 PM »
You can't compare binaries this way. There are many things in-between that may alter the binaries. It depends on the assembler and the linkers. I dont know much about MASM but i'll give it a try

Try using "mov dword[rel test_data],0" instead. I am pretty sure it will emit the same encoding. This has something to do with relative addressing. NASM and MASM may have different ways in interpreting relative addressing.

Different linkers may use different relocation strategies as well.

Plus, dumpbin is part of MS toolchain that interpret binaries from MASM point of view. You may have to be more careful when interpreting output from MS products and toolchain (CL, LINK, LIB etc) for NASM use.


Offline dlebansais

  • Jr. Member
  • *
  • Posts: 3
Re: Difference between MASM and NASM for the MOV opcode.
« Reply #2 on: January 04, 2018, 07:07:44 PM »
Thank you very much for the suggestion. I didn't know about 'rel' (I'm new to NASM), and I will most definitely try it as soon as I return to the office.

Regarding the rest of your reply, I guess I should elaborate. Yes, I'm aware I can't obtain the exact same binary with MASM and NASM, but it's a worthy goal because if I could, that would mean porting the code is successful and I don't even need to test. So I use DUMPBIN to compare binaries, eliminating from the output all irrelevant things such as date and time, checksum, debug sections and so on.

If the content of code and data sections are identical, I can with high confidence tell my boss 'it's done' and submit to test, right?

Regarding relocations, I believe this can be controlled from the assembler (whether an instruction is subject to relocation or not), and you most definitely want all relocations to be the same regardless of the assembler. Beside, the output of NASM is an object, and I use the same linker afterward, so the linker is out of the equation.



Offline dlebansais

  • Jr. Member
  • *
  • Posts: 3
Re: Difference between MASM and NASM for the MOV opcode.
« Reply #3 on: January 08, 2018, 01:21:34 PM »
To follow up with this, [rel...] didn't do it, but DEFAULT REL worked beautifully. Thanks again!