1. 汇编语言参数传递基础
在高级语言中,函数调用和参数传递对我们来说就像呼吸一样自然,但在汇编层面,这些看似简单的操作背后隐藏着一整套精密的机制。理解参数传递和堆栈修正是掌握汇编编程的关键门槛,也是从"写汇编代码"到"真正理解计算机工作原理"的重要转折点。
x86架构下的参数传递主要分为寄存器传参和堆栈传参两种方式。寄存器传参速度快但数量有限,而堆栈传参则能处理更多参数,也是C语言等高级语言默认采用的调用约定(Calling Convention)。当我们在C语言中写下func(a, b, c)这样的调用时,编译器实际上在背后为我们生成了一系列的堆栈操作指令。
关键提示:不同操作系统和编译器可能采用不同的调用约定。Windows平台常用的是
__stdcall,而Linux平台多用__cdecl,它们在参数入栈顺序和堆栈平衡责任方上有所区别。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 堆栈传参的底层原理
2.1 堆栈帧结构剖析
每次函数调用时,系统都会在堆栈中创建一个栈帧(Stack Frame),其典型结构如下:
code复制高地址
+----------------+
| 参数n |
| ... |
| 参数2 |
| 参数1 |
+----------------+
| 返回地址 |
+----------------+
| 保存的EBP | <-- EBP
+----------------+
| 局部变量 |
| ... |
低地址
当调用func(a,b,c)时,参数会按照调用约定确定的顺序压栈。以__cdecl为例,参数从右向左压栈,即先压c,再b,最后a。调用结束后,调用者负责清理堆栈(add esp, 12)。
2.2 参数访问的两种方式
在函数内部,访问参数有两种基本方法:
- 通过EBP相对寻址:
assembly复制mov eax, [ebp+8] ; 第一个参数
mov ebx, [ebp+12] ; 第二个参数
- 通过ESP相对寻址(适用于未保存EBP的情况):
assembly复制mov eax, [esp+4] ; 第一个参数
`
