You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

64位CPU运行32位代码时栈取值为何用esp+4而非esp+8?

解答

你的认知误区在于默认64位x86 CPU执行所有代码时,PUSH指令都会压入64位数据——这个结论只在CPU运行64位长模式下的64位代码时成立,和你当前的运行场景完全不符。

你的环境是用32位编译器编译程序,最终生成的是32位x86指令,这类程序在64位Windows上会通过WoW64兼容层运行,此时CPU会切换到32位保护模式工作:该模式下默认操作数宽度为4字节,栈指针使用32位的esp寄存器,PUSH指令执行时只会把栈指针减4,再写入4字节的操作数,根本不会按64位规则压8字节数据。

你这段代码的实际栈变化过程如下:

  • 初始状态:esp指向当前栈顶
  • 执行push 11:esp = esp - 4,将11写入esp指向的4字节栈空间,此时栈顶存储值为11
  • 执行push 22:esp = esp - 4,将22写入新的栈顶位置,此时栈空间的布局为:
    • esp + 0(当前栈顶):存储22
    • esp + 4:存储第一次压入的11
push 11
push 22
mov eax, [esp+4]   ; 取到esp偏移4位置的11,完全符合32位栈操作逻辑

补充说明:哪怕CPU运行在64位长模式下,PUSH的操作宽度也不是固定8字节——可以通过指令前缀显式指定压入4字节数据,不存在“64位CPU执行PUSH总会压64位数据”的绝对规则,指令的操作数宽度由运行模式、代码段配置、指令前缀共同决定。

内容的提问来源于stack exchange,提问作者Teddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:51:24