從零開始學會 Assembly Language
組合語言是最接近硬體的程式語言之一。透過它,你可以更理解 CPU、記憶體、暫存器、指令執行流程, 也能打下作業系統、編譯器、逆向工程與嵌入式開發的重要基礎。
6 大章節
完整入門路線
3 個範例
實用程式示範
5 題測驗
即時互動檢驗
; NASM x86 範例:將 5 + 3 的結果存入 eax
section .text
global _start
_start:
mov eax, 5
add eax, 3
; 結束程式
mov ebx, 0
mov eax, 1
int 0x80
Assembly Language 是什麼?
先理解組合語言的定位,再開始學語法會更容易。
接近硬體
組合語言幾乎是一對一對應機器指令,能直接操作 CPU 暫存器、記憶體位址與中斷。
效能與控制力高
能精準控制程式執行流程,常用於驅動程式、作業系統核心、嵌入式系統與效能關鍵區塊。
學習門檻較高
因為沒有高階語言那麼多抽象化,必須理解 CPU 架構、暫存器、資料表示法與記憶體模型。
你會學到什麼?
第 1 步:基本語法
了解 section、label、mov、add、sub 等常見語法。
第 2 步:暫存器與記憶體
學會使用 eax、ebx、ecx、edx 等暫存器,以及位址存取。
第 3 步:流程控制
使用 cmp、jmp、je、jne 建立條件判斷與迴圈。
第 4 步:應用練習
透過字串輸出、加總運算、迴圈範例,把概念實際串起來。
語法教學
本教學採用 x86 NASM 常見寫法,先掌握基本骨架。
1. 程式結構
常見的組合語言程式會分成資料區與程式區:
section .data ; 已初始化資料
section .bss ; 未初始化資料
section .text ; 程式碼區
global _start
_start:
; 程式從這裡開始執行
.data 放字串與常數,.bss 放未初始化變數,.text 放指令。
2. 註解與標籤
註解使用分號 ;,標籤(Label)代表可跳躍的位置。
; 這是一行註解
start_loop:
inc eax
cmp eax, 10
jne start_loop
jmp、je、jne 搭配,建立迴圈與分支流程。
3. 資料宣告
常見宣告型態如下:
db:定義 1 byte(位元組)dw:定義 2 bytesdd:定義 4 bytesdq:定義 8 bytes
section .data
msg db "Hello", 0
num dw 100
value dd 123456
4. 常見資料表示
你可以用十進位、十六進位或字元表示資料:
mov eax, 10 ; 十進位
mov ebx, 0x1F ; 十六進位
mov ecx, 'A' ; 字元 A 的 ASCII 值
由於組合語言貼近硬體,理解數值表示非常重要。
暫存器與記憶體觀念
暫存器是 CPU 內部的小型高速儲存空間,組合語言大量使用它們。
| 暫存器 | 用途 | 常見說明 |
|---|---|---|
EAX |
累加器 | 常用於運算結果、系統呼叫編號 |
EBX |
基底暫存器 | 常用於儲存資料或系統呼叫參數 |
ECX |
計數器 | 常見於迴圈、重複操作次數 |
EDX |
資料暫存器 | 常與 EAX 搭配,或作為系統呼叫參數 |
ESP |
Stack Pointer | 指向堆疊頂端 |
EBP |
Base Pointer | 常用於函式呼叫框架 |
ESI / EDI |
索引暫存器 | 常用於字串與陣列處理 |
直接值與位址
以下兩種寫法意義不同:
mov eax, 5 ; 把數值 5 放入 eax
mov eax, [num] ; 讀取記憶體 num 的內容到 eax
[ ] 表示「存取記憶體位置中的資料」。
堆疊 Stack
堆疊遵循「後進先出」(LIFO)原則,常用於儲存返回位址、區域變數與暫存資料。
push eax ; 將 eax 壓入堆疊
pop ebx ; 從堆疊取出資料到 ebx
呼叫函式時,堆疊的使用尤其重要。
常用指令總整理
先掌握這些基本指令,就能寫出許多入門程式。
| 指令 | 功能 | 範例 |
|---|---|---|
mov |
資料搬移 | mov eax, 10 |
add |
加法 | add eax, 5 |
sub |
減法 | sub eax, 2 |
inc |
加一 | inc ecx |
dec |
減一 | dec ecx |
cmp |
比較 | cmp eax, ebx |
jmp |
無條件跳躍 | jmp loop |
je |
相等時跳躍 | je equal_label |
jne |
不相等時跳躍 | jne retry |
push / pop |
堆疊操作 | push eax / pop eax |
call / ret |
函式呼叫與返回 | call func |
條件跳躍範例
mov eax, 10
mov ebx, 10
cmp eax, ebx
je equal_label
mov ecx, 0
jmp end_program
equal_label:
mov ecx, 1
end_program:
當 eax 與 ebx 相等時,程式會跳到 equal_label。
迴圈範例
mov ecx, 5
loop_start:
; 這裡可放入重複執行的程式
dec ecx
cmp ecx, 0
jne loop_start
這段程式會重複執行直到 ecx 變成 0。
範例應用例子
透過實際程式碼,理解組合語言如何運作。
範例 1:基本加法運算
將 15 與 27 相加,結果存入 eax。
section .text
global _start
_start:
mov eax, 15
add eax, 27
; 結束程式
mov ebx, 0
mov eax, 1
int 0x80
mov eax, 15 先把 15 放進 eax,
add eax, 27 再把 27 加進去,因此 eax 最後為 42。
範例 2:輸出 Hello, World!(Linux x86 / int 0x80)
這是經典入門範例,展示如何呼叫系統服務輸出字串。
section .data
msg db "Hello, World!", 10
len equ $ - msg
section .text
global _start
_start:
mov eax, 4 ; sys_write
mov ebx, 1 ; stdout
mov ecx, msg ; 字串位址
mov edx, len ; 字串長度
int 0x80
mov eax, 1 ; sys_exit
mov ebx, 0
int 0x80
int 0x80。
eax 放系統呼叫編號,ebx、ecx、edx 放參數。
範例 3:1 到 5 的總和
利用迴圈把 1+2+3+4+5 算出來。
section .text
global _start
_start:
mov eax, 0 ; sum = 0
mov ecx, 1 ; i = 1
sum_loop:
add eax, ecx
inc ecx
cmp ecx, 6
jne sum_loop
; 結束程式
mov ebx, 0
mov eax, 1
int 0x80
eax 會等於 15。
學習建議
- 先熟悉資料搬移與加減法。
- 再理解比較、跳躍與迴圈。
- 接著學堆疊、函式呼叫與記憶體位址。
- 最後再延伸到系統呼叫、檔案操作與中斷。
常見初學錯誤
- 把記憶體值與位址混淆,例如忘記使用
[ ]。 - 不知道某個系統呼叫需要哪些參數暫存器。
- 比較完之後不了解旗標(Flags)如何影響跳躍。
- 堆疊 push / pop 次數不對稱,造成錯誤。
小測驗
測試你是否掌握了基本組合語言概念。
延伸學習方向
位元運算 函式呼叫慣例 中斷與系統呼叫 記憶體配置 逆向工程 作業系統核心 x86-64 架構 NASM / MASM 語法差異如果你已經看懂這個教學網站,下一步可以繼續學習: 位元運算、旗標暫存器、函式堆疊框架、64 位元組合語言,以及與 C 語言互相呼叫的技巧。