时间:2021-05-19
首先是引用情形下的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
可以看到,指针和引用的汇编码一样,因此两者的作用也一样
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C++中引用与指针的区别实例详解引用是从C++才引入的,在C中不存在。为了搞清楚引用的概念,得先搞明白变量的定义及引用与变量的区别,变量的要素一共有两个:名称与
C++引用与指针的比较引用是C++中的概念,初学者容易把引用和指针混淆一起。一下程序中,n是m的一个引用(reference),m是被引用物(referent)
C++智能指针shared_ptr分析概要:shared_ptr是c++智能指针中适用场景多,功能实现较多的智能指针。它采取引用计数的方法来实现释放指针所指向的
介绍引用是C++中特有的语法,在C语言中不存在。本质上引用(reference)就是指针,在类型名后面加上一个&号就是引用类型。1.指针与引用的定义进行比较指针
指针与引用是C++中两个很重要的概念,它们功能看过去很相似,就是都是间接引用某个对象,那么我们应该在什么时候使用指针,什么时候使用引用呢,下面请允许我慢慢道来: