函数堆栈调用

首先,我们来了解一些简单的的汇编知识:

1:简单的汇编指令

        mov    移值             mov  dword  ptr[ ebp - 4 ],14h

        lea      移地址         lea  eax , [ ebp - 4 ]

        push   压栈             push  10

        pop     出栈             pop  eax 

        add     累加             add  eax , 4

        sub     累减             sub  eax , 4

        call     ——>       (a)  压入下一行指令的地址   (b)jump跳转到被调用方函数

2:寄存器

        eax、ebx、ecx、edx

        ebp  栈底指针寄存器

        esp   栈顶指针寄存器

        pc      下一行指针寄存器

有了简单的了解之后我们可以利用汇编语言了解函数堆栈调用的过程:

#include<stdio.h>

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

int main()
{
	int a = 10;
	int b = 20;
	int c = myadd(a,b);

	return 0;
}

一、形参是怎样开辟的?

int main()
{
00361410  push        ebp  
00361411  mov         ebp,esp  
00361413  sub         esp,0E4h  
00361419  push        ebx  
0036141A  push        esi  
0036141B  push        edi  
0036141C  lea         edi,[ebp-0E4h]  
00361422  mov         ecx,39h  
00361427  mov         eax,0CCCCCCCCh  
0036142C  rep stos    dword ptr es:[edi]  
	int a = 10;
0036142E  mov         dword ptr [a],0Ah  //给a开辟空间并赋值为10
	int b = 20;
00361435  mov         dword ptr [b],14h  //给b开辟空间并赋值为20
	int c = myadd(a,b);
0036143C  mov         eax,dword ptr [b]  //将b的值赋给寄存器eax
0036143F  push        eax  
00361440  mov         ecx,dword ptr [a]  //将a的值赋给寄存器ebx
00361443  push        ecx  
00361444  call        myadd (036118Bh)  //调用call指令做两件事
                                        //1、压入下一行指令地址
                                        //2、jump跳转到被调用方函数(myadd函数)
	int c = myadd(a,b);
00361449  add         esp,8  //esp栈顶指针移动
0036144C  mov         dword ptr [c],eax  //eax的值赋给变量c

	return 0;
0036144F  xor         eax,eax  
}

首先我们来看主函数的反汇编代码:

int myadd(int a,int b)
{
003613D0  push        ebp  
003613D1  mov         ebp,esp  
003613D3  sub         esp,0CCh  
003613D9  push        ebx  
003613DA  push        esi  
003613DB  push        edi  
003613DC  lea         edi,[ebp-0CCh]  
003613E2  mov         ecx,33h  
003613E7  mov         eax,0CCCCCCCCh  
003613EC  rep stos    dword ptr es:[edi]  
	int c = a+b;
003613EE  mov         eax,dword ptr [a]  //将a的值给eax寄存器
003613F1  add         eax,dword ptr [b]  //将eax的值+= b
003613F4  mov         dword ptr [c],eax  //将eax的值赋给变量c
	return c;
003613F7  mov         eax,dword ptr [c]  //将c的值赋给eax
}

 

 

 

 

 

 

      一、形参是怎样开辟的?

             形参由调用方开辟,调用方清理

       二、形参的入栈顺序是怎样的?

             从右向左,依次入栈(通常支持可变参数的语言都是由右向左依次入栈)

       三、函数返回值是如何带出来的?

             通常由寄存器带回

            0  ~  4个字节  寄存器带回

            5  ~  8个字节   两个寄存器带回

            大于8个字节    临时量带回

       四、函数调用结束后怎样退回到调用方?

              压栈过程中压入了调用方的栈底指针(寄存器的位置)

       五、函数调用结束为什么会沿着调用点继续执行?

              call指令压入了下一行指令

       六、清栈

               被调用方开辟的空间;让ebp回到调用方;清理调用方开辟的形参

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值