反汇编之简单函数调用

简单的函数调用,通过反汇编可以清楚了解

 

举例:

#include 

int add(int a,int b)
{
     int c=0;
     c=a+b;
     return c;
}

int main(void)
{
     int x=0;
     int y=3;
     int z=4;
     x=add(y,z);
     return 0;
}
这是一个简单的通过调用函数计算两数之和的程序

VC6.0生成的汇编代码如下:

ebp:栈低(高地址),esp:栈顶(低地址)

add函数

push        ebp         //ebp=1000	esp=896
mov         ebp,esp     //ebp=896	esp=896 至此add栈往上依次是 main栈ebp,返回地址,参数
sub         esp,44h     //ebp=896	esp=828
push        ebx
push        esi
push        edi		//ebp=896	esp=816
lea         edi,[ebp-44h]
mov         ecx,11h
mov         eax,0CCCCCCCCh
rep stos    dword ptr [edi]

int c=0;
mov         dword ptr [ebp-4],0

c=a+b;
mov         eax,dword ptr [ebp+8]
add         eax,dword ptr [ebp+0Ch]
mov         dword ptr [ebp-4],eax

return c;
mov         eax,dword ptr [ebp-4]	//在add函数返回以前,都是在操作自己的局部变量的栈空间
pop         edi
pop         esi
pop         ebx    //ebp=896  esp=828 在add函数返回以前恢复寄存器的值
mov         esp,ebp//ebp=896  esp=896	
pop         ebp    //ebp=1000 esp=900

ret                //ebp=1000 esp=904 把返回地址从main栈中弹出到指令寄存器 esp+4

 

main函数

push        ebp
mov         ebp,esp //得到main栈的栈顶地址,为了叙述方便假设此时的栈基址 ebp=1000  esp=1000

sub         esp,4Ch //为main栈开辟76个字节的区域用于局部变量使用        ebp=1000  esp=924

push        ebx
push        esi
push        edi		//需要保护的寄存器值压栈	ebp=1000  esp=912

lea         edi,[ebp-4Ch]			
mov         ecx,13h
mov         eax,0CCCCCCCCh			
rep stos    dword ptr [edi]	//局部变量初始化,debug模式下是此值,release模式局部变量为不定值

int x=0;
mov         dword ptr [ebp-4],0		
int y=3;
mov         dword ptr [ebp-8],3
int z=4;
mov         dword ptr [ebp-0Ch],4 //局部变量按照定义的顺序存储在main栈中

x=add(y,z);
mov         eax,dword ptr [ebp-0Ch]
push        eax
mov         ecx,dword ptr [ebp-8]
push        ecx			//把参数按照stdcall方式从右到左压栈 ebp=1000 esp=904
call        @ILT+15(_add) (00401014)//把返回地址压栈并跳转至add函数 ebp=1000 esp=900

add         esp,8		//参数部分的出栈工作由调用函数来完成 ebp=1000 esp=912
mov         dword ptr [ebp-4],eax	//返回的变量放到x中
return 0;

你可能感兴趣的:(C/C++语言相关)