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

Can I encode a 64-bit negative immediate in x86?

我正在尝试自学 x86,我 运行 需要 return 一个即时的负数:

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

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

$ ./neg                                                 
4294967254

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

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

32 位指令的 32 位立即数(如 movl)按原样使用,writing EAX zeros the upper 32 bits of RAX。你不是在胡说八道,你得到的是 2^32 - 42,这正是你应该期望的,因为 x86 使用 2 的补码有符号整数。

具有 64 位操作数大小的指令的 32 位立即数被符号扩展为 64 位。

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

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