In nasm (2.14.02), this instruction
add rbx, 0xffffffff
leads to warning: signed dword value exceeds bounds [-w number-overflow]
. I'm aware that arithmetic-logic operations in 64-bit mode only accept constants with 32 bit, but 0xffffffff is still 32 bit wide.
Why does nasm emit a warning, and why does it assume a signed constant? Does it sign-extend the 32-bit -1
to 64-bit -1
(0xffffffffffffffff) and therefore see an overflow? 0x7fffffff works without a warning.
Can I somehow convince nasm
that this is not a signed constant, but an unsigned one?
CodePudding user response:
0x00000000FFFFFFFF can't be encoded as a 32-bit sign-extended immediate, and x86 immediates are always sign-extended when they're narrower than the operand-size.
Your theory is somewhat correct, the instruction adds the value specified to the register. There is no way to encode an instruction that adds 0xffffffff to the register, because the only available encodings for add
ing an immediate to a 64-bit register are add r/m64, sign_extended_imm32
or add r/m64, sign_extended_imm8
. Only one special encoding of mov
(with a register destination) can use a 64-bit immediate.
The obvious encoding (stuffing 0xffffffff
into an imm32
) would in fact add 0xffffffffffffffff to rbx which is not what you requested and would be the same as add rbx, -1
There is no way to encode a value into the 32 bit field that results in 0x00000000ffffffff being added to rbx. Asm source uses values, not bit-patterns for immediates.
You need to do something like this :-
mov rcx, 0xffffffff ; This will zero extend the value
add rbx, ecx