在最開始人們編寫程序時(shí),都將所有的代碼都寫在同一個(gè)源文件中,經(jīng)過長(zhǎng)期的積累,程序可能包含了N多行的代碼,程序員維護(hù)起來非常困難。迫切地希望將程序源代碼分散到多個(gè)文件中,一個(gè)文件一個(gè)模塊,能夠更好地閱讀和維護(hù)程序,這個(gè)時(shí)候,鏈接器就閃亮登場(chǎng)了。
我們知道,數(shù)據(jù)是保存在存儲(chǔ)器中的,對(duì)于單片機(jī)來說,必須知道這些數(shù)據(jù)的地址才能使用。變量名、函數(shù)名等僅僅是地址的一種代名詞兒,旨在編程時(shí)更加方便地使用數(shù)據(jù),當(dāng)源文件被編譯成可執(zhí)行文件后,這些標(biāo)識(shí)符都不存在了,它們都被替換成了數(shù)據(jù)的地址。
任何程序的執(zhí)行,最終都要依靠計(jì)算機(jī)硬件來完成,單片機(jī)是大規(guī)模集成電路,它只認(rèn)識(shí)高低兩個(gè)電平(電壓),假設(shè)高電平為 3.3V,用1表示,低電平為 0V,用0表示。也就是說,在單片機(jī)底層,只有 0 和 1 兩個(gè)二進(jìn)制數(shù)字,這就是機(jī)器語言。
使用機(jī)器語言編程,十分繁瑣又耗時(shí),并且很容易出錯(cuò)。如果程序包含了多個(gè)源文件,就很可能會(huì)有跨文件的跳轉(zhuǎn)、在程序擁有多個(gè)模塊時(shí)會(huì)導(dǎo)致更加嚴(yán)重的問題。于是大神們發(fā)明了匯編語言,這相比機(jī)器語言來說是個(gè)很大的進(jìn)步。匯編語言使用接近人類的各種標(biāo)號(hào)來幫助記憶,比如用jmp表示跳轉(zhuǎn)指令,用func表示一個(gè)子程序(C語言中的函數(shù)就是一個(gè)子程序)的起始地址,標(biāo)號(hào)的方法使得人們從具體的機(jī)器指令和二進(jìn)制地址中解放出來。標(biāo)號(hào)這個(gè)概念隨著匯編語言的普及被廣泛接受,它用來表示一個(gè)地址,這個(gè)地址可能是一段子程序的起始地址,也可以是一個(gè)變量的地址。
隨著軟件規(guī)模的日漸龐大,代碼量開始瘋長(zhǎng),匯編語言的缺點(diǎn)逐漸暴露出來。匯編雖然提供了多種標(biāo)號(hào),但它依然非常接近計(jì)算機(jī)硬件,程序員要考慮很多細(xì)節(jié)問題和邊界問題,而且不利于模塊化開發(fā),所以后來人們發(fā)明了C語言。C語言是比匯編更加高級(jí)的編程語言,極大地提高了開發(fā)效率,以加法為例,C語言只需要一條語句,匯編卻需要四五條。
單片機(jī)編程中,程序員通過會(huì)把很多功能分散到成許多個(gè)模塊中。這些模塊之間相互依賴又相互獨(dú)立,原則上每個(gè)模塊都可以單獨(dú)開發(fā)、編譯、測(cè)試,改變一個(gè)模塊中的代碼不需要編譯整個(gè)程序。在程序被分隔成多個(gè)模塊后,需要解決的一個(gè)重要問題是如何將這些模塊組合成一個(gè)單一的可執(zhí)行程序。在C語言中,模塊之間的依賴關(guān)系主要有兩種:一種是模塊間的函數(shù)調(diào)用,另外一種是模塊間的變量訪問。函數(shù)調(diào)用需要知道函數(shù)的首地址,變量訪問需要知道變量的地址,所以這兩種方式可以歸結(jié)為一種,那就是模塊間的符號(hào)引用。這種通過符號(hào)將多個(gè)模塊拼接為一個(gè)獨(dú)立的可執(zhí)行程序的過程就叫做鏈接(Linking)。
在一個(gè)STM32項(xiàng)目中,代碼被分為多個(gè)文件時(shí),鏈接器可以鏈接ARM代碼、Thumb代碼、Thumb-2 代碼,并自動(dòng)生成交互操作中間代碼,以便在需要時(shí)切換處理器狀態(tài)。鏈接器還可以在需要時(shí)自動(dòng)生成內(nèi)聯(lián)中間代碼或長(zhǎng)跳轉(zhuǎn)中間代碼,以擴(kuò)展跳轉(zhuǎn)指令的范圍。
鏈接器還可以生成關(guān)于鏈接文件的調(diào)試和引用信息、生成靜態(tài)調(diào)用圖并列出堆棧的使用情況、控制輸出映像中符號(hào)表的內(nèi)容、顯示輸出中代碼和數(shù)據(jù)的大小。鏈接器針對(duì)下一次文件編譯提供反饋信息,提示編譯器有關(guān)未使用函數(shù)的情況。可以根據(jù)提示在后續(xù)編譯中將未使用的函數(shù)放置在各自的節(jié)中,以便鏈接器將來刪除這些函數(shù)。
使用鏈接器構(gòu)建可執(zhí)行映像時(shí),鏈接器將解析輸入對(duì)象文件之間的符號(hào)引用,從庫(kù)中提取對(duì)象模塊來滿足還未滿足的符號(hào)引用的需要,根據(jù)屬性和名稱排序輸入節(jié),并將屬性和名稱相似的節(jié)合并為相鄰塊,刪除未使用節(jié),刪除重復(fù)的公共組和公共代碼、數(shù)據(jù)及調(diào)試節(jié),根據(jù)提供的分組和布局信息將對(duì)象片段組織為內(nèi)存區(qū),給可重定位值分配地址,最終生成可執(zhí)行映像。
責(zé)任編輯:haq
-
單片機(jī)
+關(guān)注
關(guān)注
6067文章
44969瀏覽量
649627 -
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7651瀏覽量
90616 -
編程
+關(guān)注
關(guān)注
88文章
3688瀏覽量
95119
原文標(biāo)題:?jiǎn)纹瑱C(jī)生成可執(zhí)行文件之鏈接
文章出處:【微信號(hào):CanaanTech,微信公眾號(hào):嘉楠科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
如何在Visual Studio 2022中運(yùn)行FX3吞吐量基準(zhǔn)測(cè)試工具?
PADS導(dǎo)出.318文件遺漏器件
創(chuàng)建OpenVINO? Python腳本,運(yùn)行可執(zhí)行文件時(shí)遇到的報(bào)錯(cuò)怎么解決?
labview打包可執(zhí)行文件后安裝出錯(cuò)
單片機(jī)編程語言有哪些選擇
C語言生成可執(zhí)行二進(jìn)制文件的具體過程

評(píng)論