www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 程序喵大人
[導(dǎo)讀]你知道一次gcc命令究竟經(jīng)歷了什么嗎? 我們先來(lái)看一段C語(yǔ)言示例源代碼: // test.cc#include int main() { printf("Hello 程序喵\n"); return 0;} 編譯運(yùn)行 $ gcc test.cc$ ./a.outHello 程序喵 如圖一, gcc構(gòu)建過(guò)程分解 我們平時(shí)都會(huì)使用gcc來(lái)編

你知道一次gcc命令究竟經(jīng)歷了什么嗎?

我們先來(lái)看一段C語(yǔ)言示例源代碼:

// test.cc#include <stdio.h>
int main() { printf("Hello 程序喵\n"); return 0;}

編譯運(yùn)行

$ gcc test.cc$ ./a.outHello 程序喵

如圖一,

gcc構(gòu)建過(guò)程分解

我們平時(shí)都會(huì)使用gcc來(lái)編譯程序,這一行簡(jiǎn)單的命令其實(shí)經(jīng)歷了很多復(fù)雜的過(guò)程:

  1. 預(yù)處理

  2. 編譯

  3. 匯編

  4. 鏈接

首先使用file看一下test.cc文件類型:

$ file test.cctest.cc: C source, UTF-8 Unicode text, with CRLF line terminators

我們接下來(lái)看看這每個(gè)過(guò)程都做了什么?

預(yù)處理

命令:

$ gcc -E test.cc -o test.i或者$ cpp test.cc -o test.i

再看下test.i的文件類型

$ file test.itest.i: C source, UTF-8 Unicode text

這里可以看出預(yù)處理后的文件和預(yù)處理前的文件類型是相同的,都是文本文件,也可以直接查看test.i的內(nèi)容,里面代碼較多,就不貼上來(lái)了。

其實(shí)預(yù)處理主要操作有這幾個(gè):

  • 展開(kāi)所有#define宏定義,進(jìn)行文本替換

  • 刪除程序中所有的注釋

  • 處理所有的條件編譯,#if、#ifdef、#elif等

  • 處理所有的#include指令,把這些頭文件的內(nèi)容都復(fù)制到引用的源文件中

  • 添加行號(hào)和文件名標(biāo)識(shí),方便編譯器產(chǎn)生警告及調(diào)試信息

  • 保留所有的#pragma編譯器指令,因?yàn)榫幾g器會(huì)使用他們

編譯

命令:

gcc -S test.cc -o test.s

再查看文件類型

$ file test.stest.s: assembler source, ASCII text

編譯過(guò)程分解

如圖二,編譯過(guò)程就是把預(yù)處理后的文件進(jìn)行一系列操作生成相應(yīng)的匯編文件:

  1. 詞法分析:又稱詞法掃描,通過(guò)掃描器,利用有限狀態(tài)機(jī)的算法將源碼中的字符串分割成一系列記號(hào),如加減乘除數(shù)字括號(hào)等。

  2. 語(yǔ)法分析:使用語(yǔ)法分析器對(duì)詞法分析產(chǎn)生的記號(hào)運(yùn)用上下文無(wú)關(guān)語(yǔ)法的手段進(jìn)行語(yǔ)法分析,產(chǎn)生語(yǔ)法分析樹(shù)。這期間如果表達(dá)式不合法(括號(hào)不匹配等),就會(huì)報(bào)錯(cuò)。

  3. 語(yǔ)義分析:語(yǔ)法分析檢查表達(dá)式是否合法,語(yǔ)義分析檢查表達(dá)式是否有意義,如浮點(diǎn)型整數(shù)賦值給指針,編譯器就會(huì)報(bào)錯(cuò)。

  4. 中間語(yǔ)言生成:做一些語(yǔ)法樹(shù)優(yōu)化,如6+2=8。

  5. 目標(biāo)代碼生成及優(yōu)化:將中間代碼生成目標(biāo)匯編代碼。

匯編

命令:

$ gcc -c test.s -o test.o$ as test.s -o test.o

查看文件類型:

$ file test.otestt.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

使用匯編器將匯編代碼轉(zhuǎn)成機(jī)器可以執(zhí)行的指令,其實(shí)就是將匯編指令和機(jī)器指令按照對(duì)照表一一翻譯。

鏈接

為什么匯編器不直接生成可執(zhí)行文件而是生成一個(gè)目標(biāo)文件呢,因?yàn)橐粋€(gè)文件需要依賴其它好多個(gè)庫(kù),這些庫(kù)的符號(hào)需要通過(guò)鏈接過(guò)程才可以互相配合生成一個(gè)可執(zhí)行文件,需要經(jīng)歷地址和空間分配、符號(hào)決議、重定位等步驟,這塊內(nèi)容較多,后續(xù)會(huì)詳細(xì)介紹,現(xiàn)在我們可以簡(jiǎn)單的通過(guò)ldd查看一下可執(zhí)行程序需要依賴的庫(kù),這些庫(kù)都需要在鏈接過(guò)程中被鏈接才可以使用。

$ ldd a.outlinux-vdso.so.1 (0x00007ffff5b4a000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa1fc660000)/lib64/ld-linux-x86-64.so.2 (0x00007fa1fce00000)

參考

程序員的自我修養(yǎng)——鏈接、裝載與庫(kù)




c++11識(shí)點(diǎn)!

c++團(tuán)隊(duì)

內(nèi)對(duì)

c++11


你點(diǎn)的每個(gè)贊,我都認(rèn)真當(dāng)成了喜歡

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉