簡體   English   中英

為什么x86-64上的GCC在函數內部插入NOP?

[英]Why does GCC on x86-64 insert a NOP inside of a function?

給定以下C函數:

void go(char *data) {
    char name[64];
    strcpy(name, data);
}

x86-64上的GCC 5和6編譯(普通gcc -c -g -o后跟objdump )這個:

0000000000000000 <go>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 50             sub    $0x50,%rsp
   8:   48 89 7d b8             mov    %rdi,-0x48(%rbp)
   c:   48 8b 55 b8             mov    -0x48(%rbp),%rdx
  10:   48 8d 45 c0             lea    -0x40(%rbp),%rax
  14:   48 89 d6                mov    %rdx,%rsi
  17:   48 89 c7                mov    %rax,%rdi
  1a:   e8 00 00 00 00          callq  1f <go+0x1f>
  1f:   90                      nop
  20:   c9                      leaveq 
  21:   c3                      retq   

GCC是否有任何理由在1f處插入90 / nop ,或者只是在未啟用優化時可能發生的副作用?

注意:這個問題與大多數其他問題不同,因為它詢問函數體內的nop ,而不是外部填充。

測試的編譯器版本:GCC Debian 5.3.1-14(5.3.1)和Debian 6-20160313-1(6.0.0)

這很奇怪,我從來沒有注意過-O0之前的asm輸出中的雜散nop (可能是因為我不浪費時間查看未優化的編譯器輸出)。

通常nop的內部函數是對齊分支目標,包括像Brian鏈接的問題函數入口點。 (另請參閱gcc文檔中的 -falign-loops 默認情況下在-Os之外的優化級別處啟用)。


在這種情況下, nop是裸空函數的編譯器噪聲的一部分:

void go(void) {
    //char name[64];
    //strcpy(name, data);
}
    push    rbp
    mov     rbp, rsp
    nop                     # only present for gcc5, not gcc 4.9.3
    pop     rbp
    ret

在Godbolt Compiler Explorer中查看該代碼,以便您可以檢查asm是否有其他編譯器版本和編譯選項。

(技術上不是噪聲,但-O0啟用-fno-omit-frame-pointer ,並且-O0甚至空函數設置並拆除堆棧幀。)


當然,該nop不存在於任何非零優化級別。 問題中的代碼中的nop沒有調試或性能優勢。 (請參閱標記wiki中的性能指南鏈接,尤其是Agner Fog的微體系結構指南 ,了解在當前CPU上使代碼快速運行的原因。)

我的猜測是它純粹是gcc內部的神器 nop是有作為nopgcc -S ASM輸出,而不是作為一個.p2align指令。 gcc本身不計算機器代碼字節,它只是在某些點使用對齊指令來對齊重要的分支目標。 只有匯編程序知道實際需要多大的nop才能達到給定的對齊。

默認的-O0告訴gcc你希望它快速編譯而不是編寫好的代碼。 這意味着asm輸出會告訴您更多關於gcc內部的信息,而不是其他-O級別,而關於如何優化或其他任何內容的信息很少。

如果您正在嘗試學習asm,那么查看-Og處的代碼會更有趣(例如,針對調試進行優化)。

如果您正在嘗試查看gcc或clang在編寫代碼時的表現,那么您應該查看-O3 -march=native (或-O2 -mtune=intel ,或者您構建項目的任何設置)。 然而,在-O3進行的優化令人費解是學習一些asm技巧的好方法。 -fno-tree-vectorize如果你想要看到除此之外完全優化的非矢量化版本,那么它很方便。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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