有关引用的汇编层面探索

 

                                                  有关引用的汇编层面探索

 

       基础知识:其实所谓的指针和普通变量无本质区别,就看编译器怎么去解读他,如果是值就直接取出来用;如果是指针,就先把内存中的值读出来,作为地址再去读这个地址中的值,编译器会建立一张表:对应名字和地址。

注:本例在VS2008中观看C++代码的汇编解释,m对应的内存为0012FF60;p的内存地址为0012FF3C;m_a的内存地址为0012FF48


1定义:

普通变量的定义:
int m=5;
004114CE  mov  dword ptr [m],5    //因为它是int型,会占4个字节,[m]就相当于[0012FF60],所以意思就是内存中0012FF60开始的这四个字节的值就是5。


指针:

int* const p=&m;
004114EB  lea         eax,[m]           //意思是把m的值,也就是0012FF60作为地址传给eax寄存器。
004114EE  mov      dword ptr [p],eax //这句话的意思把m_a对应的内存0012FF3C开始的四个字节的值设为0012FF60

再来看看引用:
int& m_a=m;
004114DC  lea         eax,[m]                    //意思是把m的值,也就是0012FF60作为地址传给eax寄存器。
004114DF  mov         dword ptr [m_a],eax  //这句话的意思把m_a对应的内存 0012FF48 开始的四个字节的值设为0012FF60

可以看出:和指针一摸一样。其实引用和指针一样也要占内存。

 

2操作
m_a=4;
004114E2  mov         eax,dword ptr [m_a] //把m_a对应的内存0012FF48开始的四个字节的值(为内存0012FF60)赋给eax寄存器。
004114E5  mov         dword ptr [eax],4 //把4赋值给eax对应的内存0012FF60开始的四个字节的值。
对指针一样:
     *p=3;
004114FA  mov         eax,dword ptr [p]
004114FD  mov         dword ptr [eax],3
相比对变量操作多了一个先取出指针的值,作为地址再进行操作的步骤。

 

3指针和引用作为形参
如下所示:
void swap(int& a,int& b)
{
004113B0  push        ebp 
004113B1  mov         ebp,esp
004113B3  sub         esp,0CCh
004113B9  push        ebx 
004113BA  push        esi 
004113BB  push        edi 
004113BC  lea         edi,[ebp-0CCh]
004113C2  mov         ecx,33h
004113C7  mov         eax,0CCCCCCCCh
004113CC  rep stos    dword ptr es:[edi]
    int c=a;
004113CE  mov         eax,dword ptr [a]
004113D1  mov         ecx,dword ptr [eax]
004113D3  mov         dword ptr [c],ecx
     a=b;
004113D6  mov         eax,dword ptr [a]
004113D9  mov         ecx,dword ptr [b]
004113DC  mov         edx,dword ptr [ecx]
004113DE  mov         dword ptr [eax],edx
    b=c;
004113E0  mov         eax,dword ptr [b]
004113E3  mov         ecx,dword ptr [c]
004113E6  mov         dword ptr [eax],ecx
}

 


void swap1(int* a,int* b)
{
00411400  push        ebp 
00411401  mov         ebp,esp
00411403  sub         esp,0CCh
00411409  push        ebx 
0041140A  push        esi 
0041140B  push        edi 
0041140C  lea         edi,[ebp-0CCh]
00411412  mov         ecx,33h
00411417  mov         eax,0CCCCCCCCh
0041141C  rep stos    dword ptr es:[edi]
    int c=*a;
0041141E  mov         eax,dword ptr [a]
00411421  mov         ecx,dword ptr [eax]
00411423  mov         dword ptr [c],ecx
     *a=*b;
00411426  mov         eax,dword ptr [a]
00411429  mov         ecx,dword ptr [b]
0041142C  mov         edx,dword ptr [ecx]
0041142E  mov         dword ptr [eax],edx
    *b=c;
00411430  mov         eax,dword ptr [b]
00411433  mov         ecx,dword ptr [c]
00411436  mov         dword ptr [eax],ecx
}

 

void swap2(int a,int b)
{
00411460  push        ebp 
00411461  mov         ebp,esp
00411463  sub         esp,0CCh
00411469  push        ebx 
0041146A  push        esi 
0041146B  push        edi 
0041146C  lea         edi,[ebp-0CCh]
00411472  mov         ecx,33h
00411477  mov         eax,0CCCCCCCCh
0041147C  rep stos    dword ptr es:[edi]
    int c=a;
0041147E  mov         eax,dword ptr [a]
00411481  mov         dword ptr [c],eax
     a=b;
00411484  mov         eax,dword ptr [b]
00411487  mov         dword ptr [a],eax
    b=c;
0041148A  mov         eax,dword ptr [c]
0041148D  mov         dword ptr [b],eax
}

4总结:

1.说明指针和引用在汇编层面就是一个东西,都是储存了变量的地址。

 

2.在高级语言层面不同,仅仅是限制的不同,一旦你申明了一个变量是指针或者引用之后,编译器解释他们和普通变量的时候就不一样了。
比如上面的:
int m=5;
int& m_a=m;
int* const p=&m;

 

3.有了以上定义之后,你写*p编译器一看,啊,这个我认识,这是指针,需要先取地址,再操作这个地址对应的值;而你如果写m_a,编译器一看,啊,
这个我也认识,这是引用,虽然没打*我也要先取地址再操作这个地址对应的值。

 

4.平时都说m_a只是一个m的别名,他们其实是一个东西,如果真是这样的话,对m_a和m操作应该是一样的,对吗?

其实不然,从上面的汇编代码可以看出
你用引用的时候,编译器需要多执行一条代码才能访问到m。所以用变量本身比用引用效率高!

 

 水平有限,文中不妥之处,请高手纠正!

版权所有,转载请注明出处:http://blog.csdn.net/WXWTJ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值