码迷,mamicode.com
首页 > 其他好文 > 详细

理解指针

时间:2014-05-02 06:02:18      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   tar   color   

如题:理解指针

 

 

VS如何看汇编代码(DEBUG状态)

  Debug->Windows->DisAssambly即可看到汇编窗口

 

 

先看看C++代码

 

bubuko.com,布布扣
int _tmain(int argc, _TCHAR* argv[])
{
    /*
    char temp[100] = "c:\abc\bcd\cde \n";
    char temp2[100] = "c:/abc/bcd/cde \n";
    char temp3[100] = "c:\\abc\\bcd\\cde \n";
    */

    //&取地址   运算符:取出内存地址
    //*间接寻址 运算符:得到内存地址里面的值

    int ival = 100; //地址为0x00adf75c{100}
    int *p = &ival;    //取ival的地址  赋给p的指针(地址0x00adf75c 赋给*p)
    ival = 200;        //改ival的值0x00adf75c{200}


    //printf("\n ival = %d, &ival = 0x%x, *p =0x%x ", ival, &ival, *p);

    //little endian
    int **b = &p;//b是二级指针,     第一个指针地址是0x00adf75c{200}(0x00adf75c存的值为200),   第二个指针地址是0x00adf750
    //printf("\n b>>>>>>>>> **b =0x%d, *b=0x%x,  b =%x", **b, *b, b);


    //============================================================================
    //通过debug可以看到二级指针的信息    0x00adf750{0x00adf75c{200}}


    int *first = &(**b);
    //1.按照()优先级, 二级指针b  先间接寻址,再间接寻址 得到200的值, 然后取地址  得到ival的地址(也就是*p的值  0x00adf75c{200})
    
    //汇编过程
    //1.  【二级指针b】把0x00adf750 赋给eax
    //2.  eax(间接寻址后)得到 0x00adf75c{200} 赋给ebx,   再取地址  赋给 *first(first指针地址 为0x00adf75c{200})
    
    
    int *second = *b;    
    //二级指针b先把0x00adf750{0x00adf75c{200}}   赋给 寄存器eax, 
    //eax 0x00adf750(间接寻址后)得到0x00adf75c{200}  赋给 *second(second指针地址 为0x00adf75c{200})

    int **c = b;//二级指针 b 赋给二级指针c
    //printf("\n c >>>>>>>>>>>> **c =0x%d, *c=0x%d,  c =%d", **c, *c, c);


    int d = **b;//二级指针b , 间接寻址 再间接寻址(也就是ival指针地址的值),赋给d

    return 0;
}
View Code

 

 

 

再看看汇编是如何实现的

 

bubuko.com,布布扣
int _tmain(int argc, _TCHAR* argv[])
{
00E213B0  push        ebp  
00E213B1  mov         ebp,esp  
00E213B3  sub         esp,118h  
00E213B9  push        ebx  
00E213BA  push        esi  
00E213BB  push        edi  
00E213BC  lea         edi,[ebp-118h]  
00E213C2  mov         ecx,46h  
00E213C7  mov         eax,0CCCCCCCCh  
00E213CC  rep stos    dword ptr es:[edi]  
00E213CE  mov         eax,dword ptr ds:[00E28000h]  
00E213D3  xor         eax,ebp  
00E213D5  mov         dword ptr [ebp-4],eax  
    /*
    char temp[100] = "c:\abc\bcd\cde \n";
    char temp2[100] = "c:/abc/bcd/cde \n";
    char temp3[100] = "c:\\abc\\bcd\\cde \n";
    */

    //&取地址   运算符:取出内存地址
    //*间接寻址 运算符:得到内存地址里面的值

    int ival = 100; //地址为0x00adf75c{100}
00E213D8  mov         dword ptr [ival],64h  
    int *p = &ival;    //取ival的地址  赋给p的指针(地址0x00adf75c 赋给*p)
00E213DF  lea         eax,[ival]  
00E213E2  mov         dword ptr [p],eax  
    ival = 200;        //改ival的值0x00adf75c{200}
00E213E5  mov         dword ptr [ival],0C8h  


    //printf("\n ival = %d, &ival = 0x%x, *p =0x%x ", ival, &ival, *p);

    //little endian
    int **b = &p;//b是二级指针,     第一个指针地址是0x00adf75c{200}(0x00adf75c存的值为200),   第二个指针地址是0x00adf750
00E213EC  lea         eax,[p]  
00E213EF  mov         dword ptr [b],eax  
    //printf("\n b>>>>>>>>> **b =0x%d, *b=0x%x,  b =%x", **b, *b, b);


    //============================================================================
    //通过debug可以看到二级指针的信息    0x00adf750{0x00adf75c{200}}


    int *first = &(**b);
00E213F2  mov         eax,dword ptr [b]  
00E213F5  mov         ecx,dword ptr [eax]  
00E213F7  mov         dword ptr [first],ecx  
    //1.按照()优先级, 二级指针b  先间接寻址,再间接寻址 得到200的值, 然后取地址  得到ival的地址(也就是*p的值  0x00adf75c{200})
    
    //汇编过程
    //1.  【二级指针b】把0x00adf750 赋给eax
    //2.  eax(间接寻址后)得到 0x00adf75c{200} 赋给ebx,   再取地址  赋给 *first(first指针地址 为0x00adf75c{200})
    
    
    int *second = *b;    
00E213FA  mov         eax,dword ptr [b]  
00E213FD  mov         ecx,dword ptr [eax]  

00E213FF  mov         dword ptr [second],ecx  
    //二级指针b先把0x00adf750{0x00adf75c{200}}   赋给 寄存器eax, 
    //eax 0x00adf750(间接寻址后)得到0x00adf75c{200}  赋给 *second(second指针地址 为0x00adf75c{200})

    int **c = b;//二级指针 b 赋给二级指针c
00E21402  mov         eax,dword ptr [b]  
00E21405  mov         dword ptr [c],eax  
    //printf("\n c >>>>>>>>>>>> **c =0x%d, *c=0x%d,  c =%d", **c, *c, c);


    int d = **b;//二级指针b , 间接寻址 再间接寻址(也就是ival指针地址的值),赋给d
00E21408  mov         eax,dword ptr [b]  
00E2140B  mov         ecx,dword ptr [eax]  
00E2140D  mov         edx,dword ptr [ecx]  
00E2140F  mov         dword ptr [d],edx  

    return 0;
00E21412  xor         eax,eax  
}
View Code

 

 

图:

bubuko.com,布布扣

 

//==========分割线

有个问题提下:

为什么【一级指针0x00adf75c】定义早于【二级指针0x00adf750 】但是二级指针的内存地址在低位

 

原因:

机器是intel x64  【little endian机】

所以每8位,高位地址在前,低位地址在后面,所以先分配0x00adf75c,再分配0x00adf750

 

大端小端知识传送门(深入理解计算机里面也有讲)

http://en.wikipedia.org/wiki/Endianness

 

 

 

理解指针,布布扣,bubuko.com

理解指针

标签:style   blog   class   code   tar   color   

原文地址:http://www.cnblogs.com/scotth/p/3703616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!