gcc如何生成可以使用ENTER指令设置堆栈框架的程序集

时间:2019-05-14 14:12:28

标签: gcc assembly x86

我用gcc生成这样的汇编代码,gcc可以生成对堆栈框架具有ENTER键的代码吗?

.file   "temp.c"
.text
.globl  main
.type   main, @function
main:
pushq   %rbp
movq    %rsp, %rbp
movl    $0, -12(%rbp)
movl    $0, -8(%rbp)
movl    $0, -4(%rbp)
movl    $0, %eax
popq    %rbp
ret
.size   main, .-main
.ident  "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04) 7.4.0"
.section    .note.GNU-stack,"",@progbits

这是原始代码:

 #include <stdio.h>
  int main(){
   int a;
   int b;
   int c;
   a = 0;
   b = 0;
   c = 0;
}

1 个答案:

答案 0 :(得分:3)

GCC永远不会发出enter ,因为与普通的2或3条单uup指令的帧指针设置相比,它的速度非常慢。

(如果它完全使帧指针; gcc -O1及更高版本将启用-fomit-frame-pointer。除了进行大小优化外,因为x(%rsp)寻址模式与{{1 }}模式。)

x(%rbp)

具体来说,在Skylake # equivalent to enter $24, $0 (4 bytes) push %rbp # 1 byte mov %rsp, %rbp # 3 bytes sub $24, %rsp # 4 bytes only for a non-zero immediate 上为12 oups,对于enterAgner Fog's instruction tables),每8周期吞吐量一个。嵌套级别为非零时,它非常缓慢,就像enter a, 0

在Ryzen上,87 cycles + 7 * nesting level为12 oups,每16周期吞吐量为一个。

enter很好,但是:在Intel CPU上只有3微秒。 (尽管这仍然比leave / mov %rbp, %rsp多一个。3个不包含堆栈同步uop;即使堆栈引擎在pop %rbp之前是同步的,它也是3个。)


使用leave的唯一原因是以牺牲速度为代价来优化代码大小。但是,即使enter也不在乎代码大小,无法为此选择一个选项。

即使gcc -Os(将使用clang -Oz / push $1来保存2个字节而不是pop %rax)也不使用mov $1, %eax。 (Godbolt compiler explorer

但是enter甚至都没有保存代码大小,因此简直太糟糕了。

  

我遵循一本手册,该手册说程序以ENTER开始输入

这是一个(过时且不推荐使用的)选项。

如果您想编写自己的编译器来编写慢速代码,请继续。