标签:function pop 调用约定 _stdcall 高效 引用 windows 变量 使用
对函数调用时如何传递参数的一种约定,我们知道调用函数前需要将参数压入栈然后再传递给函数,栈就是定义在进程中的一段内存,向下扩展,大小记录在PE头中,运行时确定栈的大小
函数执行完毕后,ESP的值如何变化?
ESP的值恢复到函数调用之前,这样可引用的栈大小不会缩减
1 int function(int a, int b) 2 { 3 return a + b; 4 } 5 void main() 6 { 7 function(10, 20); 8 }
主要函数约定如下:
__cdecl函数调用约定是我们最长见的一种约定,我们平时在写程序的时候默认会使用该种约定,其特点如下:
1 _function 2 push ebp 3 mov ebp, esp 4 mov eax, [ebp+8] ;参数1 5 add eax, [ebp+C] ;加上参数2 6 pop ebp 7 retn 8 _main 9 push ebp 10 mov ebp, esp 11 push 14h ;参数 2入栈 12 push 0Ah ;参数 1入栈 13 call _function ;调用函数 14 add esp, 8 ;修正栈 15 xor eax, eax 16 pop ebp 17 retn
__stdcall约定是我们在写WinAPI的时候经常用的约定,很多windows下面的API都是该种调用约定,其特点如下:
_function@8 push ebp mov ebp, esp mov eax, [ebp] ;参数 1 add eax, [ebp+C] ;加上参数 2 pop ebp retn 8 ;修复栈 _main push ebp mov ebp, esp push 14h ;参数 2入栈 push 0Ah ;参数 1入栈 call _function@8 ;函数调用 xor eax, eax pop ebp retn
从名称上可以看出是速度快,因为其参数是可以放在寄存器中传递的,通常需要在要求高效率的函数中使用此约定,其特点如下:
该约定是高效率的调用约定,和另外两种约定最大的区别就是参数的传递方式,利用了寄存器来快速的传递
1 @function@8 2 push ebp 3 mov ebp, esp ;保存栈指针 4 sub esp, 8 ;多了两个局部变量 5 mov [ebp-8], edx ;保存参数 2 6 mov [ebp-4], ecx ;保存参数 1 7 mov eax, [ebp-4] ;参数 1 8 add eax, [ebp-8] ;加上参数 2 9 mov esp, ebp ;修正栈 10 pop ebp 11 retn 12 _main 13 push ebp 14 mov ebp, esp 15 mov edx, 14h ;参数 2给EDX 16 mov ecx, 0Ah ;参数 1给ECX 17 call @function@8 ;调用函数 18 xor eax, eax 19 pop ebp 20 retn
标签:function pop 调用约定 _stdcall 高效 引用 windows 变量 使用
原文地址:https://www.cnblogs.com/mysky007/p/12913778.html