在NASM(2.14.02)中,指令add rbx, 0xffffffff导致警告:有符号双字值超出界限[-w+数字溢出]我知道64位模式下的算术逻辑运算只接受32位的常量,但0xffffffff仍然是32位宽。为什么NASM发出警告,为什么它假定一个 signed 常量?它是否将32位-1符号扩展为64位-1(0xffffffffffffff),因此看到溢出?0x 7 fffffff工作时没有警告。我能以某种方式使NASM相信这不是一个有符号常量,而是一个无符号常量吗?
add rbx, 0xffffffff
-1
j2datikz1#
0x 00000000 FFFFFFFF不能编码为32位符号扩展立即数,并且x86立即数在比操作数大小更窄时总是进行符号扩展。您的理论在某种程度上是正确的,指令将指定的值添加到寄存器。无法对将0xffffffff添加到寄存器的指令进行编码,因为the only available encodings for add将立即数添加到64位寄存器是add r/m64, sign_extended_imm32或add r/m64, sign_extended_imm8。只有mov的一种特殊编码(带有寄存器目标)可以使用64位立即数。显而易见的编码(将0xffffffff填充到imm32中)实际上会将0xffffffffffffffff添加到rbx中,这不是您所请求的,而是与add rbx, -1相同没有办法将一个值编码到32位字段中,导致0x 00000000 ffffffff被添加到rbx。Asm源使用值,而不是立即数的位模式。你需要这样做:-
add
add r/m64, sign_extended_imm32
add r/m64, sign_extended_imm8
mov
0xffffffff
imm32
add rbx, -1
mov rcx, 0xffffffff ; RCX = 0xFFFFFFFF = 0x00000000FFFFFFFF add rbx, rcx
mov ecx, 0xffffffff也将以相同的方式设置RCX; NASM将为您优化为一个有效的5字节指令(使用implicit zero-extension to 64-bit when writing a 32-bit register),而不是需要一个带有64位立即数的10字节指令;请参阅another Q&A以了解有关机器码中MOV的不同形式的更多信息。
mov ecx, 0xffffffff
1条答案
按热度按时间j2datikz1#
0x 00000000 FFFFFFFF不能编码为32位符号扩展立即数,并且x86立即数在比操作数大小更窄时总是进行符号扩展。
您的理论在某种程度上是正确的,指令将指定的值添加到寄存器。无法对将0xffffffff添加到寄存器的指令进行编码,因为the only available encodings for
add
将立即数添加到64位寄存器是add r/m64, sign_extended_imm32
或add r/m64, sign_extended_imm8
。只有mov
的一种特殊编码(带有寄存器目标)可以使用64位立即数。显而易见的编码(将
0xffffffff
填充到imm32
中)实际上会将0xffffffffffffffff添加到rbx中,这不是您所请求的,而是与add rbx, -1
相同没有办法将一个值编码到32位字段中,导致0x 00000000 ffffffff被添加到rbx。Asm源使用值,而不是立即数的位模式。
你需要这样做:-
mov ecx, 0xffffffff
也将以相同的方式设置RCX; NASM将为您优化为一个有效的5字节指令(使用implicit zero-extension to 64-bit when writing a 32-bit register),而不是需要一个带有64位立即数的10字节指令;请参阅another Q&A以了解有关机器码中MOV的不同形式的更多信息。