函数调用参数为引用的实现机制

本文阐述二个要点:

       数组的引用,就是数组本身;即      char str[16];     有 str ==& str;  成立

       引用在汇编层级的实现即为取参数地址;

 

举例说明,看下面的代码:

void testref(int &a,char * & str)
{
int b=a;
a=2;
strcpy(str,"refello");

str =(char*)malloc(16);
strcpy(str,"cello");
}

void test(int a,char * str)
{
int b=a;
a=2;
strcpy(str,"aello");

}

void main()
{
int a=1,b=3;
a=b;

char strr[16];
char *p=strr;
strcpy(strr,"eewww");
test(a,strr);

//注意这里得用p,而不是str,否则编译通不过
testref(a,p);

char c;
c=getchar();
}

注意2个函数,一个传值test,一个传引用testref,

test的被调用方式:

45:       test(a,strr);

//压入第二个参数str的地址
00401393   lea         eax,[ebp-18h]
00401396   push        eax

//压入第一个参数a的值1
00401397   mov         ecx,dword ptr [ebp-4]
0040139A   push        ecx
0040139B   call        @ILT+5(test) (0040100a)
004013A0   add         esp,8

test的汇编代码如下:

29:   void test(int a,char * str)
30:   {
004012F0   push        ebp
004012F1   mov         ebp,esp
004012F3   sub         esp,44h
004012F6   push        ebx
004012F7   push        esi
004012F8   push        edi
004012F9   lea         edi,[ebp-44h]
004012FC   mov         ecx,11h
00401301   mov         eax,0CCCCCCCCh
00401306   rep stos    dword ptr [edi]
31:       int b=a;
00401308   mov         eax,dword ptr [ebp+8]
0040130B   mov         dword ptr [ebp-4],eax
32:       a=2;
0040130E   mov         dword ptr [ebp+8],2
33:       strcpy(str,"aello");
00401315   push        offset string "aello" (0042e030)
0040131A   mov         ecx,dword ptr [ebp+0Ch]
0040131D   push        ecx
0040131E   call        strcpy (0040a2f0)
00401323   add         esp,8
34:
35:   }

testref的呢??????
46:       testref(a,p);

//压入第二个参数p的地址
004013A3   lea         edx,[ebp-1Ch]
004013A6   push        edx

//压入第一个参数a的地址
004013A7   lea         eax,[ebp-4]
004013AA   push        eax
004013AB   call        @ILT+0(testref) (00401005)
004013B0   add         esp,8

19:   void testref(int &a,char * & str)
20:   {
00401260   push        ebp
00401261   mov         ebp,esp
00401263   sub         esp,44h
00401266   push        ebx
00401267   push        esi
00401268   push        edi
00401269   lea         edi,[ebp-44h]
0040126C   mov         ecx,11h
00401271   mov         eax,0CCCCCCCCh
00401276   rep stos    dword ptr [edi]
21:       int b=a;
00401278   mov         eax,dword ptr [ebp+8]
0040127B   mov         ecx,dword ptr [eax]
0040127D   mov         dword ptr [ebp-4],ecx
22:       a=2;
00401280   mov         edx,dword ptr [ebp+8]
00401283   mov         dword ptr [edx],2
23:       strcpy(str,"refello");
00401289   push        offset string "refello" (0042e024)
0040128E   mov         eax,dword ptr [ebp+0Ch]
00401291   mov         ecx,dword ptr [eax]
00401293   push        ecx
00401294   call        strcpy (0040a2f0)
00401299   add         esp,8
24:
25:       str =(char*)malloc(16);
0040129C   push        10h
0040129E   call        malloc (00408460)
004012A3   add         esp,4
004012A6   mov         edx,dword ptr [ebp+0Ch]
004012A9   mov         dword ptr [edx],eax
26:       strcpy(str,"cello");
004012AB   push        offset string "cello" (0042e01c)
004012B0   mov         eax,dword ptr [ebp+0Ch]
004012B3   mov         ecx,dword ptr [eax]
004012B5   push        ecx
004012B6   call        strcpy (0040a2f0)
004012BB   add         esp,8
27:   }

二者区别在哪里呢???test被调用int参数压入实际值,二testref压入int参数的内存地址,所以后者执行语句

                     int b=a 时修改传入地址的值,达到修改原值的目的。

同理对char*&类型参数,传入间接指针参数p,达到修改原值的目的。

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值