結合hello world探討gcc編譯程序的過程

本博客(http://blog.csdn.net/livelylittlefish)貼出作者(三二一@小魚)相關研究、學習內容所做的筆記,歡迎廣大朋友指正!

?

?

結合"hello world"探討gcc編譯程序的過程

?

1. gcc簡介

?

gcc/g++是GNU工程的C和C++編譯器。都要用四個步驟中的一個或多個處理輸入文件。

  • 預處理(preprocessing)
  • 編譯(compilation)
  • 匯編(assembly)
  • 連接(linking)

?

源文件后綴名標識源文件的語言,但是對編譯器來說,后綴名控制著缺省設定。

gcc命令的一般格式為:gcc [選項]?要編譯的文件?[選項] [目標文件]

?

gcc的詳細內容,可參考gcc manual。

?

2. gcc的輸出選項

?

gcc輸出選項,-o后指定輸出文件名,gcc解釋如下。

?

`-o FILE'

?????Place output in file FILE.??This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.

?????If `-o' is not specified, the default is to put an executable file in `a.out', the object file for `SOURCE.SUFFIX' in `SOURCE.o', its assembler file in `SOURCE.s', a precompiled header file in `SOURCE.SUFFIX.gch', and all preprocessed C source on standard output.

?

????指定輸出文件為FILE,該選項不考慮GCC產生什么輸出,無論是可執行文件、目標文件、匯編文件還是預處理后的C代碼。

????如果沒有使用`-o'選項,默認的輸出結果是:可執行文件為a.out,source.suffix的目標文件是source.o,匯編文件是source.s,而預處理后的C代碼送往標準輸出。

?

?

3. "hello wolrd"的處理過程

?

本文以"hello world"程序,探討GCC編譯程序的過程。

?

hello.c文件內容如下。

?

#include <stdio.h>

?

int main(int argc, char **argv)

{

????printf("Hello World! via %x/n", printf);

????return 0;

}

?

?

3.1?預處理(preprocessing)

?

在該階段,編譯器將C源代碼中的包含的頭文件如stdio.h編譯進來,可以使用gcc的選項”-E”進行查看預處理結果。

?

Gcc manual中對-E選項的解釋如下。

?

`-E'

?????Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.

?????Input files which don't require preprocessing are ignored.

????預處理后停止,不進行編譯。預處理后的代碼送往標準輸出。GCC忽略任何不需要預處理的輸入文件。

?

?

格式:gcc -E hello.c -o hello.i

作用:對hello.c進行預處理輸出為hello.i文件

?

Hello.c被預處理后的hello.i文件。

?

# 1 "hello.c"

# 1 "<built-in>"

# 1 "<command line>"

# 1 "hello.c"

# 1 "/usr/include/stdio.h" 1 3 4

# 28 "/usr/include/stdio.h" 3 4

# 1 "/usr/include/features.h" 1 3 4

# 335 "/usr/include/features.h" 3 4

# 1 "/usr/include/sys/cdefs.h" 1 3 4

# 360 "/usr/include/sys/cdefs.h" 3 4

# 1 "/usr/include/bits/wordsize.h" 1 3 4

# 361 "/usr/include/sys/cdefs.h" 2 3 4

# 336 "/usr/include/features.h" 2 3 4

# 359 "/usr/include/features.h" 3 4

# 1 "/usr/include/gnu/stubs.h" 1 3 4

?

?

# 1 "/usr/include/bits/wordsize.h" 1 3 4

# 5 "/usr/include/gnu/stubs.h" 2 3 4

?

?

# 1 "/usr/include/gnu/stubs-32.h" 1 3 4

# 8 "/usr/include/gnu/stubs.h" 2 3 4

# 360 "/usr/include/features.h" 2 3 4

# 29 "/usr/include/stdio.h" 2 3 4

?

?

# 1 "/usr/lib/gcc/i386-redhat-linux/4.1.2/include/stddef.h" 1 3 4

# 214 "/usr/lib/gcc/i386-redhat-linux/4.1.2/include/stddef.h" 3 4

typedef unsigned int size_t;

# 35 "/usr/include/stdio.h" 2 3 4

?

# 1 "/usr/include/bits/types.h" 1 3 4

# 28 "/usr/include/bits/types.h" 3 4

# 1 "/usr/include/bits/wordsize.h" 1 3 4

# 29 "/usr/include/bits/types.h" 2 3 4

?

?

typedef unsigned char __u_char;

typedef unsigned short int __u_short;

typedef unsigned int __u_int;

typedef unsigned long int __u_long;

?

?

typedef signed char __int8_t;

typedef unsigned char __uint8_t;

typedef signed short int __int16_t;

typedef unsigned short int __uint16_t;

typedef signed int __int32_t;

typedef unsigned int __uint32_t;

?

?

__extension__ typedef signed long long int __int64_t;

__extension__ typedef unsigned long long int __uint64_t;

?

?

__extension__ typedef long long int __quad_t;

__extension__ typedef unsigned long long int __u_quad_t;

# 131 "/usr/include/bits/types.h" 3 4

# 1 "/usr/include/bits/typesizes.h" 1 3 4

# 132 "/usr/include/bits/types.h" 2 3 4

?

...

?

?

3.2?編譯(compilation)

?

在這個階段中,Gcc首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤后,Gcc把代碼翻譯成匯編語言。可以使用”-S”選項來進行查看,該選項只進行編譯而不進行匯編,生成匯編代碼。

?

Gcc manual中對-S選項的解釋如下。

?

`-S'

?????Stop after the stage of?compilation?proper; do not assemble.??The output is in the form of?an assembler code file?for each non-assembler input file specified.

?????By default, the assembler file name for a source file is made by replacing the suffix `.c', `.i', etc., with `.s'. Input files that don't require compilation are ignored.

?????編譯后即停止,不進行匯編。對于每個輸入的非匯編語言文件,輸出文件是匯編語言文件。

?????缺省情況下,GCC通過用`.o'替換源文件名后綴`.c',`.i'等以產生目標文件名。可以使用-o選項指定選擇其他名字。GCC忽略任何不需要編譯的輸入文件。

?

?

格式:gcc –S hello.i –o hello.s

作用:將預處理輸出文件hello.i匯編成hello.s文件

?

Hello.i被匯編后的hello.s文件。

?

??.file????????"hello.c"

??.section????????.rodata

.LC0:

??.string????????"Hello World! via %x/n"

??.text

.globl main

??.type????????main, @function

main:

??leal????????4(%esp), %ecx

??andl????????$-16, %esp

??pushl????????-4(%ecx)

??pushl????????%ebp

??movl????????%esp, %ebp

??pushl????????%ecx

??subl????????$20, %esp

??movl????????$printf, 4(%esp)

??movl????????$.LC0, (%esp)

??call????????printf

??movl????????$0, %eax

??addl????????$20, %esp

??popl????????%ecx

??popl????????%ebp

??leal????????-4(%ecx), %esp

??ret

??.size????????main, .-main

??.ident????????"GCC: (GNU) 4.1.2 20070925 (Red Hat 4.1.2-33)"

??.section????????.note.GNU-stack,"",@progbits

?

?

3.3?匯編(assembly)

?

匯編階段是把編譯階段生成的.s文件轉成二進制目標代碼。

?

gcc manual中對選項-C的解釋如下。

?

`-c'

?????Compile or assemble the source files, but do not link. The linking stage simply is not done.??The ultimate output is in the form of an object file for each source file.

?????By default, the object file name for a source file is made by replacing the suffix `.c', `.i', `.s', etc., with `.o'. Unrecognized input files, not requiring compilation or assembly, are ignored.

?????編譯或匯編源文件,但不連接,編譯器輸出對應于源文件的目標文件。

?????缺省情況下,GCC通過用'.o'替換源文件名后綴`.c', `.i', `.s'等等以產生目標文件名。可以使用-o選項指定選擇其他名字。GCC忽略-c選項后面任何無法識別的不需要編譯或匯編的輸入文件。

?

?

gcc manual中對選項-V的解釋如下。

?

`-v'

?????Print (on standard error output) the commands executed to run the stages of compilation.??Also print the version number of the compiler driver program and of the preprocessor and the compiler proper.

????(在標準錯誤輸出)顯示執行編譯階段的命令,同時顯示編譯器驅動程序、預處理器、編譯器的版本號。

?

?

格式:gcc?–c hello.s?–o hello.o

作用:將編譯輸出的.s文件匯編成二進制目標代碼.o文件

?

我們可以通過objdump程序來查看hello.o的內容。

?

# objdump -d hello.o

?

hello.o:?????file format elf32-i386

?

Disassembly of section .text:

?

00000000 <main>:

???0:???8d 4c 24 04?????????????lea????0x4(%esp),%ecx

???4:???83 e4 f0????????????????and????$0xfffffff0,%esp

???7:???ff 71 fc????????????????pushl??-0x4(%ecx)

???a:???55??????????????????????push???%ebp

???b:???89 e5???????????????????mov????%esp,%ebp

???d:???51??????????????????????push???%ecx

???e:???83 ec 14????????????????sub????$0x14,%esp

??11:???c7 44 24 04 00 00 00????movl???$0x0,0x4(%esp)

??18:???00

??19:???c7 04 24 00 00 00 00????movl???$0x0,(%esp)

??20:???e8 fc ff ff ff??????????call???21 <main+0x21>

??25:???b8 00 00 00 00??????????mov????$0x0,%eax

??2a:???83 c4 14????????????????add????$0x14,%esp

??2d:???59??????????????????????pop????%ecx

??2e:???5d??????????????????????pop????%ebp

??2f:???8d 61 fc????????????????lea????-0x4(%ecx),%esp

??32:???c3??????????????????????ret???

?

?

3.4?鏈接(linking)

?

編譯成功后,就進入鏈接。

格式:gcc hello.o -o hello.exe

??或者gcc hello.o -o hello

作用:將編譯輸出的.o文件鏈接為最終可執行文件。

?

同樣,我們也可以通過objdump程序來查看鏈接后的輸出hello文件的內容。

?

?

hello:?????file format elf32-i386

?

Disassembly of section .init:

?

08048298 <_init>:

?8048298:????????55???????????????????????????push???%ebp

?8048299:????????89 e5????????????????????????mov????%esp,%ebp

?804829b:????????83 ec 08?????????????????????sub????$0x8,%esp

?804829e:????????e8 71 00 00 00???????????????call???8048314 <call_gmon_start>

?80482a3:????????e8 f8 00 00 00???????????????call???80483a0 <frame_dummy>

?80482a8:????????e8 d3 01 00 00???????????????call???8048480 <__do_global_ctors_aux>

?80482ad:????????c9???????????????????????????leave?

?80482ae:????????c3???????????????????????????ret???

Disassembly of section .plt:

?

080482b0 <__gmon_start__@plt-0x10>:

?80482b0:????????ff 35 40 96 04 08????????????pushl??0x8049640

?80482b6:????????ff 25 44 96 04 08????????????jmp????*0x8049644

?80482bc:????????00 00????????????????????????add????%al,(%eax)

...

?

080482c0 <__gmon_start__@plt>:

?80482c0:????????ff 25 48 96 04 08????????????jmp????*0x8049648

?80482c6:????????68 00 00 00 00???????????????push???$0x0

?80482cb:????????e9 e0 ff ff ff???????????????jmp????80482b0 <_init+0x18>

?

080482d0 <__libc_start_main@plt>:

?80482d0:????????ff 25 4c 96 04 08????????????jmp????*0x804964c

?80482d6:????????68 08 00 00 00???????????????push???$0x8

?80482db:????????e9 d0 ff ff ff???????????????jmp????80482b0 <_init+0x18>

?

080482e0 <printf@plt>:

?80482e0:????????ff 25 50 96 04 08????????????jmp????*0x8049650

?80482e6:????????68 10 00 00 00???????????????push???$0x10

?80482eb:????????e9 c0 ff ff ff???????????????jmp????80482b0 <_init+0x18>

?

...

?

080483c4 <main>:

?80483c4:????????8d 4c 24 04??????????????????lea????0x4(%esp),%ecx

?80483c8:????????83 e4 f0?????????????????????and????$0xfffffff0,%esp

?80483cb:????????ff 71 fc?????????????????????pushl??-0x4(%ecx)

?80483ce:????????55???????????????????????????push???%ebp

?80483cf:????????89 e5????????????????????????mov????%esp,%ebp

?80483d1:????????51???????????????????????????push???%ecx

?80483d2:????????83 ec 14?????????????????????sub????$0x14,%esp

?80483d5:????????c7 44 24 04 e0 82 04 ????????movl???$0x80482e0,0x4(%esp)

?80483dc:????????08

?80483dd:????????c7 04 24 d0 84 04 08 ????????movl???$0x80484d0,(%esp)

?80483e4:????????e8 f7 fe ff ff???????????????call???80482e0?<printf@plt>

?80483e9:????????b8 00 00 00 00???????????????mov????$0x0,%eax

?80483ee:????????83 c4 14?????????????????????add????$0x14,%esp

?80483f1:????????59???????????????????????????pop????%ecx

?80483f2:????????5d???????????????????????????pop????%ebp

?80483f3:????????8d 61 fc?????????????????????lea????-0x4(%ecx),%esp

?80483f6:????????c3???????????????????????????ret???

?80483f7:????????90???????????????????????????nop???

?

...

?

?

4. 小結

?

編譯程序的4個過程:

預處理:gcc -E hello.c -o hello.i

編譯:gcc –S hello.i –o hello.s
匯編:gcc –c hello.s –o hello.o
鏈接:gcc hello.o -o hello

?

轉自:http://blog.csdn.net/livelylittlefish/article/details/5109300

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280711.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280711.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280711.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Powershell 時間相關

1.時間相差秒數計算 $start Get-Date Get-HotFix $end Get-Date Write-Host -ForegroundColor Red (Total Runtime: ($end - $start).TotalSeconds)//若開始時間保存為字符串$startTime Get-Date -Format yyyyMMddTHH:mm:ss $startTime[datetime]::ParseExact("$sta…

java類中,成員變量賦值第一個進行,其次是靜態構造函數,再次是構造函數

如題是結論&#xff0c;如果有人問你Java類的成員初始化順序和初始化塊知識就這樣回答他。下面是代碼&#xff1a; package com.test;public class TestClass{// 成員變量賦值第一個執行private static int m11;private int m21;// 靜態構造函數第二個執行static{System.out.pr…

Unity的未來,是固守Mono,還是擁抱CoreCLR?

TLDR;Unity堅定的擁抱.NET標準生態&#xff0c;正全速向CoreCLR遷移。Mono vs CoreCLR對于一個C#的初學者&#xff0c;首先要了解的便是.NET和C#的關系。所以這里不再贅述。對于一個Unity的初學者&#xff0c;在使用C#編碼的過程中&#xff0c;一定會遇到一些C#新特性不能在項目…

hinton教授的本科生課程CSC321-機器學習中的神經網的筆記

最近一直在看仙守博友所記錄的筆記 Hinton的CSC321課程&#xff08;完結&#xff0c;待文字潤色&#xff09;&#xff1a; 1、lecture1-NN的簡介 2、lecture2-NN結構的主要類型的概述和感知機 3、lecture3-線性神經元和算法 4、lecture4-神經網絡在語言上的應用 5、lecture5-對…

ASP存儲過程參數數據類型

ASP調用存儲過程一般的方法&#xff1a; p.Append cmd.CreateParameter("參數名稱",類型,方向,大小) 參許參數值的類型的意義如下&#xff1a; 名稱值 整數值 功能 adDBTimeStamp 135 日期時間數據類型 adDecimal 14 十進制整數值 adDouble …

powershell 啟動線程與關閉線程

啟動線程 $ScreenCapture"C:\ResolutionTool\ScreenCapture.exe" Start-Process $ScreenCapture 關閉線程 Get-Process ScreenCapture| Stop-Process

HDU 5673 Robot 卡特蘭數

題目鏈接&#xff1a; http://acm.hdu.edu.cn/showproblem.php?pid5673 題目描述&#xff1a; 一個人從原點開始向右走&#xff0c; 要求N秒后回到原點&#xff0c; 且過程中不能到負半軸&#xff0c; 人有兩種操作&#xff0c; 走動或者停止&#xff0c; 問總共有多少種方案&…

刪除本地賬戶無法登錄電腦_如何從Windows的登錄屏幕中刪除本地用戶帳戶

刪除本地賬戶無法登錄電腦If you have multiple user accounts on your computer, you might find it annoying to have to click on the icon for your username each time you start up the computer. To remedy this problem, you can hide a user account with a registry …

tarjan算法詳解

https://blog.csdn.net/jeryjeryjery/article/details/52829142?locationNum4&fps1 以防鏈接失效&#xff0c;特此轉載此博&#xff0c;如有侵權請見諒 在有向圖G中&#xff0c;如果兩個頂點間至少存在一條路徑&#xff0c;稱兩個頂點強連通(strongly connected)。如果有向…

Gitlab簡單使用CI/CD

開篇語大概是去年就想做這個事情了&#xff0c;奈何當時卡到一個docker命令找不到的問題上&#xff0c;導致文章難產了&#xff0c;墨跡了這么久&#xff0c;終于又有空來搗鼓它了。目的我們要實現的目的是我本地不斷提交代碼(CI),然后服務器不斷進行部署(CD)的一個簡單流程。準…

AppleScript: Handler

AppleScript絕對是個奇葩的存在&#xff01;不管功能有多強大。 Handler有兩種&#xff0c;一種是和OC類似的使用Label參數&#xff0c;一種是和javascript類似的使用括號把一堆參數都放在里面的。 label參數的Handler的寫法非常奇怪&#xff0c;光看文檔絕對讓人迷糊。這里按照…

powershell 運行策略

Unrestricted 這是一種比較寬容的策略&#xff0c;允許運行未簽名的腳本。對于從網絡上下載的腳本&#xff0c;在運行前會進行安全性提示&#xff1a; Set-ExecutionPolicy UnRestricted

免費的數字圖書館_不僅是書籍:您當地圖書館可能提供的所有免費數字資料

免費的數字圖書館You might think of libraries as old fashioned, or irrelevant in the age of the internet. You’d be wrong. 您可能會認為圖書館是老式的&#xff0c;或者與互聯網時代無關。 你會錯的。 Modern libraries offer books, yes, but they also provide inter…

iNeuOS工業互聯網操作系統,腳本化實現設備運行時長和效率計算與統計

目 錄1. 概述... 22. 實時采集開停狀態... 23. 增加虛擬設備... 24. 腳本統計和計算設備運行時長... 45. 設備運行時長報表... 71. 概述有一個煤礦項目&#xff0c;使用iNeuOS系統時有一個需要是&#xff1a;要統計設備的運行時長&#xff0c…

webpack二(以webpack4.x起步)

一.基本安裝首先我們要創建一個目錄&#xff0c;初始化npm&#xff0c;以及在本地安裝webpack&#xff1a;復制代碼mkdir webpackapp && cd webpackapp復制代碼npm init -y復制代碼npm install --save-dev webapck復制代碼現在我們看一下我們創建的目錄以及目錄下的結構…

阿里云中間件是什么-阿里云中間件介紹

阿里云中間件是什么?這其實是一個比較虛的概念。廣義的中間件范圍很廣。起溝通作用的都可以認為是中間件。甚至ODBC這樣的東西你也可以認為是中間件。 使用了中間件之后&#xff0c;以前直接連接的前臺應用程序和數據庫之前就多了個中間件&#xff0c;現在前臺程序把請求發給…

C# 圖片、文件等加入Project Resources

一、目的 1.編譯后&#xff0c;只想有一個exe文件&#xff0c;不想外部文件引用&#xff0c;直接運行exe文件即可。 2.不會出現文件丟失情況。 二、操作 1.右擊project ->properties->Resource&#xff0c;左上角選擇Image&#xff08;或其他類型&#xff09; 2. 點擊…

jfinal使用shiro注解大體流程

2019獨角獸企業重金招聘Python工程師標準>>> 上一篇答題梳理了jfinal整合shiro的流程&#xff0c;jfinal讀取shiro注解&#xff0c;這一篇將作為補充。 1.JFinalShiroPlugin作者為shiro的RequiresRoles&#xff0c;RequiresPermissions&#xff0c; RequiresAuthent…

chrome 快捷鍵取消_如何使用鍵盤快捷鍵在Chrome和Firefox中固定和取消固定選項卡...

chrome 快捷鍵取消If you tend to open a lot of tabs in your browser, it can become difficult to find the tabs with your most used websites. Pinning tabs in your browser moves those tabs to the left and shrinks the tabs to only show the favicon, and you can …

.NET Conf China 2022參會指南速覽(內含超多福利)趕緊預約!???

12月充滿驚喜各種美好節日紛至沓來似在獎勵一年辛苦勞作的你12月的第一波福利.NET Conf China 承包啦立即掃碼預約加入.NET年度盛宴搶12月第一波驚喜&#xff01;.NET Conf China 2022 .NET Conf China 2022是面向開發人員的社區峰會&#xff0c;延續 .NET Conf 2022 的活動&a…