7-6 指针参数作为返回值

1. 调用函数,使用函数返回值的流程:函数的返回值是一开始是存储在函数栈中的,然后复制到寄存器;在其他地方调用函数,使用函数的返回值时,会把寄存器中的函数返回值复制到到函数栈中进行使用,共完成两次拷贝

int SumIntArray(int array[], int length){
  int sum = 0;
  for (int i = 0; i < length; ++i) {
    sum += array[i];
  }
  return sum;
}

int main(){
  int array[5]={0,1,2,3,4};
  int b = SumIntArray(array, 5);
  printf("%d", b);
  return 0;
}

这个 demo 中,SumIntArray(array, 5) 的结果 sum 的值,就是先从函数栈拷贝到 eax 寄存器中,然后再从 eax 寄存器拷贝到变量 b 所在的函数栈地址中

之所以会发生两次拷贝,是因为指向函数栈的指针的值是变化的( [rbp-4] 的值是变化的 ),所以要将函数返回值暂存到寄存器中,等到要使用的时候再调用寄存器使用

2. 在 mingw 编译器下,通过 GDB 可以查看寄存器的值,这里查看 rbp 寄存器值的变化(我电脑只能查看 ebp 寄存器)

所以要用 eax 寄存器暂存一下函数的返回值,因为 ebp 值会变

3. 寄存器 EDX 和 RDX 的关系,RDX 的低32位就是 EDX,同样 EAX 是 RAX 的低32位,低32位清0的情况下,高32位也会清0,即 EDX 初始化等同 RDX 初始化

5. 结构体返回值:当函数返回值过大,一个寄存器存不下该怎么办?====> 使用多个寄存器进行存储

6. 将想返回的值,它的指针变量作为参数传入到函数中,避免发生两次拷贝,现在只发生了一次拷贝,从函数栈拷贝到寄存器中,没有后面那次寄存器拷贝至函数栈了

void SumIntArray2(int array[], int length, int *sum){
  *sum = 0;
  for (int i = 0; i < length; ++i) {
    *sum += array[i];
  }
}

7. 使用指针参数作为返回值的好处,
    1)避免函数返回值带来的开销
    2)实现函数多个返回值的目的

 

提问:

1. 关于5,结构体那边没太看懂汇编,尤其是赋值那一块

2. 关于6,这里真的是发生一次拷贝吗?虽然说 sum 的值被存储在了 rax 寄存器中,但是在 main 函数的使用中,不会将寄存器的值拷贝到函数栈中进行使用吗?原先的第二次拷贝就是为了使用才放到函数栈中的,尤其是在 main 函数中多添加一段 sum=sum+1 的代码,观察它的汇编代码:

如果这样,使用指针进行传参是否是一次拷贝,再者,指针传参减少了总程序的拷贝次数吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值