在 masm64 中,如果我编写指令 Push 0,它将在堆栈中压入一个 64 位立即数(即 esp=esp-8)。
所以如果我只是想推一个16位立即数来设置EFLAGS,我没有办法只好写机器码,比如:
.code
FlagFunction PROC
dd 00006866h; push a 16-bit immediate 0
popf
ret
FlagFunction ENDP
END
程序有效,但我想知道 MASM64 中是否有这方面的说明。谢谢。
根据此处的英特尔手册:https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
允许 64 位模式下的 PUSH imm16。 当您在 x86-64 汇编中使用
push imm16
指令将 16 位立即值压入堆栈时,它不会被零扩展。 push imm16
指令将 RSP 调整 2 而不是 8,并且仅将 16 位值压入堆栈。
这是 CPU 使用的算法:
IF StackAddrSize = 64
THEN
IF OperandSize = 64
THEN
RSP := RSP – 8;
Memory[SS:RSP] := SRC; (* push quadword *)
ELSE IF OperandSize = 32
THEN
RSP := RSP – 4;
Memory[SS:RSP] := SRC; (* push dword *)
ELSE (* OperandSize = 16 *)
RSP := RSP – 2;
Memory[SS:RSP] := SRC; (* push word *)
FI
要设置 RFLAGS,您需要
push 0x1234
(符号扩展 imm32 的 qword 推送)/popf
。立即数的低 16 位将成为新的 FLAGS。
它总是影响RSP,而不是ESP。
您 can
push
在 64 位模式下使用 16 位或 64 位操作数大小(但不是 32),但您不想通过 16 位推送暂时错位堆栈。 不指定操作数大小时,push指令入栈多少字节?
据我所知,PUSH 和 POP 在 x64 中总是使用 QWord