首页 > 逆向调试 > 引用不分配内存?

引用不分配内存?

当我第一次遇到这个问题,还是有很大的疑虑的。不管怎么样,从汇编的角度去考察问题,就会很清晰。

目标程序:

// 本程序有点无聊
#include <iostream>    
using namespace std;
 
int main(int argc, char *argv[])    
{    
	int a, b;
 
	scanf("%d %d", &a, &b);
 
	int &p = a;
	int *pp = &a;
 
	*pp = 15;
	p = b;
	printf("%d\n", *pp);
	printf("a = %d b = %d p = %d\n", a, b, p);
 
	return 0;    
}

Debug版本(Visual Studio 2008)

int main(int argc, char *argv[])    
{    
004113B0  push        ebp  
004113B1  mov         ebp,esp 
004113B3  sub         esp,0F0h 
004113B9  push        ebx  
004113BA  push        esi  
004113BB  push        edi  
004113BC  lea         edi,[ebp-0F0h] 
004113C2  mov         ecx,3Ch 
004113C7  mov         eax,0CCCCCCCCh 
004113CC  rep stos    dword ptr es:[edi] 
	int a, b;
 
	scanf("%d %d", &a, &b);
004113CE  mov         esi,esp 
004113D0  lea         eax,[b] 
004113D3  push        eax  
004113D4  lea         ecx,[a] 
004113D7  push        ecx  
004113D8  push        offset string "%d %d" (415820h) 
004113DD  call        dword ptr [__imp__scanf (4182BCh)] 
004113E3  add         esp,0Ch 
004113E6  cmp         esi,esp 
004113E8  call        @ILT+315(__RTC_CheckEsp) (411140h) 
 
	int &p = a;
004113ED  lea         eax,[a] 
004113F0  mov         dword ptr [p],eax 
	int *pp = &a;
004113F3  lea         eax,[a] 
004113F6  mov         dword ptr [pp],eax 
 
	*pp = 15;
004113F9  mov         eax,dword ptr [pp] 
004113FC  mov         dword ptr [eax],0Fh 
	p = b;
00411402  mov         eax,dword ptr [p] 
00411405  mov         ecx,dword ptr [b] 
00411408  mov         dword ptr [eax],ecx 
	printf("%d\n", *pp);
0041140A  mov         esi,esp 
0041140C  mov         eax,dword ptr [pp] 
0041140F  mov         ecx,dword ptr [eax] 
00411411  push        ecx  
00411412  push        offset string "%d\n" (41581Ch) 
00411417  call        dword ptr [__imp__printf (4182C4h)] 
0041141D  add         esp,8 
00411420  cmp         esi,esp 
00411422  call        @ILT+315(__RTC_CheckEsp) (411140h) 
	printf("a = %d b = %d p = %d\n", a, b, p);
00411427  mov         esi,esp 
00411429  mov         eax,dword ptr [p] 
0041142C  mov         ecx,dword ptr [eax] 
0041142E  push        ecx  
0041142F  mov         edx,dword ptr [b] 
00411432  push        edx  
00411433  mov         eax,dword ptr [a] 
00411436  push        eax  
00411437  push        offset string "a = %d b = %d p = %d\n" (415800h) 
0041143C  call        dword ptr [__imp__printf (4182C4h)] 
00411442  add         esp,10h 
00411445  cmp         esi,esp 
00411447  call        @ILT+315(__RTC_CheckEsp) (411140h) 
 
	return 0;    
0041144C  xor         eax,eax 
}

仔细看看这里:是不是感觉指针和引用没有区别?

	int &p = a;
004113ED  lea         eax,[a] 
004113F0  mov         dword ptr [p],eax 
	int *pp = &a;
004113F3  lea         eax,[a] 
004113F6  mov         dword ptr [pp],eax

OllyDbg调试Release版本:

00401000  /$  83EC 08       SUB ESP,8
00401003  |.  56            PUSH ESI
00401004  |.  8D4424 08     LEA EAX,DWORD PTR SS:[ESP+8]
00401008  |.  50            PUSH EAX                                 ;  B
00401009  |.  8D4C24 08     LEA ECX,DWORD PTR SS:[ESP+8]             ;  %d\n
0040100D  |.  51            PUSH ECX                                 ;  A
0040100E  |.  68 04214000   PUSH Test.00402104                       ; /%d %d
00401013  |.  FF15 A4204000 CALL DWORD PTR DS:[<&MSVCR90.scanf>]     ; \scanf
00401019  |.  8B4424 14     MOV EAX,DWORD PTR SS:[ESP+14]
0040101D  |.  8B35 9C204000 MOV ESI,DWORD PTR DS:[<&MSVCR90.printf>] ;  MSVCR90.printf
00401023  |.  50            PUSH EAX                                 ; /<%d>
00401024  |.  68 0C214000   PUSH Test.0040210C                       ; |%d\n
00401029  |.  894424 18     MOV DWORD PTR SS:[ESP+18],EAX            ; |
0040102D  |.  FFD6          CALL ESI                                 ; \printf
0040102F  |.  8B4424 18     MOV EAX,DWORD PTR SS:[ESP+18]
00401033  |.  8B5424 1C     MOV EDX,DWORD PTR SS:[ESP+1C]
00401037  |.  50            PUSH EAX
00401038  |.  52            PUSH EDX
00401039  |.  50            PUSH EAX
0040103A  |.  68 10214000   PUSH Test.00402110                       ;  a = %d b = %d p = %d\n
0040103F  |.  FFD6          CALL ESI
00401041  |.  83C4 24       ADD ESP,24
00401044  |.  33C0          XOR EAX,EAX
00401046  |.  5E            POP ESI
00401047  |.  83C4 08       ADD ESP,8
0040104A  \.  C3            RETN

注意printf函数:引用就是用了被引用对象的地址,似乎就不存在。

00401037  |.  50            PUSH EAX
00401038  |.  52            PUSH EDX
00401039  |.  50            PUSH EAX
0040103A  |.  68 10214000   PUSH Test.00402110                       ;  a = %d b = %d p = %d\n

从汇编的角度看世界,一切都很明了。测试结果为:Debug模式下引用分配内存,Release模式下不分配内存。实际结果以编译器为准。
最后,我认为讨论这个问题没有意义。


觉得文章还不错?点击此处对作者进行打赏!


本文地址: 程序人生 >> 引用不分配内存?
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


更多



分类: 逆向调试 标签: , , ,
  1. 本文目前尚无任何评论.