堆栈操作深度解析:PUSH/POP 与函数调用的秘密
栈是什么?
栈(Stack)是一种 后进先出(LIFO) 的数据结构。在汇编中,它由 SS:SP 指向。
PUSH 与 POP
PUSH AX ; SP = SP - 2, [SS:SP] = AX
POP BX ; BX = [SS:SP], SP = SP + 2
栈帧结构
函数调用时,栈中会形成栈帧:
高地址
+----------------+
| 参数 2 |
+----------------+
| 参数 1 |
+----------------+
| 返回地址 | ← CALL 自动压入
+----------------+
| 旧 BP | ← PUSH BP
+----------------+ ← BP (当前栈帧基址)
| 局部变量 1 |
+----------------+
| 局部变量 2 |
+----------------+ ← SP (栈顶)
低地址
函数调用流程
; 调用者
PUSH 参数 2
PUSH 参数 1
CALL FUNC
; 被调用者 FUNC:
PUSH BP ; 保存旧栈帧
MOV BP, SP ; 设置新栈帧
SUB SP, 4 ; 分配局部变量空间
; ... 函数体 ...
MOV SP, BP ; 恢复 SP
POP BP ; 恢复旧栈帧
RET ; 弹出返回地址并跳转
为什么需要栈?
1. 保存返回地址:CALL 自动将下一条指令地址压栈
2. 传递参数:通过栈传递,避免寄存器不够用
3. 保存上下文:子程序可以随意使用寄存器,退出前恢复
4. 局部变量:每个函数有独立的栈帧,互不干扰
总结
理解栈,就理解了程序执行的"时间线"。每一次函数调用,都是在栈上翻开新的一页。
下一篇:《标志位详解:CF/ZF/SF/OF 如何影响程序流程》
原文链接:https://wenyiblog.top/2026/06/asm-07-stack-operations/
首发于文艺技术笔记(wenyiblog.top),转载请注明出处。

浙公网安备 33010602011771号