c++函数参数传递

从汇编代码看c++基础数据类型 的数组参数传递

double数组

void test(double arr1[],int n){
    for (size_t i = 0; i < n; i++)
    {
        arr1[i] = i * 2;
    }   

};
int main(){
    double * arr = new double[10];
    for (size_t i = 0; i < 10; i++)
    {
        arr[i] = i;
    }
    test(arr,10);
    return 0;
}

main函数汇编

Dump of assembler code for function main():
   0x0000555555556334 <+0>:	endbr64 
   0x0000555555556338 <+4>:	push   rbp
   0x0000555555556339 <+5>:	mov    rbp,rsp
   0x000055555555633c <+8>:	sub    rsp,0x10         //上面代码给main 分配栈空间
   0x0000555555556340 <+12>:	mov    edi,0x50
   0x0000555555556345 <+17>:	call   0x555555556110 <_Znam@plt>  //创建数组 并把内存地址 放入rax中  operator new[](unsigned long)
   0x000055555555634a <+22>:	mov    QWORD PTR [rbp-0x8],rax     //把数组地址备份在[rbp-0x8] 
   0x000055555555634e <+26>:	mov    QWORD PTR [rbp-0x10],0x0
   0x0000555555556356 <+34>:	cmp    QWORD PTR [rbp-0x10],0x9
   0x000055555555635b <+39>:	ja     0x5555555563a1 <main()+109>
   0x000055555555635d <+41>:	mov    rax,QWORD PTR [rbp-0x10]
   0x0000555555556361 <+45>:	lea    rdx,[rax*8+0x0]
   0x0000555555556369 <+53>:	mov    rax,QWORD PTR [rbp-0x8]
   0x000055555555636d <+57>:	lea    rcx,[rdx+rax*1]
   0x0000555555556371 <+61>:	mov    rax,QWORD PTR [rbp-0x10]
   0x0000555555556375 <+65>:	test   rax,rax
   0x0000555555556378 <+68>:	js     0x555555556381 <main()+77>
   0x000055555555637a <+70>:	cvtsi2sd xmm0,rax
   0x000055555555637f <+75>:	jmp    0x555555556396 <main()+98>
   0x0000555555556381 <+77>:	mov    rdx,rax
   0x0000555555556384 <+80>:	shr    rdx,1
   0x0000555555556387 <+83>:	and    eax,0x1
   0x000055555555638a <+86>:	or     rdx,rax
   0x000055555555638d <+89>:	cvtsi2sd xmm0,rdx
   0x0000555555556392 <+94>:	addsd  xmm0,xmm0
   0x0000555555556396 <+98>:	movsd  QWORD PTR [rcx],xmm0
   0x000055555555639a <+102>:	add    QWORD PTR [rbp-0x10],0x1
   0x000055555555639f <+107>:	jmp    0x555555556356 <main()+34>        //上面是main函数中数组赋值 不关注
   0x00005555555563a1 <+109>:	mov    rax,QWORD PTR [rbp-0x8]           //把备份在[rbp-0x8]数组地址 取出 放入 rax
   0x00005555555563a5 <+113>:	mov    esi,0xa                            //把10放入esi      test函数的第二个参数  
   0x00005555555563aa <+118>:	mov    rdi,rax                            //把数组地址放入rdi test函数的第一个参数
   0x00005555555563ad <+121>:	call   0x5555555562c9 <test(double*, int)>
   0x00005555555563b2 <+126>:	mov    eax,0x0
   0x00005555555563b7 <+131>:	leave  
   0x00005555555563b8 <+132>:	ret    

test函数汇编

Dump of assembler code for function test(double*, int):
   0x00005555555562c9 <+0>:	endbr64 
   0x00005555555562cd <+4>:	push   rbp                //备份上个函数的基址指针
   0x00005555555562ce <+5>:	mov    rbp,rsp             //更新新的基址指针为rsp   相当于给画个分界线
   0x00005555555562d1 <+8>:	mov    QWORD PTR [rbp-0x18],rdi  //rdi是函数调用的第一个参数   取出来放入[rbp-0x18]  每个函数独立的rbp
   0x00005555555562d5 <+12>:	mov    DWORD PTR [rbp-0x1c],esi   //esi是函数调用的第二个参数   取出来放入[rbp-0x1c] 注每个函数独立的rbp
   0x00005555555562d8 <+15>:	mov    QWORD PTR [rbp-0x8],0x0    //[rbp-0x8] 等价于c++代码中的局部变量i
   0x00005555555562e0 <+23>:	mov    eax,DWORD PTR [rbp-0x1c]
   0x00005555555562e3 <+26>:	cdqe   
   0x00005555555562e5 <+28>:	cmp    QWORD PTR [rbp-0x8],rax         //这个指令是循环控制的条件
   0x00005555555562e9 <+32>:	jae    0x555555556331 <test(double*, int)+104>   //如果i >= rax(传递的第二个参数)则跳转,否则 向下执行
   0x00005555555562eb <+34>:	mov    rax,QWORD PTR [rbp-0x8]
   0x00005555555562ef <+38>:	add    rax,rax                         //这边等效于执行了 i*2 存放的临时计算结果
   0x00005555555562f2 <+41>:	mov    rdx,QWORD PTR [rbp-0x8]
   0x00005555555562f6 <+45>:	lea    rcx,[rdx*8+0x0]               //这个代码作用实现指针增加的作用 rcx 存入的相对数组首地址的相对偏移量
   0x00005555555562fe <+53>:	mov    rdx,QWORD PTR [rbp-0x18]
   0x0000555555556302 <+57>:	add    rcx,rdx                       //这边rcx 里面存入的就是具体数组元素的地址了
   0x0000555555556305 <+60>:	test   rax,rax                        //错误检测  如果结果为负数 则执行 72到102行逻辑
   0x0000555555556308 <+63>:	js     0x555555556311 <test(double*, int)+72>
   0x000055555555630a <+65>:	cvtsi2sd xmm0,rax
   0x000055555555630f <+70>:	jmp    0x555555556326 <test(double*, int)+93>   //无条件跳转
   0x0000555555556311 <+72>:	mov    rdx,rax
   0x0000555555556314 <+75>:	shr    rdx,1
   0x0000555555556317 <+78>:	and    eax,0x1
   0x000055555555631a <+81>:	or     rdx,rax
   0x000055555555631d <+84>:	cvtsi2sd xmm0,rdx
   0x0000555555556322 <+89>:	addsd  xmm0,xmm0
   0x0000555555556326 <+93>:	movsd  QWORD PTR [rcx],xmm0
   0x000055555555632a <+97>:	add    QWORD PTR [rbp-0x8],0x1
   0x000055555555632f <+102>:	jmp    0x5555555562e0 <test(double*, int)+23>
   0x0000555555556331 <+104>:	nop
   0x0000555555556332 <+105>:	pop    rbp                                      //恢复调用函数基址指针
   0x0000555555556333 <+106>:	ret                                             //恢复调用函数ip

结论: double数组没有复制,函数间通过指针传递,共用相同的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值