1. 程式人生 > >執行c程式碼前發生了什麼

執行c程式碼前發生了什麼

眾所周知,c程式碼也是一種比較高階的語言了,機器是沒有辦法直接執行的,機器所能理解的只有機器碼--那一串0和1而已。

雖然早就知道c程式碼是先經過編譯連結最後才放在機器上執行,但是在這麼一個過程中究竟發生了什麼,最近在學習嵌入式裸機開發中,才又有了更深入的瞭解。

簡單描述一下生成機器程式碼過程

編譯過程

編譯過程是以前就知道了的,預編譯會對一些帶#號的預編譯命令處理,如#define等,編譯器會對他們進行替換得到.i檔案,然後進一步編譯得到.o檔案。

連結過程

在將原始檔編譯成可執行檔案時,有一個過程是連結。

其實我以前就對這個連結過程感覺有些不解的,這個連結過程到底是怎麼把這些.o檔案連結在一起,是有一種什麼樣的規則呢,總不可能隨便連結的吧,隨便連結的話怎麼解決依賴問題。

直到之前瞭解了一下alios系統,在學習的過程中發現,在晶片架構的支援中,有一個elf檔案,裡面定義了一些地址,當時還不知道有什麼用;最近學習裸機開發中,也遇到了這麼一個類似的lds檔案。

通過學習,才知道,原來這種檔案定義了各個段如程式碼段、資料段等的地址,這樣編譯器在連結的過程中,就知道了要把各種.o檔案以什麼樣的順序連結,連結在什麼地址處。

準備c語言執行環境

這是我在網上找的圖,從圖中可以看出,為了使c程式可以執行在目標處理器,連結的過程中,還混入了一些其他的東西,比如Startup Code。

在Startup Code中,會做一系列的事,比如關中斷、重定位、申請棧空間等等,具體過程和硬體相關。

最後跳轉到main()。

網上有一篇基於ARM介紹這些相關知識的,非常建議去看看,可以解決自己以前嵌入式程式設計的很多疑惑。

http://www.bravegnu.org/gnu-eprog/c-startup.html

篇外話

這篇博文是在接觸到了一些啟動程式碼後突然有的想法,就開始整理自己的思路,寫的同時,在谷歌上查詢自己疑惑的地方,從runtime environment查到startup code,結果發現自己疑惑的地方卻更多了O__O "…,好好的一篇科普文變成了推薦閱讀文(手動笑哭)

非常建議看看下面給出的參考資料,相信對初學者會有很大幫助。

參考資料