从汇编代码分析(一级)指针形参
用于测试的C++源码:
int* f(int *a) { *a=10; a=0; return a; }
int main(int argc, char **argv) { int a = 1, *p = &a; f(p); }
MS Windows x64, 汇编代码:
Dump of assembler code for function f(int*): 0x0000000000401550 <+0>: push rbp 0x0000000000401551 <+1>: mov rbp,rsp 0x0000000000401554 <+4>: mov QWORD PTR [rbp+0x10],rcx ;分配新的地址空间[rbp+0x10]用于保存p=&a,a地址值 => 0x0000000000401558 <+8>: mov rax,QWORD PTR [rbp+0x10] ;a地址值传给rax 0x000000000040155c <+12>: mov DWORD PTR [rax],0xa ;修改a地址处的内存值 *p=10,注:此处mian函数中变量a值被修改。 0x0000000000401562 <+18>: mov QWORD PTR [rbp+0x10],0x0 ;修改新的内存地址[rbp+0x10]的值为0 0x000000000040156a <+26>: mov rax,QWORD PTR [rbp+0x10] ;返回新地址空间[rbp+0x10]的值,f(p)=rax=0。 0x000000000040156e <+30>: pop rbp 0x000000000040156f <+31>: ret End of assembler dump.
Dump of assembler code for function main(int, char**): ;main函数被库函数__tmainCRTStartup调用。__tmainCRTStartup被WinMainCRTStartup或WinMainCRTStartup,mainCRTStartup(用于控制台应用程序)调用 0x0000000000401570 <+0>: push rbp ;外部函数的rbp入栈 0x0000000000401571 <+1>: mov rbp,rsp 0x0000000000401574 <+4>: sub rsp,0x30 ;开辟main函数栈空间:0x30 0x0000000000401578 <+8>: mov DWORD PTR [rbp+0x10],ecx ;main函数参数1:argc 0x000000000040157b <+11>: mov QWORD PTR [rbp+0x18],rdx ;main函数参数2:argv 0x000000000040157f <+15>: call 0x4016e0 <__main> ;_main检测初始化是否完成。若initialized不为0,则retrun eip;若initialized为0,则设为initialized=1,然后call __do_global_ctors 0x0000000000401584 <+20>: mov DWORD PTR [rbp-0xc],0x1 ;a=1,a地址:[rbp-0xc],类型int 0x000000000040158b <+27>: lea rax,[rbp-0xc] ;获取a变量地址 0x000000000040158f <+31>: mov QWORD PTR [rbp-0x8],rax ;p=&a,把a变量地址传输给指针变量p;p地址[rbp-0x8] 0x0000000000401593 <+35>: mov rax,QWORD PTR [rbp-0x8] ;获取p变量值,即变量a的地址。 0x0000000000401597 <+39>: mov rcx,rax ;f(int*)参数保存在rcx中,rcx=p=&a 0x000000000040159a <+42>: call 0x401550 <f(int*)> ;call f(int*) 0x000000000040159f <+47>: mov eax,0x0 ;main函数返回值eax=0. 0x00000000004015a4 <+52>: add rsp,0x30 ;回收main函数栈空间 0x00000000004015a8 <+56>: pop rbp 0x00000000004015a9 <+57>: ret End of assembler dump.
结论:
f(int*)执行后:
f(int* )函数中*a=10,改变了main函数中变量a的值,即改变了指针p所指对象的值
f(int*)函数中a=0,对main函数中a变量无影响,改变了指针p的局部拷贝对象,实参未改变

浙公网安备 33010602011771号