文章也同時在個人博客 http://kimihe.com/更新
引言
本章介紹匯編語言程序的創(chuàng)建過程急鳄,我們要準備踏上創(chuàng)作匯編程序之路啦~
仍舊如之前所說的,越了解底層堰酿,就越能夠駕馭計算機疾宏。
摘要
- 所有的匯編過程都是處理文件的過程。
- 程序就是一個由非常小的步驟組成的漫長旅途触创,這些步驟是一個代表機器指令的二進制值的列表坎藐。
二進制文件 vs. 文本文件
- 機器上文件可以分為:文本文件(text file)和二進制文件(binary file)。
- 二進制文件可以使用Linux命令:
> xxd file
來查看,你需要直到打印出來的內容各字段的含義岩馍。如下輸出:
$ xxd aa
00000000: 610a 620a 630a 640a 650a 660a 670a 680a a.b.c.d.e.f.g.h.
00000010: 300a 310a 320a 330a 340a 350a 360a 370a 0.1.2.3.4.5.6.7.
00000020: 380a 390a
可以看到輸出有三列碉咆,最左側的00000000等數(shù)字代表偏移量抖单,它包含顯示那一行的第一個字節(jié)與文件開頭的第一個字節(jié)的偏移量藤树。中間的以字節(jié)為單位顯示16進制內容。最右側顯示可視化文本字符运翼,對于不可顯字符的二進制值采用句號字符表示双谆。
- 注意到其中夾雜的0AH块攒,這里它代表換行,對應鍵盤的enter(return)佃乘。值得一提的是在windows中囱井,這個按鍵會產生回車(0DH)+換行(0AH),而Linux中只有換行(0AH)∪け埽現(xiàn)在大多數(shù)計算機系統(tǒng)和軟件忽略回車庞呕,這是當年機械打字機的歷史遺留:當打字機一行打滿后,你必須把游標移到行首(回車0DH)程帕,并切到下一行(換行0AH)住练,這樣才能開始新一行的輸入。
- 在一個二進制可執(zhí)行文件中愁拭,位模式可能意味著完全不同的內容讲逛,這取決于它剛好位于文件中的位置,以及該文件中岭埠,它附近存在這哪些其他位模式盏混。
字節(jié)序
- 對于字節(jié)順序的解釋可以分為小端法(little endian)和大端法(big endian)。一旦使用不止一個字節(jié)來代表一個數(shù)字值惜论,字節(jié)的順序就變得至關重要许赃。
- 將多字節(jié)值的最低有效字節(jié)存儲到最低偏移位置的計算機體系結構稱為小端系統(tǒng)(little endian)。反之馆类,將多字節(jié)值的最高有效字節(jié)存儲到最低偏移位置的計算機體系結構稱為大端系統(tǒng)(big endian)混聊。
- 在大端系統(tǒng)中的數(shù)據(jù)以16進制顯示很容易,因為它們按照人們期待的順序出現(xiàn)乾巧,最重要(高位)的數(shù)在左邊句喜。而在小端系統(tǒng)中,一切都是顛倒的沟于。
- 字節(jié)排列順序的差異不僅適用于存儲在文件中的字節(jié)咳胃,而且也適用于存儲在內存中的字節(jié)。而最近的硬件體系結構都被設計為雙向字節(jié)社裆。
編譯器
- 匯編語言具有非常重要的特征拙绊,正是這一點向图,使它在眾多的編譯器中與眾不同泳秀,即:完全控制目標代碼标沪。
- CPU有很多機器指令,其中每一條都有一個對應的匯編語言助記符嗜傅。
- 助記符和它的操作數(shù)整合在一起稱為指令(instruction)金句。
目標代碼和連接器
- 現(xiàn)代匯編編譯器產生的目標代碼文件是一種源代碼和可執(zhí)行文件之間的中間步驟,這個中間步驟是一種叫作目標模塊(object module)的二進制文件吕嘀。
- 目標代碼文件本身并不能作為程序運行违寞,還需要一個額外的必要步驟,那就是連接(link)偶房。
- 目標代碼文件作為中間步驟的原因是:大的源代碼文件可以劃分成許多更小的源代碼文件趁曼,以保持文件大小和復雜性 的可管理性。
- 連接器不只是把目標代碼塊組合成一個單個的塊棕洋,它確保模塊以外的函數(shù)調用能夠到達目標對象模塊挡闰,并且確保所有此類內存引用實際上指向它們期望引用的地方。
重定位能力
- 與現(xiàn)代8086一同引入的Intel體系結構內部有了很大的改進掰盘,從而使程序無須被編譯為在特定的物理地址運行摄悯。可知行文件內部的所有引用都通過相對于該程序起始位置的偏移量來指定。
- 偏移量總是相同的愧捕,并且因為所有的引用都是相對于可知行程序文件的起始位置奢驯,所以在運行時,程序放在物理內存中的什么地方都沒有關系次绘。
- 上述特性叫作可重定位能力瘪阁。
感想
似乎是時候可以去親手挑選硬件,并組裝一臺機器了說邮偎。