function_stack 调试分析

#include<stdio.h>

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

int main()
{
    int a = 5;
    int b = 6;
    int c = 0;
    
    c = add(a,b);
    printf("c = %d\n",c);
}

---------- E:\c_project\test.c  --------------
9:
10:   int main()
11:   {
00401060   push        ebp
00401061   mov         ebp,esp
00401063   sub         esp,4Ch
00401066   push        ebx
00401067   push        esi
00401068   push        edi
00401069   lea         edi,[ebp-4Ch]
0040106C   mov         ecx,13h
00401071   mov         eax,0CCCCCCCCh
00401076   rep stos    dword ptr [edi]
12:       int a = 5;
00401078   mov         dword ptr [ebp-4],5
13:       int b = 6;
0040107F   mov         dword ptr [ebp-8],6         --- (1)
14:       int c = 0;
00401086   mov         dword ptr [ebp-0Ch],0       --- (2)
15:
16:       c = add(a,b);                            
0040108D   mov         eax,dword ptr [ebp-8]   //此条命令执行前 ESP = 0018FEF0, EBP = 0018FF48 ;
  //在vc6.0 的memory 调试框输入 ebp-8 后,对应的值和 上面21行的 --- (1) 结果是一致的,都是 6.
00401090   push        eax                    //执行到此行时,即此条命令执行前,寄存器的状态      ESP = 0018FEF0  EBP = 0018FF48    //第二个参数压栈 ?
00401091   mov         ecx,dword ptr [ebp-4]  //此条命令执行前,寄存器的状态      ESP = 0018FEEC  EBP = 0018FF48     0018FEF0 - 0018FEEC = 4;
00401094   push        ecx                     //此条命令执行前,寄存器的状态     ESP = 0018FEEC  EBP = 0018FF48     /第一个参数压栈 ?
00401095   call        @ILT+0(_add) (00401005)  跳转到下面的 A:  //运行到此行时, 此条命令执行前,寄存器的状态  ESP = 0018FEE8  EBP = 0018FF48
0040109A   add         esp,8                     --------- (3)
0040109D   mov         dword ptr [ebp-0Ch],eax
17:       printf("c = %d\n",c);
004010A0   mov         edx,dword ptr [ebp-0Ch]
004010A3   push        edx
004010A4   push        offset string "c = %d\n" (0042201c)
004010A9   call        printf (004010e0)
004010AE   add         esp,8
18:   }

//同时注意call 和 ret 指令对 esp的影响 : CALL和RET指令 ;
CALL和RET指令 --- 汇编学习笔记 : https://blog.csdn.net/qq_37340753/article/details/81585083


00401095   call        @ILT+0(_add) (00401005)  执行后对应下面的一行执行情况:
A :
@ILT+0(_add):     00401005   jmp         add (00401020)  //执行到此行时, 寄存器的状态 : EIP = 00401005, ESP = 0018FEE4,  EBP = 0018FF48 ;

执行A 后的跳转和寄存器状态 : EIP = 00401020, ESP = 0018FEE4, EBP = 0018FF48, EFL = 00000216   
在实际调试中 : ESP = 0018FEE4, ESP存放0018FEE4这个地址, 地址 0018FEE4 的内容是个地址 40109A ; 存放的是下一条指令: add  esp,8 的地址; 下一条指令的地址 也即 返回地址;

1:    #include<stdio.h>
2:
3:    int add(int a, int b)
4:    {
00401020   push        ebp                   //命令执行跳转到此行时, 寄存器的状态 : EIP = 00401020, ESP = 0018FEE4, EBP = 0018FF48, EFL = 00000216;
00401021   mov         ebp,esp               //EIP = 00401021 ESP = 0018FEE0  EBP = 0018FF48 EFL = 00000216
00401023   sub         esp,44h               //EIP = 00401023 ESP = 0018FEE0  EBP = 0018FEE0 EFL = 00000216
00401026   push        ebx                   //EIP = 00401026 ESP = 0018FE9C  EBP = 0018FEE0 EFL = 00000216
00401027   push        esi                   //EIP = 00401027 ESP = 0018FE98  EBP = 0018FEE0 EFL = 00000216
00401028   push        edi                   //EIP = 00401028 ESP = 0018FE94  EBP = 0018FEE0 EFL = 00000216
00401029   lea         edi,[ebp-44h]         //EIP = 00401029 ESP = 0018FE90  EBP = 0018FEE0 EFL = 00000216
0040102C   mov         ecx,11h               //EIP = 0040102C ESP = 0018FE90  EBP = 0018FEE0 EFL = 00000216
00401031   mov         eax,0CCCCCCCCh        //EIP = 00401031 ESP = 0018FE90  EBP = 0018FEE0 EFL = 00000216
00401036   rep stos    dword ptr [edi] //在此处下一步,其它寄存器会一直在变化. ECX 和 EDI等寄存器, 直到ECX寄存器为0 //EIP = 00401036 ESP = 0018FE90  EBP = 0018FEE0 EFL = 00000216
                                             //EAX = CCCCCCCC EBX = 7EFDE000  ECX = 00000010 EDX = 00560F40 ESI = 00000000 EDI = 0018FEA0
                                             //EIP = 00401036 ESP = 0018FE90  EBP = 0018FEE0 EFL = 00010216
5:        int c = 0;          
00401038   mov         dword ptr [ebp-4],0   //
6:        c = a+b;
0040103F   mov         eax,dword ptr [ebp+8]
00401042   add         eax,dword ptr [ebp+0Ch]
00401045   mov         dword ptr [ebp-4],eax
7:        return c;
00401048   mov         eax,dword ptr [ebp-4]
8:    }
0040104B   pop         edi              //EIP = 0040104B ESP = 0018FE90  EBP = 0018FEE0 EFL = 00000202
0040104C   pop         esi              //ESI = 00000000 EDI = 0018FF48  EIP = 0040104C ESP = 0018FE94  EBP = 0018FEE0 EFL = 00000202
0040104D   pop         ebx              //ESI = 00000000 EDI = 0018FF48  EIP = 0040104D ESP = 0018FE98  EBP = 0018FEE0 EFL = 00000202
0040104E   mov         esp,ebp          //ESI = 00000000 EDI = 0018FF48  EIP = 0040104E ESP = 0018FE9C  EBP = 0018FEE0 EFL = 00000202
00401050   pop         ebp              //ESI = 00000000 EDI = 0018FF48  EIP = 00401050 ESP = 0018FEE0  EBP = 0018FEE0 EFL = 00000202
00401051   ret                          //ESI = 00000000 EDI = 0018FF48  EIP = 00401051 ESP = 0018FEE4  EBP = 0018FF48 EFL = 00000202
--- No source file  ----------------

执行完ret指令后,跳转到上面的主程序中的 --------- (3)
0040109A   add         esp,8                                 //执行到此行时, EIP = 0040109A ESP = 0018FEE8  EBP = 0018FF48 EFL = 00000202
0040109D   mov         dword ptr [ebp-0Ch],eax
17:       printf("c = %d\n",c);
004010A0   mov         edx,dword ptr [ebp-0Ch]
004010A3   push        edx
004010A4   push        offset string "c = %d\n" (0042201c)
004010A9   call        printf (004010e0)
004010AE   add         esp,8
18:   }
004010B1   pop         edi
004010B2   pop         esi
004010B3   pop         ebx
004010B4   add         esp,4Ch
004010B7   cmp         ebp,esp
004010B9   call        __chkesp (00401160)
004010BE   mov         esp,ebp
004010C0   pop         ebp
004010C1   ret

//运行在函数add之前的esp, ebp;
EIP = 00401086 ESP = 0018FEF0
EBP = 0018FF48 EFL = 00000216

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值