博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
指针与引用
阅读量:5285 次
发布时间:2019-06-14

本文共 9679 字,大约阅读时间需要 32 分钟。

int main(){000000013FA01010  push        rdi  000000013FA01012  sub         rsp,50h  000000013FA01016  mov         rdi,rsp  000000013FA01019  mov         ecx,14h  000000013FA0101E  mov         eax,0CCCCCCCCh  000000013FA01023  rep stos    dword ptr [rdi]      int x=0x12345678;000000013FA01025  mov         dword ptr [x],12345678h      //取地址到指针变量p中    int *p=&x;000000013FA0102D  lea         rax,[x]  000000013FA01032  mov         qword ptr [p],rax      int y=*p;000000013FA01037  mov         rax,qword ptr [p]  000000013FA0103C  mov         eax,dword ptr [rax]  000000013FA0103E  mov         dword ptr [y],eax      printf("%d",y);000000013FA01042  mov         edx,dword ptr [y]  000000013FA01046  lea         rcx,[__xi_z+150h (013FA068C0h)]  000000013FA0104D  call        qword ptr [__imp_printf (013FA0B540h)]      return 0;000000013FA01053  xor         eax,eax  }000000013FA01055  mov         edi,eax  000000013FA01057  mov         rcx,rsp  000000013FA0105A  lea         rdx,[__xi_z+1A0h (013FA06910h)]  000000013FA01061  call        _RTC_CheckStackVars (013FA010D0h)  000000013FA01066  mov         eax,edi  000000013FA01068  add         rsp,50h  000000013FA0106C  pop         rdi  000000013FA0106D  ret

解引用在汇编中要取两次“地址”。

指针p是一个指针变量,空间内存放x的地址。

下面看看引用:

可以看到,两者反汇编代码是相同的,不同的是解引用是由编译器操作的。

我们在定义时,定义为引用,编译器就知道这是一个需要编译器寻址的指针。例如printf时,不需要写成*p。

看下面的代码:

void _swap(int a,int b){    int temp;    temp=a;    a=b;    b=temp;}void swap1(int *a,int *b){    int temp;    temp=*a;    *a=*b;    *b=temp;}void swap2(int &a,int &b){    int temp=a;    a=b;    b=temp;}int main(){    int x,y;    x=10;    y=20;    _swap(x,y);    printf("%d,%d\n",x,y);    swap1(&x,&y);    printf("%d,%d\n",x,y);    swap2(x,y);    printf("%d,%d\n",x,y);    return 0;}

vc中的反汇编代码:

void _swap(int a,int b){000000013F1F1030  mov         dword ptr [rsp+10h],edx  000000013F1F1034  mov         dword ptr [rsp+8],ecx  000000013F1F1038  push        rdi  000000013F1F1039  sub         rsp,10h  000000013F1F103D  mov         rdi,rsp  000000013F1F1040  mov         ecx,4  000000013F1F1045  mov         eax,0CCCCCCCCh  000000013F1F104A  rep stos    dword ptr [rdi]  000000013F1F104C  mov         ecx,dword ptr [a]      int temp;    temp=a;000000013F1F1050  mov         eax,dword ptr [a]  000000013F1F1054  mov         dword ptr [rsp],eax      a=b;000000013F1F1057  mov         eax,dword ptr [b]  000000013F1F105B  mov         dword ptr [a],eax      b=temp;000000013F1F105F  mov         eax,dword ptr [rsp]  000000013F1F1062  mov         dword ptr [b],eax  }000000013F1F1066  add         rsp,10h  000000013F1F106A  pop         rdi  000000013F1F106B  ret  /void swap1(int *a,int *b){000000013F1F1080  mov         qword ptr [rsp+10h],rdx  000000013F1F1085  mov         qword ptr [rsp+8],rcx  000000013F1F108A  push        rdi  000000013F1F108B  sub         rsp,10h  000000013F1F108F  mov         rdi,rsp  000000013F1F1092  mov         ecx,4  000000013F1F1097  mov         eax,0CCCCCCCCh  000000013F1F109C  rep stos    dword ptr [rdi]  000000013F1F109E  mov         rcx,qword ptr [a]      int temp;    temp=*a;000000013F1F10A3  mov         rax,qword ptr [a]  000000013F1F10A8  mov         eax,dword ptr [rax]  000000013F1F10AA  mov         dword ptr [rsp],eax      *a=*b;000000013F1F10AD  mov         rax,qword ptr [a]  000000013F1F10B2  mov         rcx,qword ptr [b]  000000013F1F10B7  mov         ecx,dword ptr [rcx]  000000013F1F10B9  mov         dword ptr [rax],ecx      *b=temp;000000013F1F10BB  mov         rax,qword ptr [b]  000000013F1F10C0  mov         ecx,dword ptr [rsp]  000000013F1F10C3  mov         dword ptr [rax],ecx  }000000013F1F10C5  add         rsp,10h  000000013F1F10C9  pop         rdi  000000013F1F10CA  ret  //void swap2(int &a,int &b){000000013F1F10E0  mov         qword ptr [rsp+10h],rdx  000000013F1F10E5  mov         qword ptr [rsp+8],rcx  000000013F1F10EA  push        rdi  000000013F1F10EB  sub         rsp,10h  000000013F1F10EF  mov         rdi,rsp  000000013F1F10F2  mov         ecx,4  000000013F1F10F7  mov         eax,0CCCCCCCCh  000000013F1F10FC  rep stos    dword ptr [rdi]  000000013F1F10FE  mov         rcx,qword ptr [a]      int temp=a;000000013F1F1103  mov         rax,qword ptr [a]  000000013F1F1108  mov         eax,dword ptr [rax]  000000013F1F110A  mov         dword ptr [rsp],eax      a=b;000000013F1F110D  mov         rax,qword ptr [a]  000000013F1F1112  mov         rcx,qword ptr [b]  000000013F1F1117  mov         ecx,dword ptr [rcx]  000000013F1F1119  mov         dword ptr [rax],ecx      b=temp;000000013F1F111B  mov         rax,qword ptr [b]  000000013F1F1120  mov         ecx,dword ptr [rsp]  000000013F1F1123  mov         dword ptr [rax],ecx  }000000013F1F1125  add         rsp,10h  000000013F1F1129  pop         rdi  000000013F1F112A  ret  //int main(){000000013F541140  push        rdi  000000013F541142  sub         rsp,60h  000000013F541146  mov         rdi,rsp  000000013F541149  mov         ecx,18h  000000013F54114E  mov         eax,0CCCCCCCCh  000000013F541153  rep stos    dword ptr [rdi]      int x,y;    x=10;000000013F541155  mov         dword ptr [x],0Ah      y=20;000000013F54115D  mov         dword ptr [y],14h      _swap(x,y);000000013F541165  mov         edx,dword ptr [y]  000000013F541169  mov         ecx,dword ptr [x]  000000013F54116D  call        _swap (013F541005h)      printf("%d,%d\n",x,y);000000013F541172  mov         r8d,dword ptr [y]  000000013F541177  mov         edx,dword ptr [x]  000000013F54117B  lea         rcx,[__xi_z+150h (013F5468C0h)]  000000013F541182  call        qword ptr [__imp_printf (013F54B540h)]      swap1(&x,&y);000000013F541188  lea         rdx,[y]  000000013F54118D  lea         rcx,[x]  000000013F541192  call        swap1 (013F54100Ah)      printf("%d,%d\n",x,y);000000013F541197  mov         r8d,dword ptr [y]  000000013F54119C  mov         edx,dword ptr [x]  000000013F5411A0  lea         rcx,[__xi_z+158h (013F5468C8h)]  000000013F5411A7  call        qword ptr [__imp_printf (013F54B540h)]      swap2(x,y);000000013F5411AD  lea         rdx,[y]  000000013F5411B2  lea         rcx,[x]  000000013F5411B7  call        swap2 (013F54100Fh)      printf("%d,%d\n",x,y);000000013F5411BC  mov         r8d,dword ptr [y]  000000013F5411C1  mov         edx,dword ptr [x]  000000013F5411C5  lea         rcx,[__xi_z+160h (013F5468D0h)]  000000013F5411CC  call        qword ptr [__imp_printf (013F54B540h)]      return 0;000000013F5411D2  xor         eax,eax  }000000013F5411D4  mov         edi,eax  000000013F5411D6  mov         rcx,rsp  000000013F5411D9  lea         rdx,[__xi_z+1F0h (013F546960h)]  000000013F5411E0  call        _RTC_CheckStackVars (013F541290h)  000000013F5411E5  mov         eax,edi  000000013F5411E7  add         rsp,60h  }000000013F5411EB  pop         rdi  000000013F5411EC  ret

在这上面看不出什么有价值的东西,看看IDA:

; int __cdecl main()main proc neara= dword ptr -44hb= dword ptr -24hpush    rdisub     rsp, 60hmov     rdi, rspmov     ecx, 18hmov     eax, 0CCCCCCCChrep stosdmov     [rsp+68h+a], 0Ahmov     [rsp+68h+b], 14hmov     edx, [rsp+68h+b] ; bmov     ecx, [rsp+68h+a] ; acall    j_?_swap@@YAXHH@Z ; _swap(int,int)mov     r8d, [rsp+68h+b]mov     edx, [rsp+68h+a]lea     rcx, aDD        ; "%d,%d\n"call    cs:__imp_printflea     rdx, [rsp+68h+b] ; blea     rcx, [rsp+68h+a] ; acall    j_?swap1@@YAXPEAH0@Z ; swap1(int *,int *)mov     r8d, [rsp+68h+b]mov     edx, [rsp+68h+a]lea     rcx, aDD_0      ; "%d,%d\n"call    cs:__imp_printflea     rdx, [rsp+68h+b] ; blea     rcx, [rsp+68h+a] ; acall    j_?swap2@@YAXAEAH0@Z ; swap2(int &,int &)mov     r8d, [rsp+68h+b]mov     edx, [rsp+68h+a]lea     rcx, aDD_1      ; "%d,%d\n"call    cs:__imp_printfxor     eax, eaxmov     edi, eaxmov     rcx, rsp        ; framelea     rdx, v          ; vcall    _RTC_CheckStackVarsmov     eax, ediadd     rsp, 60hpop     rdiretnmain endp; void __cdecl _swap(int a, int b)?_swap@@YAXHH@Z proc nearvar_18= dword ptr -18harg_0= dword ptr  8arg_8= dword ptr  10h;win x64不超过4个参数用寄存器传参;但是堆栈会保留并且会赋值mov     [rsp+arg_8], edxmov     [rsp+arg_0], ecxpush    rdisub     rsp, 10hmov     rdi, rspmov     ecx, 4mov     eax, 0CCCCCCCChrep stosdmov     ecx, [rsp+18h+arg_0]mov     eax, [rsp+18h+arg_0]mov     [rsp+18h+var_18], eaxmov     eax, [rsp+18h+arg_8]mov     [rsp+18h+arg_0], eaxmov     eax, [rsp+18h+var_18]mov     [rsp+18h+arg_8], eaxadd     rsp, 10hpop     rdiretn?_swap@@YAXHH@Z endp; void __cdecl swap1(int *a, int *b)?swap1@@YAXPEAH0@Z proc nearvar_18= dword ptr -18harg_0= qword ptr  8arg_8= qword ptr  10hmov     [rsp+arg_8], rdxmov     [rsp+arg_0], rcxpush    rdisub     rsp, 10hmov     rdi, rspmov     ecx, 4mov     eax, 0CCCCCCCChrep stosdmov     rcx, [rsp+18h+arg_0]mov     rax, [rsp+18h+arg_0]mov     eax, [rax]mov     [rsp+18h+var_18], eaxmov     rax, [rsp+18h+arg_0]mov     rcx, [rsp+18h+arg_8]mov     ecx, [rcx]mov     [rax], ecxmov     rax, [rsp+18h+arg_8]mov     ecx, [rsp+18h+var_18]mov     [rax], ecxadd     rsp, 10hpop     rdiretn?swap1@@YAXPEAH0@Z endp; void __cdecl swap2(int *a, int *b)?swap2@@YAXAEAH0@Z proc nearvar_18= dword ptr -18harg_0= qword ptr  8arg_8= qword ptr  10hmov     [rsp+arg_8], rdxmov     [rsp+arg_0], rcxpush    rdisub     rsp, 10hmov     rdi, rspmov     ecx, 4mov     eax, 0CCCCCCCChrep stosdmov     rcx, [rsp+18h+arg_0]mov     rax, [rsp+18h+arg_0]mov     eax, [rax]mov     [rsp+18h+var_18], eaxmov     rax, [rsp+18h+arg_0]mov     rcx, [rsp+18h+arg_8]mov     ecx, [rcx]mov     [rax], ecxmov     rax, [rsp+18h+arg_8]mov     ecx, [rsp+18h+var_18]mov     [rax], ecxadd     rsp, 10hpop     rdiretn?swap2@@YAXAEAH0@Z endp

对比一下:

指针与引用对比。两者反汇编代码是一样的。

1.为何用非指针非引用传参函数无效?

因为是在栈上的参数交换的地址内的数,属于公用的,并不是去改变x,y地址内的数。输出x,y当然没有改变。

2.指针、引用为何能改变?

因为它们找到x,y地址,改变了地址内的内容。

 

 

转载于:https://www.cnblogs.com/qiangua/p/3716622.html

你可能感兴趣的文章
关于IE和火狐,谷歌,Safari对Html标签Object和Embed的支持问题
查看>>
poj3320 Jessica's Reading Problem(尺取思路+STL)
查看>>
分布式计算开源框架Hadoop介绍
查看>>
坏的事情不都会带来坏的结果
查看>>
RPC的基础:调研EOS插件http_plugin
查看>>
第二次团队冲刺第二天
查看>>
bzoj 2257 (JSOI 2009) 瓶子与燃料
查看>>
11)Java abstract class 和 interface
查看>>
使用xrdp或Xmanager 远程连接 CentOS6
查看>>
Linux误删恢复
查看>>
Unity调用Windows窗口句柄,选择文件和目录
查看>>
HashMap循环遍历方式
查看>>
React Native 入门 调试项目
查看>>
C# 通过 Quartz .NET 实现 schedule job 的处理
查看>>
关于java之socket输入流输出流可否放在不同的线程里进行处理
查看>>
目前为止用过的最好的Json互转工具类ConvertJson
查看>>
Day13
查看>>
tensorflow saver简介+Demo with linear-model
查看>>
Luogu_4103 [HEOI2014]大工程
查看>>
Oracle——SQL基础
查看>>