我可以在x86中编码64位负立即数吗?

时间:2017-10-18 20:34:37

标签: assembly x86 32bit-64bit twos-complement integer-arithmetic

我正在尝试自学x86,而且我已经遇到需要立即返回负数的问题:

.text
.align 4,0x90
.globl _scheme_entry
_scheme_entry:
movl $-42, %eax
ret

当我打印此函数的返回值(printf("%" PRIdPTR "\n", scheme_entry())时,我得到一个无意义的数字:

$ ./neg                                                 
4294967254

我猜这是因为它是32位负数,00000000FFFFFFFF,而不是64位负数,FFFFFFFFFFFFFFFF。

如何直接在汇编程序函数中存储常量64位值?我是否必须将其编码为两个单独的指令?

1 个答案:

答案 0 :(得分:3)

32位指令的32位即时(如movl)按原样使用,writing EAX zeros the upper 32 bits of RAX。你没有得到废话,你得到2^32 - 42,这正是你应该期待的,因为x86使用了2的补码有符号整数。

对于64位操作数大小的指令,32位立即符号扩展为64位。

使用mov $-42, %rax返回负64位值,而不是略低于2 ^ 32的正64位值。 (使用%rax作为目标意味着64位操作数大小,即movq。)

使用调试器查看寄存器中的值。