分类目录

展开|收起

看你喜欢

(1) (1) (42) (1) (1) (1) (16) (2) (1) (1) (4) (1) (2) (7) (4) (1) (1) (1) (1) (3) (1) (5) (1) (1) (1) (1) (1) (2) (1) (4) (4) (3) (1) (1) (2) (1) (37) (2) (1) (5) (3) (1) (4) (1) (1) (11) (3) (1) (9) (3) (1) (23) (2) (1) (2) (1) (1) (1) (1)

最新精华

函数调用汇编分析【3】- 实例分析3(引用传参)

3.3 引用传参

(1)源程序

#include <stdio.h>
int add(int& c , int& d)
{
    int e;
    e=c+d;  
    return e;
}

void main()
{
    int a = 1;
    int b = 2;
    int c;

    c=add(a,b);

    while (1)
    {
    }
}

(2)汇编代码

1:    #include <stdio.h>
2:
3:    int add(int&c , int&d)
4:    {
0040B650   push        ebp
0040B651   mov         ebp,esp
0040B653   sub         esp,44h
0040B656   push        ebx
0040B657   push        esi
0040B658   push        edi
0040B659   lea         edi,[ebp-44h]
0040B65C   mov         ecx,11h
0040B661   mov         eax,0CCCCCCCCh
0040B666   rep stos    dword ptr [edi]
5:        int e;
6:        e=c+d;
0040B668   mov         eax,dword ptr [ebp+8]   // 取第一个参数的地址
0040B66B   mov         ecx,dword ptr [eax]     // 获取参数的值
0040B66D   mov         edx,dword ptr [ebp+0Ch] // 取第二个参数的地址
0040B670   add         ecx,dword ptr [edx]     // c+d
0040B672   mov         dword ptr [ebp-4],ecx   // e=c+d
7:        return e;
0040B675   mov         eax,dword ptr [ebp-4]   // e通过eax寄存器返回
8:    }
0040B678   pop         edi
0040B679   pop         esi
0040B67A   pop         ebx
0040B67B   mov         esp,ebp
0040B67D   pop         ebp
0040B67E   ret

9:
10:
11:   void main()
12:   {
0040B530   push        ebp
0040B531   mov         ebp,esp
0040B533   sub         esp,4Ch
0040B536   push        ebx
0040B537   push        esi
0040B538   push        edi
0040B539   lea         edi,[ebp-4Ch]
0040B53C   mov         ecx,13h
0040B541   mov         eax,0CCCCCCCCh
0040B546   rep stos    dword ptr [edi]
13:       int a = 1;
0040B548   mov         dword ptr [ebp-4],1  // 栈中保存a
14:       int b = 2;
0040B54F   mov         dword ptr [ebp-8],2  // 栈中保存b
15:
16:       int c;
17:
18:       c=add(a,b);
0040B556   lea         eax,[ebp-8]    // 取b的地址,注意是地址不是值
0040B559   push        eax            // 入栈作为函数的第二个参数
0040B55A   lea         ecx,[ebp-4]    // 取a的地址
0040B55D   push        ecx            // 入栈作为函数的第一个参数
0040B55E   call        @ILT+40(add) (0040102d)  // 调用add函数
0040B563   add         esp,8                    // 调整堆栈指针
0040B566   mov         dword ptr [ebp-0Ch],eax   // 返回值赋给c 
                                             由于返回值不大于4个字节,
                                           所以,函数的返回值是通过eax返回
19:
20:       while (1)
0040B569   mov         edx,1
0040B56E   test        edx,edx
0040B570   je          main+44h (0040b574)
21:       {
22:       }
0040B572   jmp         main+39h (0040b569)
23:   }
0040B574   pop         edi
0040B575   pop         esi
0040B576   pop         ebx
0040B577   add         esp,4Ch
0040B57A   cmp         ebp,esp
0040B57C   call        __chkesp (004010e0)
0040B581   mov         esp,ebp
0040B583   pop         ebp
0040B584   ret

(3)小结

可以看出,add函数的汇编代码和指针传递时是完全一样的,虽然从C语言的定义上看起来有点区别。同时,main函数中虽然C语言中写的是add(a,b),但实际入栈的是a和b的地址。我左看右看,除了定义和使用方式和指针传递参数不同,其它我没看出来差异。或许大家可以再去看看C语言的语法书上对引用的描述,好像引用在C++中用的较多,我没仔细去研究了,有谁对这个引用了解得透彻一点请告诉我一下,呵呵。

  打分:5.0/5 (共3人投票)
(浏览总计: 31 次)
Add Comment Register



发表回复

  

  

  

您可以使用这些HTML标签

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>