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

汇编语言中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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:17:37