This question already has answers here:
Push and Pop on AMD64 [duplicate]

(1个答案)



Does each PUSH instruction push a multiple of 8 bytes on x64?

(2个答案)


3年前关闭。





NASM返回错误,例如:“ 64位模式不支持指令”,我不知道该怎么办。

主指令是pop ecxpush ecx指令。我可以用什么代替它们,或者有其他方法可以解决此问题?

最佳答案

一般的想法是,您通常压入并弹出完整的寄存器,即64位模式下的64位寄存器。 push的默认操作数大小为64位,而32位操作数大小不可用。 Does each PUSH instruction push a multiple of 8 bytes on x64?(是的,除非您专门使用16位推送,但32位不可用)。
您不能在64位模式下推送32位寄存器。相反,您可以压入并弹出包含所需32位值的整个64位寄存器,因此该push rax而不是push eax。内存引用也是如此-您可以push qword ptr[rax],但不能push dword ptr[rax]
但是:即使在64位模式下,您仍然可以推送:

8或32位立即数符号扩展到64;通常,这是由汇编程序自动进行的优化处理(如果您执行push 1,则会使用最紧凑的编码(6A01,即使用imm8操作数)对其进行编码)。不管汇编器选择立即宽度多大,它都是always a 64-bit push unless you explicitly specify push word 1

fsgs段寄存器,但没有csdsesss寄存器(在64位模式下并不重要,只能用mov读取) ,而不是push,释放那些推送/弹出操作码以备将来使用。
作为例外,段寄存器可以零扩展或以16位的移动量压入堆栈(即堆栈上的其他48位保持不变);这并不是什么大问题,因为pop fspop gs只是丢弃这些多余的位。


您可以使用push imm64 / push low32模拟mov dword [rsp+4], high32。或使用mov r64, imm64 / push r64; mov用来注册(不是内存)是唯一可以立即执行64位立即数的x86-64指令。

使用16位操作数大小(66h前缀),您可以执行16位压入,将RSP调整为2而不是8。但是通常不要这样做,因为它会在您执行16之前使堆栈不对齐位弹出或以其他方式纠正它。

16位寄存器(push ax)和存储器引用(push word ptr[rax]);
8位符号扩展或16位立即数。


8位寄存器不能以任何模式推送(除了作为更宽寄存器的一部分),并且32位在64位模式even with a REX.W=0 prefix中不可用。

关于assembly - 64位模式不支持PUSH和POP指令,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43435764/

10-10 22:27
查看更多