簡體   English   中英

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

[英]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 uopsenter a, 0 8時每8周期吞吐量enter a, 0Agner 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM