
上次我們提到了匯編語言的兩種格式,Intel 和 AT&T 格式,今天講的是對應兩種編譯器的一些使用。
我們知道,編譯器就是一個將一種程序語言翻譯成另外一種語言的程序。編譯的過程其實共有5個流程:詞法分析、語法分析、語義分析和中間代碼生成、優化、目標代碼生成。具體是怎么實現的,有興趣的話,可以找一本好的《編譯原理》書看一看,順便自己也嘗試寫一個編譯器。
對于匯編語言呢,不同平臺不同格式都有各自不同的編譯器,也有一些可以跨平臺的編譯器。那么上次我們提到的Intel 格式和AT&T格式匯編使用的編譯器是什么呢?
Linux 中編譯Intel 格式使用 Nasm, 編譯AT&T格式使用Gas。
下面以Hello World程序做個示范,為了區分格式,我們將Intel格式的匯編代碼文件后綴名寫為.asm,而AT&T的寫為.s.
Intel:
$> nasm -f elf hello.asm
或者
$> nasm -f elf64 hello.asm
上面的兩條命令都會生成一個hello.o目標文件,下面的那條命令可以對上兼容。elf64相當于說是說明64位機器,elf是32位。看我們的代碼可以知道,如果寄存器中使用的rax之類的,那么一定是64位的。當然,這個問題都不大,不管使用那一條命令,其實都能通過。
生成.o文件之后,我們就需要用鏈接器(linker)將目標文件鏈接起來,生成可執行文件
$> ld -m elf_i386 -o hello hello.o $> ld -o hello hello.o $> ld -o -m elf_x86_64 -o hello hello.o
上面的第1條鏈接命令對應前面的第一條編譯命令,第2,3條是等價的,對應前面第二條編譯命令。之前也說了,這是一個對應機器位數的問題。如果混用,會出現不匹配問題,看圖說話。


情況就是這么個情況,不要問為什么。這就跟找對象一樣,合適是很重要了。
AT&T
使用Gas編譯AT&T格式匯編。Gas 是GNU中自帶的,如果是Linux系統的話,基本上都自帶了,不需要再安裝。
Gas編譯起來沒有那么多花樣
$> as -o hello.o hello.s
$> ld -o hello helle.o
通也是生成了可執行文件hello
測試一下

關于編譯和鏈接的一些參數,可以通過使用 --help 參數來查看,一般來說掌握幾個基本參數即可。
到目前來說呢,基本的概念和幾個工具都已經簡單講完了,后面將會開始正式的開始我們的匯編語言學習。為了好看吧,將會以Intel格式來講解,期待一波吧。