I tried this simple assembly:
add r9, 0x4014000000000000
It gave me error:
Error: operand type mismatch for `add'
I also try:
addq r9, 0x4014000000000000 #(second operand is 64-bit)
which q stand for quad 64-bit, CMIIW.
I'm sure r9
is 64-bit wide.
I also try:
add r9, 0xffffffffffffffff #(second operand is 64-bit too)
But this time where second operand is 0xffffffffffffffff
which it's 64-bit operand is working fine, so what was happened?
There is no encoding that supports a 64-bit immediate on the add
instruction, just like it is the case for the majority of instructions.
To add r9, 0x4014000000000000
, move the immediate to a scratch register and add that to R9.
mov rax, 0x4014000000000000
add r9, rax
Your add r9, 0xffffffffffffffff
instruction does work because in this case 'the very big' immediate value is in fact just -1, and that's a value that nicely fits the encoding that sign-extends a 32-bit immediate into a 64-bit value. The assembler will even do better and use a single byte immediate to encode this instruction.
Your add r9, 0xffffffffffffffff
is actually add r9, -1
.
For 64-bit values in [0xFFFFFFFFFFFFFF80, 0x000000000000007F], (-128, +127) the assembler encodes a sign-extendable 8-bit immediate.
For 64-bit values in [0xFFFFFFFF80000000, 0x000000007FFFFFFF], (-2147483648, +2147483647) the assembler encodes a sign-extendable 32-bit immediate.
Other 64-bit values cannot be encoded.