Analysis of the use of references and Pointers in c++ from assembly
- 2020-04-01 21:38:55
- OfStack
The first is the reference case of c++ source code:
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);
}
The following is the assembly code corresponding to main:
; 6 : int main() {
push ebp
mov ebp, esp
sub esp, 12 ; Reserve the stack space for the calling function 12byte To store local variables a . b, c
; 7 : int a = 1;
mov DWORD PTR _a$[ebp], 1; Initialize the a _a$ for a Storage space address relative to ebp The offset of the base address
; 8 : int b = 2;
mov DWORD PTR _b$[ebp], 2; Initialize the b _b$ for b Storage space address relative to ebp The offset of the base address
; 9 : int c = 0;
mov DWORD PTR _c$[ebp], 0; First try, c _c$ for c Storage space address relative to ebp The offset of the base address
; 10 : add(a, b, c);
lea eax, DWORD PTR _c$[ebp]; To obtain c Storage space relative to ebp The offset of the base address ( namely c The offset address of the storage location ), Put in register eax In the
push eax; save c Memory space offset to the stack
mov ecx, DWORD PTR _b$[ebp]; will b The value in the storage space ( namely b The value of the ) Put in register ecx In the
push ecx; save b The value of the storage space to the stack
mov edx, DWORD PTR _a$[ebp]; will a The value in the storage space ( namely a The value of the ) Put in register edx inside
push edx; save a Storage space to the stack
; The above push eax push ecx push edx The original local variables are stored in the stack a . b . c Theta, except for theta c In terms of storage is c The offset address of the storage space
; So, for a . b That is, to save a copy of their worth, that is, to pass the value; while c Just stored their own storage space offset address, that is, the address
call ?add@@YAXHHAAH@Z ; call add The above statement is ready to pass arguments
add esp, 12 ; Because I just called the function add Pass the parameters to the stack, where the stack space is freed, that is, the parameters are released
; That's why local variables and arguments are not valid after the function call, because their space is freed, right
; 11 :
; 12 : }
xor eax, eax
mov esp, ebp
pop ebp
ret 0
The following is the assembly code corresponding to the function 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]; Take parameters a To register eax In the
add eax, DWORD PTR _b$[ebp]; Take parameters b The value of and eax In the a I'm going to add up the values of theta eax In the
mov ecx, DWORD PTR _c$[ebp]; Go to the c The offset address of ecx In the
mov DWORD PTR [ecx], eax; will eax The results are written by ecx In the specified address cell, i.e c Storage location
; 3 : }
pop ebp
ret 0
As you can see from the above, c++ does indeed pass a copy of the value for the pass value, while for the reference, it is passed in the form of the pass value, but the value address is passed inside the compiler
The following is the case of pointer c++ source code:
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);
}
Assembly code corresponding to mian function:
; 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
The assembly code corresponding to the add function:
; 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
As you can see, a pointer is the same as the sink code for a reference, so both work the same way