[英]How can gcc generate assembly which can set up stack frame with ENTER instruction
我用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;
}
GCC永远不会发出enter
因为与2或3个单uup指令的常规帧指针设置相比,它超慢。
(如果它完全使帧指针; gcc -O1
和更高版本将启用-fomit-frame-pointer
。除非进行大小优化,否则因为x(%rsp)
寻址模式比x(%rbp)
模式使用额外的字节。 )
# 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
具体来说,在Skylake上, enter
为12 uops , enter a, 0
8时每8周期吞吐量enter a, 0
( Agner Fog的指令表 )。 嵌套级别为非零时,它会异常缓慢,例如87 cycles + 7 * nesting level
。
在Ryzen上, enter
为12微妙,每16个周期吞吐量一次。
leave
的还好:在Intel CPU上只有3微秒。 (不过,这仍然比mov %rbp, %rsp
/ pop %rbp
一个。3 oups不包含堆栈同步uop;即使堆栈引擎在leave
前处于同步状态,它也为3。)
使用enter
的唯一原因将是牺牲速度来优化代码大小。 但是,即使gcc -Os
也不太在乎代码大小,无法为此提供选择。
甚至clang -Oz
(将使用push $1
/ pop %rax
来保存2个字节,而mov $1, %eax
)也不使用enter
。 ( Godbolt编译器资源管理器 )
但是enter 0,0
甚至都不会保存代码大小,因此这完全是错误的。
我遵循一本手册,其中说程序以ENTER开始输入
这是一个(过时且不建议使用的)选项。
如果要编写使代码变慢的自己的编译器,请继续。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.