[英]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.