ATL布幔之下的秘密(4)
2006-07-22 22:54:54 来源:WEB开发网核心提示: 现在就有一个问题了,当我们向函数中传递参数的时候,ATL布幔之下的秘密(4)(3),是谁来负责恢复堆栈指针的呢——函数本身还是函数的调用者?事实上,这两种情况都有可能,所以,参数的数目可以由这个数目除以4得知,并且这就是标准调用约定和C调用约定的不同,请看调用函数的
现在就有一个问题了,当我们向函数中传递参数的时候,是谁来负责恢复堆栈指针的呢——函数本身还是函数的调用者?事实上,这两种情况都有可能,并且这就是标准调用约定和C调用约定的不同。请看调用函数的下一条语句: push 10 ; 0000000aH
在这里有两个参数传递给了函数,所以堆栈指针在两个参数入栈后会减去8个字节。现在在这个程序中,设置堆栈指针就是函数调用者的职责了。这就称作C调用约定。在这种调用约定中,你可以传递可变数目的参数,因为调用者知道有多少参数传递给了函数,所以它可以来设置堆栈指针。
push 5
call _fun
add esp, 8
然而,如果你选择了标准调用约定,那么清楚堆栈就是被调用者的工作了。所以在这种情况下,可变数目的参数是不能传递给函数的,因为那样的话函数就没有办法知道到底有多少参数传给了函数,也就无法正常设置堆栈指针了。
请看下面的程序来观察标准调用约定的行为。
程序60. extern "C" void _stdcall fun(int, int) {
现在来看看函数的调用。
}
int main() {
fun(5, 10);
return 0;
}push 10 ; 0000000aH
在这里,函数名称中的@表示这是一个标准调用约定,8则表示被压入堆栈的字节数。所以,参数的数目可以由这个数目除以4得知。
push 5
call _fun@8
以下是我们这个什么也不做的函数的代码: push ebp
这个函数通过“ret 8”指令在返回之前设置了堆栈指针。
mov ebp, esp
pop ebp
ret 8
[]
更多精彩
赞助商链接