編譯器是把代碼編譯成機器能夠執行的二進制機器碼的工具,對於嵌入式設備基本都是須要使用交叉編譯工具鏈。java
編譯好以後的程序,才能夠在目標設備上面運行。linux
編譯器通常分爲以下步驟工具
預編譯 —> 編譯 —> 連接優化
拿linux gcc編譯器來講ui
預編譯是解析提供的的程序源碼的頭文件,而且對於其中的宏進行展開。spa
對於一套源碼咱們每每會定義不少宏,以下.net
#define 定義一個預處理宏
#undef 取消宏的定義
#if 編譯預處理中的條件命令,至關於C語法中的if語句
#ifdef 判斷某個宏是否被定義,若已定義,執行隨後的語句
#ifndef 與#ifdef相反,判斷某個宏是否未被定義
#elif 若#if, #ifdef, #ifndef或前面的#elif條件不知足,則執行#elif以後的語句,至關於C語法中的else-if
#else 與#if, #ifdef, #ifndef對應, 若這些條件不知足,則執行#else以後的語句,至關於C語法中的else
#endif #if, #ifdef, #ifndef這些條件命令的結束標誌.
defined 與#if, #elif配合使用,判斷某個宏是否被定義blog
編譯器經過解析這些字段能夠爲後續的編譯提供統一的輸入環境。文檔
預編譯以後的hello_wrold.c 以下圖編譯器
編譯,顧名思義就是把咱們人能看懂的代碼編譯成咱們看不懂的二進制代碼。
編譯器優化:編譯時會讀取某些關鍵字,對於有這些關鍵字修飾的變量會不作優化處理,好比volunteer 。
CPU指令集(二進制)—> 彙編 —>C語言 —>java (計算機語言的發展)
因爲計算機只能執行二進制碼,因此任何語言都是須要經過編譯以後才能在上面執行的。(解析器是另一套東西,後面能夠彙總一下解析器的原理)
gcc編譯器能夠把所提供的代碼編譯成彙編語言,彙編語言裏各類寄存器的操做移位等。
gcc編譯其中有靜態編譯和動態編譯的區別,靜態編譯會把對應庫文件裏的代碼也拷貝到當前的程序上。
而動態編譯則只是把當前的代碼編譯成二進制碼,與所須要的動態模塊進行連接。
在運行動態編譯的二進制程序時,程序會到系統庫亦或者連接庫裏找對應標記的代碼段來運行,靜態編譯則不須要。
動態編譯的優勢是節省了空間,並且CPU又是串行的,畢竟像printf這樣的代碼段誰須要誰加載,用完釋放,其樂融融。
給系統動態庫添加其餘的目錄 export LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:
相關指令
gcc -E xx.c -O xx.i #預編譯
gcc -S xx.i -o xx.s #編譯成彙編
gcc -C xx.s xx.o #編譯成二進制
objdump –d xx.o #反彙編
gcc xx.o -o xx.exe #連接
參考文檔:https://blog.csdn.net/feng_ge3/article/details/80721059
多謝