学习备忘录

学习加密解密知识

通过VC学习反汇编——函数调用

1         参数传递(默认调用约定)

用VC6.0新建一个空的控制台应用程序,新建源文件main.c,编写如下代码,注意用debug编译,不要用release,以免代码被VC优化,反汇编对应不上。 

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

int main()
{
 int x = AddInt(1, 3); 
 return 0;
}

在main函数进入的大括号处下断,按F5运行,程序断下,这时按组合键“ALT+8”,则可以打开反汇编窗口,每条C语句的下面几行就是相应的汇编代码。

7:    int main()
8:    {
00401060   push        ebp
00401061   mov         ebp,esp
00401063   sub         esp,44h
00401066   push        ebx
00401067   push        esi
00401068   push        edi
00401069   lea         edi,[ebp-44h]
0040106C   mov         ecx,11h
00401071   mov         eax,0CCCCCCCCh
00401076   rep stos    dword ptr [edi]
9:        int x = AddInt(1, 3);
00401078   push        3
0040107A   push        1
0040107C   call        @ILT+0(AddInt) (00401005)
00401081   add         esp,8
00401084   mov         dword ptr [ebp-4],eax
10:       return 0;
00401087   xor         eax,eax
11:   }
00401089   pop         edi
0040108A   pop         esi
0040108B   pop         ebx
0040108C   add         esp,44h
0040108F   cmp         ebp,esp
00401091   call        __chkesp (004010b0)
00401096   mov         esp,ebp
00401098   pop         ebp
00401099   ret

其他内容暂时不考虑,我们看0040107C这一句call @ILT+0(AddInt) (00401005),正是调用AddInt这个函数。在调用前有两个关键语句:

00401078   push        3
0040107A   push        1

可看出来,这里在默认的函数调用时,参数通过堆栈来传递,并且是从右向左依次入栈。
在调用后:

00401081   add         esp,8

这句是为了平衡堆栈,因为刚才入栈的参数是两个整型数,栈顶移动了8个字节,所以这里ESP加上8,保持堆栈的平衡。

2 返回值的保存

在上一节的程序中AddInt函数处下断点: 
F5运行断下后,按“ALT+F8”打开反汇编窗口

1:    int AddInt(int a,int b)
2:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
3:        int c = a+b;
00401038   mov         eax,dword ptr [ebp+8]
0040103B   add         eax,dword ptr [ebp+0Ch]
0040103E   mov         dword ptr [ebp-4],eax
4:        return c;
00401041   mov         eax,dword ptr [ebp-4]
5:    }
00401044   pop         edi
00401045   pop         esi
00401046   pop         ebx
00401047   mov         esp,ebp
00401049   pop         ebp
0040104A   ret

我们看最后函数返回处的汇编代码:

4:        return c;
00401041   mov         eax,dword ptr [ebp-4]

这句就是,把本来存在[ebp-4]这个地址中的a+b的计算结果,再保存到寄存器EAX中。所以,我们可以知道函数的返回值保存在EAX中,基本上函数都是这样传递返回值的。

阅读更多
文章标签: 汇编 c 优化
个人分类: 反汇编
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭