您的位置:首页 > 编程语言 > C语言/C++

C++程序中不同函数调用方式的汇编码比较(转载)

2008-09-03 21:37 351 查看
其实看雪的书中已经提到这个问题了,只不过少了thiscall和fastcall,而thiscall是VC++类成员默认的函数调用方式、fastcall是C++Builder默认的调用方式,所以我在这里做一个补充,方便大家查阅。
例子:

假设我们的函数为:

int sumExample (int a, int b)

{

return a + b;

}

调用代码为: int c = sum (2, 3);
现在分别来看几种不同的调用方式,调用者汇编代码和函数体汇编代码:
(1)_cdecl (C语言的调用方式) ---------------

调用者代码>>>:

; // push arguments to the stack, from right to left

push 3

push 2

; // call the function

call _sumExample

; // cleanup the stack by adding the size of the arguments to ESP register

add esp,8

; // copy the return value from EAX to a local variable (int c)

mov dword ptr [c],eax
函数体代码>>>:

; // function prolog

push ebp

mov ebp,esp

sub esp,0C0h

push ebx

push esi

push edi

lea edi,[ebp-0C0h]

mov ecx,30h

mov eax,0CCCCCCCCh

rep stos dword ptr [edi]

; //return a + b;

mov eax,dword ptr [a]

add eax,dword ptr [b]
; // function epilog

pop edi

pop esi

pop ebx

mov esp,ebp

pop ebp

ret
(2)__stdcall (Windows API 的调用方式) -----------------------

调用者代码>>>:

; // push arguments to the stack, from right to left

push 3

push 2

; // call the function

call _sumExample@8
; // copy the return value from EAX to a local variable (int c)

mov dword ptr [c],eax
函数体代码>>>:

; // function prolog goes here (the same code as in the __cdecl example)
; //return a + b;

mov eax,dword ptr [a]

add eax,dword ptr [b]
; // function epilog goes here (the same code as in the __cdecl example)
; // cleanup the stack and return

ret 8

(3)__fastcall(寄存器调用方式) -----------------------

调用者代码>>>:

; // put the arguments in the registers EDX and ECX

mov edx,3

mov ecx,2

; // call the function

call @fastcallSum@8

; // copy the return value from EAX to a local variable (int c)

mov dword ptr [c],eax
函数体代码>>>:

; // function prolog
push ebp

mov ebp,esp

sub esp,0D8h

push ebx

push esi

push edi

push ecx

lea edi,[ebp-0D8h]

mov ecx,36h

mov eax,0CCCCCCCCh

rep stos dword ptr [edi]

pop ecx

mov dword ptr [ebp-14h],edx

mov dword ptr [ebp-8],ecx

; // return a + b;

mov eax,dword ptr [a]

add eax,dword ptr [b]

;// function epilog

pop edi

pop esi

pop ebx

mov esp,ebp

pop ebp

ret

(4)thiscall(C++类成员函数调用方式) -----------------------

这个比较特殊,函数是某个类的成员,所以我们这样定义:

class CSum //类定义

{

int sum ( int a, int b) {return a+b;}

};
调用者代码>>>:

push 3

push 2

lea ecx,[sumObj]

call ?sum@CSum@@QAEHHH@Z; CSum::sum

mov dword ptr [s4],eax
函数体代码>>>:

push ebp

mov ebp,esp

sub esp,0CCh

push ebx

push esi

push edi

push ecx

lea edi,[ebp-0CCh]

mov ecx,33h

mov eax,0CCCCCCCCh

rep stos dword ptr [edi]

pop ecx

mov dword ptr [ebp-8],ecx

mov eax,dword ptr [a]

add eax,dword ptr [b]

pop edi

pop esi

pop ebx

mov esp,ebp

pop ebp

ret 8

总结: 这4种call基本上是C++程序(Visual C++ ,C++Builder)最常见的调用方式,熟练掌握这几种call的调用者与函数体的汇编代码格式有助于更快分析算法,写注册机。所以我简单列举在这里,不足的地方还请大家补充,错误的地方还请批评指正!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: