gpt4 book ai didi

c - 组装:推 vs movl

转载 作者:太空狗 更新时间:2023-10-29 16:06:25 26 4
gpt4 key购买 nike

我有一些用 gcc 编译的 C 代码:

int main() {
int x = 1;
printf("%d\n",x);
return 0;
}

我已经通过 gdb 7.9.1 运行它并为 main 提供了这个汇编代码:

0x0000000100000f40 <+0>:    push   %rbp                   # save original frame pointer
0x0000000100000f41 <+1>: mov %rsp,%rbp # stack pointer is new frame pointer
0x0000000100000f44 <+4>: sub $0x10,%rsp # make room for vars
0x0000000100000f48 <+8>: lea 0x47(%rip),%rdi # 0x100000f96
0x0000000100000f4f <+15>: movl $0x0,-0x4(%rbp) # put 0 on the stack
0x0000000100000f56 <+22>: movl $0x1,-0x8(%rbp) # put 1 on the stack
0x0000000100000f5d <+29>: mov -0x8(%rbp),%esi
0x0000000100000f60 <+32>: mov $0x0,%al
0x0000000100000f62 <+34>: callq 0x100000f74
0x0000000100000f67 <+39>: xor %esi,%esi # set %esi to 0
0x0000000100000f69 <+41>: mov %eax,-0xc(%rbp)
0x0000000100000f6c <+44>: mov %esi,%eax
0x0000000100000f6e <+46>: add $0x10,%rsp # move stack pointer to original location
0x0000000100000f72 <+50>: pop %rbp # reclaim original frame pointer
0x0000000100000f73 <+51>: retq

据我了解,push %rbb 将帧指针压入堆栈,因此我们稍后可以使用 pop %rbp 检索它。然后,sub $0x10,%rsp 清除堆栈上的 10 字节空间,以便我们可以在上面放东西。

稍后与堆栈的交互通过内存寻址将变量直接移动到堆栈中,而不是将它们推送到堆栈中:

movl $0x0, -0x4(%rbp)
movl $0x1, -0x8(%rbp)

为什么编译器使用 movl 而不是 push 来获取这些信息到堆栈上?

在内存地址之后引用寄存器是否也会将该值放入该寄存器?

最佳答案

对于现代编译器来说,在函数开始时将堆栈指针移动一次,然后在结束时将其移回是很常见的。这允许更有效的索引,因为它可以将内存空间视为内存映射区域而不是简单的堆栈。例如,可以忽略突然发现无用的值(可能是由于优化的快捷运算符),而不是强制将它们从堆栈中弹出。

也许在更简单的日子里,使用推送是出于性能原因。对于现代处理器,没有任何优势,因此没有理由在编译器中设置特殊情况以尽可能使用 push/pop。编译器编写的汇编代码可读性不强!

关于c - 组装:推 vs movl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31660591/

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