gpt4 book ai didi

c - 给定一个程序,我们如何确定执行的保存/恢复操作的数量?

转载 作者:行者123 更新时间:2023-11-30 18:58:54 24 4
gpt4 key购买 nike

假设我们有以下简单的程序:

int foo() {
int a = 1, b = 2, c = 3, w;
c = abs(c);
c = c + b + 7;
for (w = 0; w<10; w++) {
b += bar(b);
}
return c;
}

int bar(int v) {
int a = 1, b = 2;
a += v + b;
printf(“v=%d\n”, v);
return v;
}

如果foo()被调用一次,我们如何确定变量 a 执行的保存/恢复操作的次数, b , c ,和w当存储在调用者保存的寄存器中与被调用者保存的寄存器中时?我可能不理解术语,但是解释一下确定每个变量在每种情况下有多少加载/存储的过程会很棒。

感谢您的宝贵时间。

最佳答案

唯一的答案是“至少为零”。

  1. 现代编译器将删除 a , b ,和c来自foo() 。由于这些变量不存在,因此它们永远不会被加载或存储。

  2. w变量可能存在,也可能通过展开循环来消除。

  3. ab bar() 中的变量不需要,因此它们也可能会被删除。

输出可能是什么样子:

编译器可能会产生如下输出:

int foo()
{
printf("v=%d\n", 2);
printf("v=%d\n", 4);
printf("v=%d\n", 8);
printf("v=%d\n", 16);
printf("v=%d\n", 32);
printf("v=%d\n", 64);
printf("v=%d\n", 128);
printf("v=%d\n", 256);
printf("v=%d\n", 512);
printf("v=%d\n", 1024);
return 12;
}

如您所见,在此优化版本中没有要保存或恢复的变量。

更新

使用 -O2 进行编译时,GCC 保存 rbxrbp在 x86-64 上被调用者保存的寄存器。这些寄存器保存一次并恢复一次。 GCC 的输出 foo()从不打电话bar() ,它调用 printf()直接。

foo:
pushq %rbp ; save register rbp
movl $2, %ebp ; b = 2
pushq %rbx ; save register rbx
movl $10, %ebx ; ctr = 10
subq $8, %rsp
.L4: ; begin loop
movl %ebp, %esi
xorl %eax, %eax
movl $.LC0, %edi
call printf ; printf("v=%d\n", b)
addl %ebp, %ebp ; b += b
subl $1, %ebx ; ctr--
jne .L4 ; end loop (when ctr == 0)
addq $8, %rsp
movl $12, %eax ; return 12
popq %rbx ; restore register rbx
popq %rbp ; restore register rbp
ret

关于c - 给定一个程序,我们如何确定执行的保存/恢复操作的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14679210/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com