PUSH <src>
做:
ESP := ESP-4 ; for x86; -8 for x64
MEMORY[ESP]:=<operandvalue>
POP <dst>
做:
<operandtarget>:=MEMORY[ESP];
ESP:=ESP+4 ; for x86; +8 for x64
如果您将机器指令的描述写成这样的伪代码,则更容易理解机器指令的作用。英特尔参考手册中充满了此类伪代码,值得您花时间和精力去获取它们,并自己阅读详细信息。(例如,在 HTML 摘录中https://www.felixcloutier.com/x86/push和https://www.felixcloutier.com/x86/pop)
关于您的具体问题:您的$5
into存储-4(%esp)
是有效的机器指令,处理器将毫无怨言地执行它,但这确实是非常不安全的编程。如果处理器在该指令之后发生陷阱或中断,则处理器状态(通常)保存在“堆栈顶部”,并将覆盖您的值。由于中断是异步发生的,因此您会看到很少会丢失 5 美元的行为。这使得调试程序非常困难。
"add $4" 将 ESP 移回push 指令之前的位置。因此,您不能对弹出到 ebp 中的值说任何话,除非它是“未知”的,正如您建议的选项之一。
请参阅Raymond Chen 的博客,了解为什么在 ESP 下编写即使在 Windows 下的用户空间也是不安全的。(中断不会异步使用用户空间堆栈,但有些东西可以。)在非 Windows 上,POSIX 信号处理程序可以踩到用户空间 ESP 下方的空间。(除了在 x86-64 System V 中,ABI 定义了一个低于 RSP 的 128 字节的“红色区域”,可以安全使用。)