汇编语言中AddTwo过程的参数传递机制及调用形式解析
关于AddTwo过程参数传递的详细解答
好的,咱们一步步拆解你关于AddTwo过程的几个疑问:
1. val1和val2是否来自栈?是的!
在MASM默认的stdcall调用约定下,调用者会把参数从右往左依次压入栈中,然后调用AddTwo过程。所以val1和val2这两个参数的值,确实是存储在栈上的。
2. 具体如何从栈中取用?
你看到的val1和val2其实是MASM汇编器提供的符号别名,它们对应着栈上的特定内存偏移。
当调用者执行call AddTwo后,栈的布局大概是这样的(从栈顶到栈底):
- 第1个位置:调用者的返回地址(由
call指令自动压入,占4字节) - 第2个位置:
val1的值(调用者压入的第一个参数,偏移[esp+4]) - 第3个位置:
val2的值(调用者压入的第二个参数,偏移[esp+8])
MASM的PROC伪指令会自动帮我们处理这些偏移映射,所以你写mov eax, val1时,汇编器会自动翻译成对应的栈内存读取指令(比如mov eax, [esp+4]),不需要手动计算偏移,非常方便。
另外补充一点:如果过程里使用了栈帧(比如开头加push ebp、mov ebp, esp),那val1会对应[ebp+8],val2对应[ebp+12]——本质还是读取栈上的数据,只是通过EBP寄存器来寻址更稳定,避免esp变化影响偏移。
3. 调用该过程的函数形式
汇编层面的调用示例
用MASM风格的汇编调用AddTwo的话,代码大概是这样:
; 准备参数:先压入右边的val2,再压入左边的val1 push 10 ; val2 = 10 push 20 ; val1 = 20 call AddTwo ; 调用后,EAX里就是30 ; 因为是stdcall约定,AddTwo的ret指令会自动清理栈(相当于ret 8),所以这里不用手动add esp,8
C语言对应的函数形式
如果要在C代码中调用这个汇编过程,对应的函数原型应该是:
int AddTwo(int val1, int val2);
调用示例:
int sum = AddTwo(15, 25); // sum的值会是40,因为汇编过程把结果存在EAX中,C语言会自动从EAX读取返回值
内容的提问来源于stack exchange,提问作者Romin
相关产品推荐
相关产品推荐

