就像用高階語言開發需要使用 Complier 一樣,用 x86 Assembly 開發需要用到 Assembler 和 Linker ,當然還有一個文字編輯器(或 IDE) 。
Assembler 是組譯器,負責把 Assembly Language 翻譯為 CPU 能處理的機器語言,放在目標檔案(.obj) 內。Linker 是鏈接器,負責將一個或多個目標檔案以及函式庫連結為一個可執行檔。
Windows 可用的 Assembler 有 MASM, NASM, FASM, GAS 等。
不同的 Assembler 有各自的 Directives(偽指令),但分別不大。Directives 是不會被翻譯為機器語言的,只是用來指示 Assembler 工作。
反而要特別注意不同 Assembler 可能會採用不同的語法(對初學者來說根本是不同的語言吧!)MASM, NASM, TASM, FASM 均採用 Intel Syntax 的 Assembly Language,而只有 GAS 是採用 AT&T Syntax 的 Assembly Language。
很多國外的 Assembly 玩家會覺得 AT&T Syntax 很醜,Intel Syntax 美多了,原因主要是 value assignment 中 source 同 destination 的順序(?)
例如,在高階語言中:
a = 5
換成在 Intel Syntax 的 Assembly 可能是:
mov eax, 5
而在 AT&T Syntax 的 Assembly 中卻是:
mov $5, %eax
筆者會選擇用 NASM,原因是 NASM 仍然在持續更新(據筆者聽說微軟已沒有對 MASM 作更新了)。
NASM 下載地址:
32-bit 主機用:
https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/win32/nasm-2.14.02-win32.zip
64-bit 主機用:
https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/win64/nasm-2.14.02-win64.zip
此為可携版,下載完解壓即可用,我們主要用目錄下的 nasm.exe。
為了可在 cmd 中隨時使用 NASM,筆者會添加 NASM 所在的目錄到 Environment Path。
在 Windows 10 下可以這樣添加:
右鍵螢幕左下角的 Windows Logo -> System -> System Info -> Advanced system settings -> Environment Variables -> Path -> Browse
完成後可在 cmd 中鍵入:
nasm.exe -v
應該會顯示 nasm 的版本, 代表設置成功。
而 Linker,在 Windows 下可選擇的有包含在微軟 Visual Studio 中的 link.exe 和 包含在 gcc 套件中的 ld.exe 等。
如果讀者不想安裝動輒過 GB 的 Microsoft Visual Studio,可以選擇下載筆者在 Visual Studio 2019 中抽取的 link.exe 和它需要的 Dll 和 Lib 檔案。如需使用 Windows API(像我們下面會用到的 WriteConsole 和 ExitProcess),必須用 link.exe 鏈結 Lib 檔案到我們的可執行檔,否則 link.exe 會報錯。
下載地址:
32-bit 主機用:
https://drive.google.com/file/d/1aslxz_Hf6t1_Kvm32h77n7hin6bOswar/view?usp=sharing
64-bit 主機用:
https://drive.google.com/file/d/1X5Mm3TnlEBoNoLjndvbTQdaQoLFhTCol/view?usp=sharing
請根據自己Windows的規格下載 Hostx86 或 Hostx64 壓縮檔,每個壓縮檔又各自包含 x86 和 x64 兩個文件夾,分別用來開發 x86 和 x64 的可執行檔。
為了可在 cmd 中隨時使用 link.exe ,筆者也添加 link.exe 所在的目錄到 Environment Path。
我們現在可以用 Notepad++ 之類的文本編輯器寫一個簡單的 .asm 檔案來測試一下。
然後在 cmd 中轉換到 .asm 的目錄下鍵入:
nasm -f Win32 test.asm
NASM 會生成一個 .obj 文件。接著用 linker 鏈接就可以生成 exe 了:
link test.obj /DYNAMICBASE "kernel32.lib" /LIBPATH:你的LIB文件路徑 /SUBSYSTEM:CONSOLE /ENTRY:main
鍵入:
test.exe
輸出:
Hello, World!