WEB开发网
开发学院软件开发VC ATL布幔之下的秘密(4) 阅读

ATL布幔之下的秘密(4)

 2006-07-22 22:54:54 来源:WEB开发网   
核心提示: 现在就有一个问题了,当我们向函数中传递参数的时候,ATL布幔之下的秘密(4)(3),是谁来负责恢复堆栈指针的呢——函数本身还是函数的调用者?事实上,这两种情况都有可能,所以,参数的数目可以由这个数目除以4得知,并且这就是标准调用约定和C调用约定的不同,请看调用函数的

现在就有一个问题了,当我们向函数中传递参数的时候,是谁来负责恢复堆栈指针的呢——函数本身还是函数的调用者?事实上,这两种情况都有可能,并且这就是标准调用约定和C调用约定的不同。请看调用函数的下一条语句: push 10   ; 0000000aH
push 5
call _fun
add  esp, 8
在这里有两个参数传递给了函数,所以堆栈指针在两个参数入栈后会减去8个字节。现在在这个程序中,设置堆栈指针就是函数调用者的职责了。这就称作C调用约定。在这种调用约定中,你可以传递可变数目的参数,因为调用者知道有多少参数传递给了函数,所以它可以来设置堆栈指针。

然而,如果你选择了标准调用约定,那么清楚堆栈就是被调用者的工作了。所以在这种情况下,可变数目的参数是不能传递给函数的,因为那样的话函数就没有办法知道到底有多少参数传给了函数,也就无法正常设置堆栈指针了。

请看下面的程序来观察标准调用约定的行为。

程序60. extern "C" void _stdcall fun(int, int) {
}
int main() {
 fun(5, 10);
 return 0;
}
现在来看看函数的调用。push 10   ; 0000000aH
push 5
call _fun@8
在这里,函数名称中的@表示这是一个标准调用约定,8则表示被压入堆栈的字节数。所以,参数的数目可以由这个数目除以4得知。

以下是我们这个什么也不做的函数的代码: push ebp
mov  ebp, esp
pop  ebp
ret  8
这个函数通过“ret 8”指令在返回之前设置了堆栈指针。

上一页  1 2 3 4 5 6  下一页

Tags:ATL 之下 秘密

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接