从汇编看c++中引用与指针的使用分析
从汇编看c++中引用与指针的使用分析
发布时间:2016-12-28 来源:查字典编辑
摘要:首先是引用情形下的c++源码:复制代码代码如下:voidadd(inta,intb,int&c){c=a+b;}intmain(){inta...

首先是引用情形下的c++源码:

复制代码 代码如下:

void add(int a, int b, int&c) {

c = a + b;

}

int main() {

int a = 1;

int b = 2;

int c = 0;

add(a, b, c);

}

下面是main对应的汇编码:

复制代码 代码如下:

; 6 : int main() {

push ebp

mov ebp, esp

sub esp, 12 ; 为该调用函数的栈空间预留12byte,用来存储局部变量a,b, c

; 7 : int a = 1;

mov DWORD PTR _a$[ebp], 1;初始化a _a$为a存储空间地址相对于ebp基址的偏移量

; 8 : int b = 2;

mov DWORD PTR _b$[ebp], 2;初始化b _b$为b存储空间地址相对于ebp基址的偏移量

; 9 : int c = 0;

mov DWORD PTR _c$[ebp], 0;初试化c _c$为c存储空间地址相对于ebp基址的偏移量

; 10 : add(a, b, c);

lea eax, DWORD PTR _c$[ebp]; 获取c存储空间相对于ebp基址的偏移量(即c存储单元的偏移地址),放在寄存器eax中

push eax;保存c存储空间的偏移量到堆栈中

mov ecx, DWORD PTR _b$[ebp];将b存储空间里面的值(即b的值)放在寄存器ecx中

push ecx;保存b存储空间的值到堆栈中

mov edx, DWORD PTR _a$[ebp];将a存储空间里面的值(即a的值)放在寄存器edx里面

push edx;保存a存储空间的到堆栈

;上面push eax push ecx push edx在栈里面存储了原来局部变量a,b,c的值,只不过对于c来说,存储的是c存储空间的偏移地址

;因此,对于a,b来说,也就是将他们的值得一份拷贝存了起来,也就是传值;而c只是存储了自己存储空间的偏移地址,也就是传地址

call ?add@@YAXHHAAH@Z ; 调用add函数,上面的语句已经为传递参数做好了准备

add esp, 12 ; 由于刚才为调用函数add传递参数进行了压栈,这里释放栈空间,即释放参数

;这就是为什么函数调用完成后局部变量和参数无效的原因,因为他们的空间被释放了

; 11 :

; 12 : }

xor eax, eax

mov esp, ebp

pop ebp

ret 0

下面是函数add对应的汇编码:

复制代码 代码如下:

; 1 : void add(int a, int b, int&c) {

push ebp

mov ebp, esp

; 2 : c = a + b;

mov eax, DWORD PTR _a$[ebp];取参数a的值到寄存器eax中

add eax, DWORD PTR _b$[ebp];取参数b的值与eax中a的值相加,结果放到eax中

mov ecx, DWORD PTR _c$[ebp];去c的偏移地址放到寄存器ecx中

mov DWORD PTR [ecx], eax;将eax中的结果写到由ecx指定的地址单元中去,即c所在存储单元

; 3 : }

pop ebp

ret 0

从上面可以看到,对于传值,c++确实传的是一份值拷贝,而对于引用,虽然是传值的形式,但是其实编译器内部传递的是值得地址

下面是指针的情形的c++源码:

复制代码 代码如下:

void add(int a, int b, int* c) {

*c = a + b;

}

int main() {

int a = 1;

int b = 2;

int c = 0;

add(a, b, &c);

}

mian函数对应的汇编码:

复制代码 代码如下:

; 6 : int main() {

push ebp

mov ebp, esp

sub esp, 12 ;

; 7 : int a = 1;

mov DWORD PTR _a$[ebp], 1

; 8 : int b = 2;

mov DWORD PTR _b$[ebp], 2

; 9 : int c = 0;

mov DWORD PTR _c$[ebp], 0

; 10 : add(a, b, &c);

lea eax, DWORD PTR _c$[ebp]

push eax

mov ecx, DWORD PTR _b$[ebp]

push ecx

mov edx, DWORD PTR _a$[ebp]

push edx

call ?add@@YAXHHPAH@Z ; add

add esp, 12 ;

; 11 :

; 12 : }

xor eax, eax

mov esp, ebp

pop ebp

ret 0

add函数对应的汇编码:

复制代码 代码如下:

; 1 : void add(int a, int b, int* c) {

push ebp

mov ebp, esp

; 2 : *c = a + b;

mov eax, DWORD PTR _a$[ebp]

add eax, DWORD PTR _b$[ebp]

mov ecx, DWORD PTR _c$[ebp]

mov DWORD PTR [ecx], eax

; 3 : }

pop ebp

ret 0

可以看到,指针和引用的汇编码一样,因此两者的作用也一样

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新C语言学习
热门C语言学习
编程开发子分类