簡體   English   中英

為什么具有不同gcc版本的簡單C程序的匯編代碼不同?

[英]Why assembly code is different for simple C program with different gcc version?

我了解匯編和C編程的基礎知識。

我用C編譯了以下簡單程序,

#include <stdio.h>

int main()
{
  int a;
  int b;
  a = 10;
  b = 88

  return 0;
}

用以下命令編譯,

gcc -ggdb -fno-stack-protector test.c -o測試

使用gcc版本4.4.7的上述程序的反匯編代碼為:

5                      push   %ebp
89 e5                   mov    %esp,%ebp
83 ec 10                sub    $0x10,%esp
c7 45 f8 0a 00 00 00    movl   $0xa,-0x8(%ebp)
c7 45 fc 58 00 00 00    movl   $0x58,-0x4(%ebp)
b8 00 00 00 00          mov    $0x0,%eax
c9                      leave
c3                      ret
90                      nop

但是,與gcc版本4.3.3相同的程序的反匯編代碼為:

8d 4c 23 04     lea     0x4(%esp), %ecx
83 e4 f0        and     $0xfffffff0, %esp
55              push    -0x4(%ecx)
89 e5           mov     %esp,%ebp
51              push     %ecx
83 ec 10        sub      $0x10,%esp
c7 45 f4 0a 00 00 00 00 movl $0xa, -0xc(%ebp)
c7 45 f8 58 00 00 00 00 movl $0x58, -0x8(%ebp)
b8 00 00 00 00          mov $0x0, %eax
83 c4 10                add $0x10,%esp
59                      pop %ecx
5d                      pop %ebp
8d 61 fc                lea -0x4(%ecx),%esp
c3                      ret 

為什么匯編代碼不同?
在第二個匯編代碼中可以看到,為什么將%ecx壓入堆棧?
and $0xfffffff0, %esp含義and $0xfffffff0, %esp什么?

注意:操作系統相同

編譯器不需要為相同的源代碼生成相同的匯編代碼。 只要可觀察的行為相同,C標准就允許編譯器按其認為合適的方式優化代碼。 因此,不同的編譯器可能會生成不同的匯編代碼。

對於您的代碼,帶有-O3 GCC 6.2只會生成:

xor     eax, eax
ret

因為您的代碼基本上什么都不做。 因此,它簡化為簡單的return語句。

為了給您一些想法,有多少種方法可以為特定任務創建有效的代碼,我認為這個示例可能會有所幫助。

有時會有大小編碼競賽,顯然是針對匯編程序員的,因為在此級別上您根本無法與編譯器競爭手寫匯編。

競賽任務相當瑣碎,可以通過精確的輸入和輸出規范(最小到單字節或像素完美)來使入門水平和總精力變得合理。

因此,您幾乎要完成一些瑣碎的精確任務,即人為生成的代碼(目前仍勝過瑣碎任務的編譯器),並以一個簡單的規則“最小大小”為目標。

根據您的邏輯,絕對清楚每個競爭對手都應產生相同的結果。

現實世界對此的答案例如:

Hugi尺寸編碼比賽系列 -Compo29-隨機迷宮生成器

12個條目,代碼大小(以字節為單位):122、122、128、135、136、137、147,... 278(!)。

我敢打賭,前兩個條目都具有122B可能足夠不同(太懶了,無法實際檢查它們)。

現在,從高級編程語言和由機器(編譯器)產生有效的機器代碼要復雜得多。 而且,編譯器無法在推理上與人類競爭,大多數“ c ++編譯器如何產生良好的代碼”源於C ++語言本身的定義非常接近於機器代碼(易於編譯),並且源於殘酷的CPU功能,使編譯器能夠針對特定的代碼路徑處理成千上萬的變體,主要通過蠻力搜索接近最佳的解決方案。

優化器背后的數字“推理”仍然以他們自己的方式發展到了人類無法觸及的地步,但更像是以他們自己的方式,就像人無法在合理的努力下實現編譯器的效率一樣用於完整的應用程序編譯。

在這一點上,一些調試代碼在少數幫助序言/結尾說明中有所不同的原因...即使您發現優化代碼有所不同,並且這種差異對人類來說是“顯而易見的”,但編譯器仍然可以在此方面壯大最不重要的是,因為編譯器必須在特定代碼上應用通用規則,而不真正了解任務的上下文。

暫無
暫無

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

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