1. 程式人生 > >被隱藏了的過程

被隱藏了的過程

匯編指令 cnblogs str print 語句 define gcc ifdef 對照表

C語言經典,“Hello World”耳熟能詳,是每個人程序入門和開發環境測試的默認標準。

1 #include <studio.h>
2 
3 int main()
4 {
5     printf("Hello World");
6     return 0;
7 }

在Linux下,我們用gcc編譯該程序(假設文件名為hello.c),只需要用最簡單的命令.

$gcc hello.c
$./a.out
Hello World

但是,事實上,其中包含了4個步驟:預處理編譯匯編鏈接

  預處理

  預處理過程將處理源代碼中以“#”開始的預編譯指令,生成文件以.i為拓展名。相當於執行語句(-E表示只進行預編譯;-o 表示命名)

$gcc -E hello.c -o hello.i

或者

$cpp hello.c > hello.i

預編譯過程中的主要處理規則如下:

  • 將所有的“#define”刪除,並展開所有的宏定義
  • 處理所有的預編譯指令,如“#if”,“#ifdef”等
  • 處理“#include”指令,將被包含的文件插入到該指令位置。該過程是遞歸進行
  • 刪除所有的註釋
  • 添加行號和文件名標識
  • 保留所有的#pragma指令

當我們無法判斷宏定義是否正確或頭文件包含是否正確是,可以選擇查看預編譯文件

  編譯

  編譯過程就是講預處理完的文件進行一系列的詞法、語法、語義分析以及優化後產生相應的匯編代碼文件。(推薦看龍虎鯨)

編譯過程相當於執行如下指令:

$gcc -S hello.i -o hello.s

在執行該語句時,gcc會根據不同參數要求去調用預編譯編譯程序cc1,匯編器as,鏈接器ld。

  匯編

  匯編是將匯編代碼轉變成機器可執行的指令。一般是根據匯編指令和機器指令的對照表意義翻譯。該過程相當於執行語句:

$as hello.s -o hello.o

$gcc -c hello.s -o hello.o

  鏈接

  鏈接的過程比較復雜,我們會在後續文章中詳細介紹。簡單說,就是將匯編器產生的目標文件進行鏈接得到可執行文件。

2017-08-06

被隱藏了的過程