指针、地址、引用之间的关系

分析指针、地址、引用之间的关系;
  地址:在C++中地址使用十六进制表示。取一个变量的地址使用"&"符号,只有变量才存在内存地址,常量没有地址
  指针:指针的定义使用"Type*",Type为数据类型。任何数据类型都可以定义指针。指针本身也是一种数据类型,它用于保存各种数据类型在内存中的地址,指针变量同样可以取出地址,所以会出现多级指针;
   引用:引用定义使用"Type&",Type为数据类型。 在C++中是不可以单独定义的,并且在定义时就要进行初始化。
 各类型指针的工作方式;
   1.访问同一块地址:2.指针的寻址方式:
//访问同一块地址;
int nVar = 0x12345678;
int *pnVar = &nVar;
char *pcVar = (char*)&nVar;
short *psnVar = (short*)&nVar;
printf("%08x \r\n", *pnVar);
printf("%08x \r\n", *pcVar);
printf("%08x \r\n", *psnVar);
 
 mov   dword  ptr[nVar] ,123456789h;   //将123456789的数值存放到nVar变量对应的内存中;
 lea   eax , [nVar]                    //取nVar变量的地址值赋值给eax寄存器;
 mov   dword ptr[pnVar] , eax;        //将eax存放的地址值赋值给pnVar变量对应的内存中;
 lea   eax,  [nVar];
 mov   dword ptr[pcVar], eax;
 lea   eax , [nvar];
 mov   dword ptr[psnVar], eax; 
 
 mov   eax,dword ptr[pnVar];          //将ptr[pnVar]存放的nVar的地址移动到eax寄存器;
 mov   ecx,dword ptr[eax];            //取出对应地址内存存储值移动到寄存器;
 push  ecx;                           //参数入栈;
 push        offset string "%08x \r\n" (0F20EECh) 
 call        @ILT+4415(_printf) (0ECB144h)   
  
 mov  eax dword ptr[pcVar];      //取得存放的地址值;
 mosx ecx byte ptr[eax];
 push ecx;
 push  offset string "%08x  \r\n" (0F20EECh)
 call  @ILT+4415(_printf)(0ECB144h)

 mov eax dword ptr[psnVar];
 mosx ecx word ptr[eax];
 push ecx;
 push offset string "%08x  \r\n"(0F20EECh)
 call @ILT+4415(_printf)(0ECB144h)
 //指针的寻址方式:如下代码演示了不同类型指针加1偏移。它们偏移后的地址都是由指针类型决定的,
 //以指针保存的地址作为寻址[首地址],加上偏移量,最终得到目标地址;
 //偏移量的计算方式为指针类型长度乘以移动次数,因此得出指针寻址公式如下:
       /*type*p;              //这里用type泛指某类型的指针;
     p+n的目标地址=首地址+sizeof(指针类型 type)*n;在偏移量为赋值的情况下可以使用;
  */
//指针之间可以做减法,得到的差是指两地址之间的元素个数,指针之间不能做其他运算,并且做减法运算指针的类型必须一致:
//公式如下:   type*p,q;   p-q=((int)p-(int)q)/sizeof(指针类型type);
char cvar[5] = {0x01, 0x23, 0x45, 0x67, 0x89}; 
 int *pnVar = (int*)cVar;
 char *pcVar = (char*)cVar;
 short *psnVar = (short*)cVar;
 pnVar += 1;
 pcVar += 1; 
 psnVar += 1;
 printf("%08x \r\n", *pnVar);
 printf("%08x \r\n", *pcVar);
 printf("%08x \r\n", *psnVar);
 mov   byte ptr[ebp-1Ch],1;      //数组从低地址到高地址初始化;
 mov   byte ptr[ebp-1Bh],23h;    
 mov   byte ptr[ebp-1Ah],45h;
 mov   byte ptr[ebp-19h],67h;
 mov   byte ptr[ebp-18h],89h;  
 lea    eax,[ebp-1Ch];        //取出ebp-1Ch处的地址到寄存器;   
 mov    dword ptr[ebp-28h] , eax;  //将对应的寄存器的地址赋值给变量pnVar存放的内存中;
 lea    eax,[ebp-1Ch];
 mov    dword ptr[ebp-34h] ,eax;
 lea    eax, [ebp-1Ch];
 mov    dword ptr[ebp-40h],eax;    
 //下面描述指针加法的过程;
 mov   eax,dword ptr[ebp-28h];
 add   eax,4;
 mov   dword ptr[ebp-28h],eax;
 mov   eax,dword ptr[ebp-34h];
 add   eax,1;
 mov   dword ptr[ebp-34h], eax;    //指针内存存放的地址;   
 mov   eax,dword ptr[ebp-40h];
 add   eax,2;
 mov   dword ptr[ebp-40h], eax;    //指针内存的地址加2;
 //如下为打印汇编;
 mov   eax,  dword ptr[ebp-28h];
 mov   ecx,  dword ptr[eax]; 
 push  ecx;
 push  offset string "%08x \r\n"  (0F0DEECh);
 call @ILT+4365(_printf)(0EBA112h)
 add  esp+8;
 mov   eax,  dword ptr[ebp-34];
 mov   ecx,  dword ptr[eax]; 
 push  ecx;
 push  offset string "%08x \r\n"  (0F0DEECh);
 call @ILT+4365(_printf)(0EBA112h)
 add  esp+8;
 
 mov   eax,  dword ptr[ebp-40h];
 mov   ecx,  dword ptr[eax]; 
 push  ecx;
 push  offset string "%08x \r\n"  (0F0DEECh);
 call @ILT+4365(_printf)(0EBA112h)
 add  esp+8;     //将栈顶地址增加参数个数对应的地址增值;
引用其实就是指,实际上C++为了简化指针操作,对指针的操作进行了封装,产生了引用类型。实际上引用类型就是指针类型,只不过它用于存放地址的内存空间对使用者而言是隐藏的;意思就是type*p;我能知道p对应的内存空间;也能知道p中存放的地址;但是type&p=q;只能知道p存放的地址;看不到p的任何信息;
可以看出引用类型和指针类型没有区别;
  int nVar = 0x12345678;
//引用类型定义
int &nVarTpye = nVar;
Add(nVarTpye);  //自增函数;
mov         dword ptr [nVar],12345678h  
    lea         eax , [nVar]; 
mov         dword ptr[nVarTpye],eax;
mov         eax,dword ptr [nVarTpye]  
    push        eax  
    call        Add (1409E01h); 
    add         esp,4  



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值