从C源代码到可执行文件的四个过程:预处理、编译、汇编、链接
從C源代碼到可執(zhí)行文件的四個(gè)過程:預(yù)處理、編譯、匯編、鏈接
總覽
我們將在Linux操作系統(tǒng)中,以C語言的Hello World程序?yàn)槔?#xff0c;用gcc編譯器分步執(zhí)行這四個(gè)步驟。
我們有再熟悉不過的HelloWorld程序,hello.c:
#include <stdio.h>int main(){printf("Hellow World.\n");return 0; }預(yù)處理
預(yù)處理階段 預(yù)處理器(cpp)根據(jù)以#字節(jié)開頭的命令,修改原始的C程序,
執(zhí)行預(yù)處理命令:gcc -E hello.c -o hello.i,我們得到由.c文件得到.i文件:hello.i:
# 1 "hello.c" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "hello.c" # 1 "/usr/include/stdio.h" 1 3 4 # 27 "/usr/include/stdio.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 1 3 4 # 33 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 3 4 # 1 "/usr/include/features.h" 1 3 4 # 424 "/usr/include/features.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4 # 427 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 # 428 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4 # 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4 # 429 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4 # 425 "/usr/include/features.h" 2 3 4 # 448 "/usr/include/features.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4 # 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4 # 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4 # 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4 # 449 "/usr/include/features.h" 2 3 4 # 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4 # 28 "/usr/include/stdio.h" 2 3 4編譯
編譯階段 編譯器(cc1)將文本文件hello.i翻譯成文本文件hello.s,它包含一個(gè)匯編語言程序。
執(zhí)行編譯命令:gcc -S hello.i -o hello.s,我們得到由.i文件得到.s文件:hello.s,這就是匯編文件:
.file "hello.c".text.section .rodata .LC0:.string "Hellow World.".text.globl main.type main, @function main: .LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6leaq .LC0(%rip), %rdicall puts@PLTmovl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc .LFE0:.size main, .-main.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0".section .note.GNU-stack,"",@progbits匯編
匯編階段 匯編器(as)將hello.s翻譯成機(jī)器語言指令,把這些指令打包成一種叫做可重定位目標(biāo)程序的格式,并保存在hello.o文件中,這是一個(gè)二進(jìn)制文件,無法直接用文本編輯器查看。
執(zhí)行編譯命令:gcc -c hello.s -o hello.o,我們得到由.s文件得到.o文件:hello.o,可重定向文件文件,這個(gè)文件就不是文本文件了,因此無法展示。
至此以上三步其實(shí)可以由-c參數(shù)直接得到可重定向文件:gcc -c hello.c -o hello.o,以上是為了說明預(yù)處理和編譯兩步,專門分步進(jìn)行,以查看輸出。
鏈接
鏈接階段 hello程序調(diào)用了printf函數(shù),它來自C標(biāo)準(zhǔn)庫,具體存在于一個(gè)已經(jīng)預(yù)編譯好的printf.o文件,鏈接器(ld)負(fù)責(zé)將這個(gè)文件與我們的hello文件合并起來。
執(zhí)行鏈接命令gcc hello.o -o hello,我們有.s文件得到可執(zhí)行文件hello,直接./hello執(zhí)行即可在命令行打印輸出Hellow World。
Ref:CSAPP
總結(jié)
以上是生活随笔為你收集整理的从C源代码到可执行文件的四个过程:预处理、编译、汇编、链接的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百事可乐市值
- 下一篇: COCO 数据集格式及mmdetecti