跳轉到內容

x86 彙編/基本常見問題

來自 Wikibooks,開放世界中的開放書籍

此頁面將作為初學組合語言程式設計人員的基本常見問題解答。

計算機如何讀取/理解彙編程式碼?

[編輯 | 編輯原始碼]

計算機本身並不真正“讀取”或“理解”任何東西,因為它沒有意識或知覺,但這無關緊要。事實上,計算機無法讀取你編寫的組合語言。你的彙編器會將組合語言轉換為一種稱為“機器碼”的二進位制資訊形式,計算機使用它來執行其操作。如果你不彙編程式碼,它對於計算機來說就是完全的胡言亂語。

也就是說,彙編很重要,因為每個彙編指令通常只對應一個機器碼,而且“凡人”可以使用一張白紙、一支鉛筆和一本彙編指令參考書來直接完成這項任務。事實上,在計算機的早期,這是一項常見任務,甚至在某些情況下需要“手工彙編”機器指令來編寫一些基本的計算機程式。一個經典的例子是史蒂夫·沃茲尼亞克,他手工將整個 Integer BASIC 直譯器彙編成 6502 機器碼,用於他的最初的Apple I 計算機。然而,應該注意的是,這種為商業發行軟體所做的任務非常罕見,以至於僅憑這一點就值得特別提及。很少有程式設計師真正為超過幾個指令做過這樣的事,即使是那樣,也僅僅是課堂作業而已。

在 Windows/DOS/Linux 上是否相同?

[編輯 | 編輯原始碼]

這個問題的答案是肯定和否定。基本的 x86 機器碼只取決於處理器。Windows 和 Linux 的 x86 版本顯然是建立在 x86 機器碼之上的。在 Linux 和 Windows 中,x86 彙編程式設計之間存在一些差異。

  1. 在 Linux 計算機上,最流行的彙編器是 GAS 彙編器,它使用 AT&T 語法編寫程式碼,以及 Netwide Assembler,也稱為 NASM,它使用類似於 MASM 的語法。
  2. 在 Windows 計算機上,最流行的彙編器是 MASM,它使用 Intel 語法,但是,許多 Windows 使用者也使用 NASM。
  3. Windows 和 Linux 上可用的軟體中斷及其功能是不同的。
  4. Windows 和 Linux 上可用的程式碼庫是不同的。

使用相同的彙編器,在每個作業系統上編寫的基本彙編程式碼基本相同,只是你與 Windows 的互動方式不同於你與 Linux 的互動方式。

哪個彙編器最好?

[編輯 | 編輯原始碼]

簡而言之,沒有哪個彙編器比其他彙編器更好;這只是一個個人喜好問題。

長話短說,不同的彙編器有不同的功能、缺點等。如果你只知道 GAS 語法,那麼你可能想使用 GAS。如果你知道 Intel 語法並且在 Windows 機器上工作,你可能想使用 MASM。如果你不喜歡 MASM 和 GAS 的一些怪癖或複雜性,你可能想嘗試 FASM 或 NASM。我們將在第 2 節中討論不同彙編器之間的差異。

我需要學習彙編嗎?

[編輯 | 編輯原始碼]

對於大多數計算機任務,你不需要學習彙編,但它絕對有用。學習彙編不是學習一門新的程式語言。如果你要開始一個新的程式設計專案(除非該專案是引導載入程式、裝置驅動程式或核心),那麼你可能想避開組合語言,就像瘟疫一樣。一個例外是,如果你絕對需要從擁塞的內部迴圈中擠出最後一點效能,而你的編譯器正在生成次優程式碼。但是,請記住,過早最佳化是萬惡之源,儘管一些計算密集型即時任務只有在從一開始就理解和計劃最佳化技術的情況下才能獲得足夠的最佳化。

然而,學習彙編可以讓你對計算機內部的工作原理有特別的瞭解。當你在 C 或 Ada 等高階語言中程式設計時,你的所有程式碼最終都需要轉換為機器碼指令,以便你的計算機可以執行它們。理解處理器在最基本級別上能做些什麼的限制,也將有助於你使用高階語言進行程式設計。

我應該如何格式化我的程式碼?

[編輯 | 編輯原始碼]

大多數彙編器要求彙編程式碼指令每行顯示一條,並用回車符隔開。大多數彙編器還允許在指令、運算元等之間出現空格。你如何格式化程式碼完全取決於你,儘管有一些常用的方法。

一種方法是將所有內容對齊。

Label1:
mov ax, bx
add ax, bx
jmp Label3
Label2:
mov ax, cx
...

另一種方法是將所有標籤放在一列,將所有指令放在另一列。

Label1: mov ax, bx
        add ax, bx
        jmp Label3
Label2: mov ax, cx
...

另一種方法是將標籤放在它們自己的行上,並稍微縮排指令。

Label1:
   mov ax, bx
   add ax, bx
   jmp Label3
Label2:
   mov ax, cx
...

還有另一種方法是將標籤和指令分成不同的列,並且將標籤放在它們自己的行上。

Label1:
        mov ax, bx
        add ax, bx
        jmp Label3
Label2:
        mov ax, cx
...

因此有不同的方法可以做到,但有一些通用的規則是彙編程式設計師通常遵循的。

  1. 讓你的標籤一目瞭然,以便其他程式設計師可以清楚地看到它們。
  2. 更多結構(縮排)將使你的程式碼更易於閱讀。
  3. 使用註釋來解釋你在做什麼。一段彙編程式碼的含義往往並不立即明瞭。
華夏公益教科書