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

ATL布幔之下的秘密(4)

 2006-07-22 22:54:54 来源:WEB开发网   
核心提示: 程序64. extern "C" void _declspec(naked) fun() {_asm ret}int main() {fun();return 0;}编译器生成的fun函数代码是类似于这个样子: _asm ret这就意味着在这个函数中没有prolog代码

程序64. extern "C" void _declspec(naked) fun() {
 _asm ret
}
int main() {
 fun();
 return 0;
}
编译器生成的fun函数代码是类似于这个样子: _asm ret这就意味着在这个函数中没有prolog代码和epilog代码。事实上,naked函数有一些规则,也就是你不能在naked函数中定义自动变量。因为如果你这么做的话,编译器就需要为你产生代码,而naked函数中编译器是不会产生任何代码的。其实,你还需要自己编写ret语句,否则程序就会崩溃。你甚至不能在naked函数中编写return语句。为什么呢?因为当你从函数中返回一些东西的时候,编译器就会把它的值放在eax寄存器之中。所以这就意味着编译器会为你的return语句产生代码。让我们通过下面的简单程序来弄懂函数返回值的工作过程吧。

程序64. #include <cstdio>
extern "C" int sum(int a, int b) {
 return a + b;
}
int main() {
 int iRetVal;
 sum(3, 7);
 _asm mov iRetVal, eax
 printf("%d\n", iRetVal);
 return 0;
}
程序的输出为10。在这里我们并没有直接使用函数的返回值,而是在函数调用结束后将eax的值复制了一份。

现在来编写我们的naked函数,这个函数没有prolog代码和epilog代码,它返回了两个变量的和。

程序65. #include <cstdio>
extern "C" int _declspec(naked) sum(int a, int b) {
 // prolog代码
 _asm push ebp
 _asm mov ebp, esp
 // 用于相加变量和返回的代码
 _asm mov eax, dword ptr [ebp + 8]
 _asm add eax, dword ptr [ebp + 12]
 
 // epilog代码
 _asm pop ebp
 _asm ret
}
int main() {
 int iRetVal;
 sum(3, 7);
 _asm mov iRetVal, eax
 printf("%d\n", iRetVal);
 return 0;
}
程序的输出为10,也就是两个参数3和7的和。

这一属性被用于ATLBASE.H中来实现_QIThunk结构的成员。这个结构被用于在定义了_ATL_DEBUG_INTERFACES的情况下调试ATL程序的引用计数。

我希望在下一篇文章中能够探究一些ATL的其它秘密。

上一页  1 2 3 4 5 6 

Tags:ATL 之下 秘密

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