It does matter what operand-size you use for several reasons, and it would be weird and unintuitive / non-obvious to have the size implied by the integer value. It's a much better design to have NASM error when there's ambiguity because neither operand is a register.
As the two following segments of code will yield the same result:
add byte [ebx], 32
add dword [ebx], 32
They only yield the same result because 'P' + 32
doesn't carry into the next byte.
Flags are set according to the result. If the 4th byte had its high bit set, then SF
would be set for the dword version.
re: comments about how CF works:
Carry-out from an add is always 0
or 1
. i.e. the sum of two N
-bit integers will always fit in an (N+1)
-bit integer, where the extra bit is CF
. Think of the add eax, ebx
as producing the result in CF:EAX
, where each bit can be 0 or 1 depending on the input operands.
Also, if ebx
was pointing at the last byte in a page, then dword [ebx]
could segfault (if the next page was unmapped), but byte [ebx]
wouldn't.
This also has performance implications: read-modify-write of a byte can't store-forward to a dword load, and a dword read-modify-write accesses all 4 bytes. (And correctness if another thread had just modified one of those other bytes before this thread stored the old value over it.)
For these and various other reasons, it matters whether the opcode for the instruction that NASM assembles into the output file is the opcode for add r/m32, imm8
or add r/m8, imm8
.
It's a Good Thing that it forces you to be explicit about which one you mean instead of having some kind of default. Basing it on the size of the immediate would be confusing, too, especially when using a ASCII_casebit equ 0x20
constant. You don't want the operand-size of your instructions to change when you change a constant.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…