欧美网址在线观看-亚洲最新毛片-国产成人免费爽爽爽视频-亚洲一区在线影院-日韩欧美在线观看视频网站-男女激情四射-成人一区二区免费看-欧美亚洲综合在线-日韩一级视频在线播放-国产成人三级视频在线播放-亚洲中文字幕日产无码2020-99久久久国产精品免费无卡顿-av在线观看地址-果冻传媒mv免费播放在线观看-欧美在线观看视频免费-日韩天天操

聯系我們 - 廣告服務 - 聯系電話:
您的當前位置: > 關注 > > 正文

從源代碼到二進制行程序 C語言的編譯過程是怎樣的?

來源:CSDN 時間:2023-01-12 10:33:08

前言

C語言程序從源代碼到二進制行程序都經歷了那些過程?本文以Linux下C語言的編譯過程為例,講解C語言程序的編譯過程。

編寫hello world C程序:


【資料圖】

// hello.c#includeint main(){    printf("hello world!\n");}

編譯過程只需:

$ gcc hello.c # 編譯$ ./a.out # 執行hello world!

這個過程如此熟悉,以至于大家覺得編譯事件很簡單的事。事實真的如此嗎?我們來細看一下C語言的編譯過程到底是怎樣的。

上述gcc命令其實依次執行了四步操作:1.預處理(Preprocessing), 2.編譯(Compilation), 3.匯編(Assemble), 4.鏈接(Linking)。

示例

為了下面步驟講解的方便,我們需要一個稍微復雜一點的例子。假設我們自己定義了一個頭文件mymath.h,實現一些自己的數學函數,并把具體實現放在mymath.c當中。然后寫一個test.c程序使用這些函數。程序目錄結構如下:

├── test.c└── inc    ├── mymath.h    └── mymath.c

程序代碼如下:

// test.c#include#include "mymath.h"http:// 自定義頭文件int main(){    int a = 2;    int b = 3;    int sum = add(a, b);     printf("a=%d, b=%d, a+b=%d\n", a, b, sum);}

頭文件定義:

// mymath.h#ifndef MYMATH_H#define MYMATH_Hint add(int a, int b);int sum(int a, int b);#endif

頭文件實現:

// mymath.cint add(int a, int b){    return a+b;}int sub(int a, int b){    return a-b;}

1.預處理(Preprocessing)

預處理用于將所有的#include頭文件以及宏定義替換成其真正的內容,預處理之后得到的仍然是文本文件,但文件體積會大很多。gcc的預處理是預處理器cpp來完成的,你可以通過如下命令對test.c進行預處理:

gcc -E -I./inc test.c -o test.i

或者直接調用cpp命令

$ cpp test.c -I./inc -o test.i

上述命令中-E是讓編譯器在預處理之后就退出,不進行后續編譯過程;-I指定頭文件目錄,這里指定的是我們自定義的頭文件目錄;-o指定輸出文件名。

經過預處理之后代碼體積會大很多:

X文件名文件大小代碼行數

預處理前test.c146B9

預處理后test.i17691B857

預處理之后的程序還是文本,可以用文本編輯器打開。

2.編譯(Compilation)

這里的編譯不是指程序從源文件到二進制程序的全部過程,而是指將經過預處理之后的程序轉換成特定匯編代碼(assembly code)的過程。編譯的指定如下:

$ gcc -S -I./inc test.c -o test.s

上述命令中-S讓編譯器在編譯之后停止,不進行后續過程。編譯過程完成后,將生成程序的匯編代碼test.s,這也是文本文件,內容如下:

// test.c匯編之后的結果test.s    .file   "test.c"    .section    .rodata.LC0:    .string "a=%d, b=%d, a+b=%d\n"    .text    .globl  main    .type   main, @functionmain:.LFB0:    .cfi_startproc    pushl   %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    andl    $-16, %esp    subl    $32, %esp    movl    $2, 20(%esp)    movl    $3, 24(%esp)    movl    24(%esp), %eax    movl    %eax, 4(%esp)    movl    20(%esp), %eax    movl    %eax, (%esp)    call    add     movl    %eax, 28(%esp)    movl    28(%esp), %eax    movl    %eax, 12(%esp)    movl    24(%esp), %eax    movl    %eax, 8(%esp)    movl    20(%esp), %eax    movl    %eax, 4(%esp)    movl    $.LC0, (%esp)    call    printf    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret     .cfi_endproc.LFE0:    .size   main, .-main    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"    .section    .note.GNU-stack,"",@progbits

請不要問我上述代碼是什么意思!-_-

3.匯編(Assemble)

匯編過程將上一步的匯編代碼轉換成機器碼(machine code),這一步產生的文件叫做目標文件,是二進制格式。gcc匯編過程通過as命令完成:

$ as test.s -o test.o

等價于:

gcc -c test.s -o test.o

這一步會為每一個源文件產生一個目標文件。因此mymath.c也需要產生一個mymath.o文件

4.鏈接(Linking)

鏈接過程將多個目標文以及所需的庫文件(.so等)鏈接成最終的可執行文件(executable file)。

命令大致如下:

$ ld -o test.out test.o inc/mymath.o ...libraries...

結語

經過以上分析,我們發現編譯過程并不像想象的那么簡單,而是要經過預處理、編譯、匯編、鏈接。盡管我們平時使用gcc命令的時候沒有關心中間結果,但每次程序的編譯都少不了這幾個步驟。也不用為上述繁瑣過程而煩惱,因為你仍然可以:

$ gcc hello.c # 編譯$ ./a.out # 執行

參考文獻

1.https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html 2.http://www.trilithium.com/johan/2005/08/linux-gate/ 3.https://gcc.gnu.org/onlinedocs/gccint/Collect2.html

責任編輯:

標簽:

相關推薦:

精彩放送:

新聞聚焦
Top 欧美网址在线观看-亚洲最新毛片-国产成人免费爽爽爽视频-亚洲一区在线影院-日韩欧美在线观看视频网站-男女激情四射-成人一区二区免费看-欧美亚洲综合在线-日韩一级视频在线播放-国产成人三级视频在线播放-亚洲中文字幕日产无码2020-99久久久国产精品免费无卡顿-av在线观看地址-果冻传媒mv免费播放在线观看-欧美在线观看视频免费-日韩天天操

        国产成人精品视频免费看| 不卡的av中文字幕| 亚洲午夜无码av毛片久久| 亚洲欧美一区二区三区不卡| 内射国产内射夫妻免费频道| 亚洲国产精品女人| 亚洲欧美手机在线| 国产精品嫩草影院8vv8| 日韩av片专区| 特黄视频免费观看| 久久人人爽av| 免费看污污视频| 久无码久无码av无码| 国产日韩欧美精品在线观看| 极品粉嫩国产18尤物| 日av中文字幕| 日本高清xxxx| 国产一级做a爰片久久| 一级黄色高清视频| 青青青青在线视频| 国产人妻人伦精品| 国产91对白刺激露脸在线观看| 亚洲一二三区av| 免费看国产一级片| japanese在线播放| 性欧美在线视频| 伊人成色综合网| 久艹在线免费观看| 亚洲最大天堂网| 国产精品一色哟哟| 欧美,日韩,国产在线| 黄色影视在线观看| 色网站在线视频| 日本不卡一区二区在线观看| 日本中文字幕网址| 久久99中文字幕| 欧美aⅴ在线观看| 日韩网址在线观看| 日韩免费高清在线| 奇米影视四色在线| 五月天激情播播| 亚洲妇熟xx妇色黄蜜桃| 国产一区一区三区| 日本福利视频网站| 国产精品国产亚洲精品看不卡| 亚洲熟妇无码一区二区三区| 久久www视频| 欧美综合在线观看视频| 日韩欧美xxxx| 欧美日韩视频免费| 午夜啪啪小视频| 久草资源站在线观看| 一级片视频免费观看| 久久亚洲精品无码va白人极品| 成人午夜免费在线| 亚洲制服在线观看| 色诱视频在线观看| 欧美成人三级在线视频| 亚洲成人福利在线| 在线观看av日韩| 日本一本二本在线观看| av一区二区三区免费观看| 国产永久免费网站| 视色视频在线观看| 国产又黄又猛又粗又爽的视频| 精品久久久久久无码中文野结衣| 精品久久免费观看| 国产一级片中文字幕| 中文字幕av导航| 一级性生活视频| 波多野结衣 作品| 亚洲色成人www永久在线观看| 好吊色这里只有精品| 一级黄色在线播放| 精品国产一区二区三区无码| 黄色片免费在线观看视频| 国产成人亚洲综合无码| 国产精品久久中文字幕| 亚洲色欲综合一区二区三区| 玩弄japan白嫩少妇hd| 久久99999| 国产一区二区三区在线免费| 日韩av片免费观看| 天天操天天爽天天射| 午夜影院免费版| 成人综合视频在线| 欧美少妇一级片| 蜜臀av免费观看| 欧美色图色综合| 一区二区三区四区毛片| 波多野结衣家庭教师在线| www激情五月| 午夜激情在线观看视频| 男女爱爱视频网站| 日日噜噜夜夜狠狠久久丁香五月| 爱情岛论坛vip永久入口| 99色精品视频| 亚洲免费av一区二区三区| 日韩视频第二页| 天堂在线资源视频| 午夜xxxxx| 神马午夜伦理影院| 97成人在线观看视频| 日本在线视频www| 日本不卡一区在线| 国产视频九色蝌蚪| 成年人午夜免费视频| 成人性做爰片免费视频| 99爱视频在线| 亚洲激情在线看| 久久撸在线视频| 无码人妻丰满熟妇区96| 国产精品jizz在线观看老狼| 狠狠热免费视频| 男人操女人免费软件| 欧美又粗又长又爽做受| 久久久久亚洲av无码专区喷水| 日本福利视频一区| 男人添女人荫蒂免费视频| 男人天堂网站在线| 国产精品视频网站在线观看| 秋霞在线一区二区| 国产四区在线观看| 伊人久久在线观看| 一二三四中文字幕| 日韩欧美中文视频| 性欧美大战久久久久久久| 一区二区传媒有限公司| 欧美日韩中文在线视频| 美女网站免费观看视频 | www国产精品内射老熟女| 天天久久综合网| 精品成在人线av无码免费看| 成人av一级片| 亚洲男人天堂2021| 日本韩国欧美在线观看| 久久国产精品国产精品| 免费国产黄色网址| 三上悠亚在线一区二区| 亚洲最新免费视频| 国产xxxxhd| 日韩欧美国产综合在线| 91小视频在线播放| 日韩黄色片在线| 2021狠狠干| 制服丝袜中文字幕第一页| 精品国产成人av在线免| 天天做天天爱天天高潮| 粗暴91大变态调教| 91传媒免费视频| 一道本在线免费视频| 精品少妇无遮挡毛片| 天天操天天干天天玩| 国产女人18毛片| a级黄色一级片| 国产视频在线视频| 国产亚洲视频一区| 日韩视频在线观看一区二区三区| www.天天射.com| 天堂av2020| 特级西西人体www高清大胆| 国产高潮免费视频| 99久久99久久精品| 青青青青草视频| 激情六月丁香婷婷| 日本国产一级片| 九九九九免费视频| 一本—道久久a久久精品蜜桃| 国内精品国产三级国产99| 成人国产一区二区三区| 国产一级片黄色| 九九九久久久久久久| 老太脱裤让老头玩ⅹxxxx| 国产九九在线观看| 欧美丰满熟妇bbbbbb百度| 成人午夜免费剧场| 992kp免费看片| 亚洲 激情 在线| 日日碰狠狠丁香久燥| 成人在线观看毛片| 欧美日韩午夜爽爽| 国产a级片免费看| 亚洲一区二区三区四区精品| 亚洲天堂国产视频| 人人干人人干人人| 国产九九热视频| 亚洲欧美国产中文| 日韩在线第三页| 国产人妻777人伦精品hd| 欧美精品卡一卡二| 黄色国产精品视频| 91香蕉视频污版| 不卡中文字幕在线| 老司机午夜av| 亚洲黄色av片| 国产av第一区| 日韩 欧美 高清| 国产精品h视频| 久久久久久久久久久久久国产精品| 阿v天堂2018|