3

As the question states, What's the difference between (for example) mov eax, 0 and mov eax, dword 0?

I've been using cmp statements, and I can't catch the difference. Is one an address and the other a numerical value?

Wulf
  • 153
  • 1
  • 8

3 Answers3

4

As stated, no difference for the MOV instruction. For CMP, you would have difference between

CMP memory address of a qword,a 32 bit immediate

is different from

CMP memory address of a qword,an 8 bit immediate

as the comparison will be done after a sign extension, and hence, with a smaller dimension immediate number, expecially when its a negative number, some caution is advised.

Have fun programming...

quasar66
  • 555
  • 4
  • 14
  • 2
    @Wulf: NASM syntax also lets you override the default of picking the smallest size to encode the displacement in an effective address. e.g. `[rax + 32]`: mod/rm + 8bit displacement. `[rax + dword 32]`: mod/rm + 32b displacement. It's useful if you want to request the assembler uses a larger encoding, either for alignment reasons (instead of NOPs for padding) or because you're going to rewrite a placeholder value. If you don't have a good reason like that, just let the assembler pick the smallest encoding for what you wrote. – Peter Cordes Dec 17 '15 at 03:03
  • Correction, the encoding override has to have `dword` at the start of the `[]`. Like `mov ecx, [dword 1 + rax]`. Otherwise NASM rejects it. – Peter Cordes Oct 10 '20 at 09:55
2

It does not make a difference with a register since the name of the register already tells the assembler "how big" the data item (in this case, 0) is:

mov   eax, dword 0    ; move a 4-byte 0 into eax
mov   eax, 0          ; move a 0 into eax (eax is 4 bytes, so move 4 bytes)

However, there are cases where you might want to be able to specify how large the value is since there's a choice. In x86 32-bit assembly, the following would push a 4-byte 0 value on the stack:

push   0             ; push 4-byte 0 onto the stack

If you wanted to push a 2-byte 0 value, you would use:

push   word 0

If you wanted to be explicit so it's clear for the 4-byte immediate push, you could use the dword:

push   dword 0

If you want to move an immediate value to memory, the size specifier becomes necessary because the assembler doesn't know how large the data item is otherwise. For example, consider the following code in nasm assembly:

        section  .bss
num     resb     4

        ...
        section  .text
        ...
        mov    [num], 0

This will generate an error:

 error: operation size not specified

So you need to specify the size, say, 4-bytes:

        mov    [num], dword 0
lurker
  • 56,987
  • 9
  • 69
  • 103
  • It could affect the encoding of `cmp eax, byte 0` vs. `cmp eax, dword 0`. There is no `mov r32, imm8` sign-extending immediate operand, though. See my comment on Quasar's answer. Actually nvm, `add ebx, dword 1` doesn't change YASM's behaviour: still an imm8. – Peter Cordes Dec 17 '15 at 03:18
  • @PeterCordes yes, good point. An attempt to do that with `mov` gives a mismatched operand size error in `nasm`, but `cmp` allows different sized operands. It's probably assembler dependent in that area. – lurker Dec 17 '15 at 03:24
1

They are exactly the same thing, it's just assembler syntax.

As a side note, xor eax, eax is generally preferred since it generates a two byte instruction which is much smaller.

Olipro
  • 3,489
  • 19
  • 25
  • Actually `xor eax, eax` is two bytes long. First byte for the opcode, second byte for the mod R/M. – Nayuki Dec 17 '15 at 02:45
  • [Does using xor reg, reg give advantage over mov reg, 0?](http://stackoverflow.com/q/1135679/995714), [Any reason to do a “xor eax, eax”?](http://stackoverflow.com/q/1396527/995714) – phuclv Dec 17 '15 at 03:07
  • Xor eax,eax changes value of the flags, so you potentially could lose the status of a previous comparison, and therefore, use of an instruction like CMOVcc or SETcc, whereas, MOV does not impact any flags – quasar66 Dec 17 '15 at 03:41