## 🧠 主題:堆疊(Stack)的概念與應用
適用:微處理機課程(組合語言基礎)
---
### 📘 一、什麼是堆疊(Stack)?
* 堆疊是一種**資料儲存方式**。
* 特性是「**後進先出**」(LIFO, Last In First Out)。
* 就像一疊書或盤子,**最後放上去的,最先拿出來**。
---
### 📚 二、生活化例子:疊書
* 想像你把書一本一本疊在桌上:
* 書A → 書B → 書C → 書D(最後放)
* 要拿書時,你只能從最上面的**書D**先拿。
---
### 🔧 三、組合語言中的堆疊操作(以8086為例)
| 指令 | 說明 |
| ------ | -------- |
| `PUSH` | 將資料壓入堆疊 |
| `POP` | 將資料從堆疊取出 |
📌 **堆疊是由高位址往低位址儲存資料。**
📌 **使用SP(Stack Pointer)作為堆疊指標。**
---
### ✍️ 四、程式範例
```cpp=
MOV AX, 1234h ; 將數值1234放入AX
PUSH AX ; 將AX的值壓入堆疊
MOV AX, 0000h ; 清除AX
POP AX ; 將堆疊的值取回AX
```
🗯️ 說明:這段程式將AX的內容存進堆疊,再取回,就像「暫時寄放書本後又拿回來」。
---
### 🧩 五、堆疊的應用
* \*\*副程式呼叫(CALL)\*\*時儲存返回位址。
* 儲存**暫時資料與暫存器值**(例如中斷處理)。
* 實作遞迴函數。
* 協助實作表達式求值、括號配對等演算法。
---
### 📌 記憶口訣
> **堆疊 Stack → 後進先出 LIFO → 最後放的最先出**
---
需要我幫你整理成PPT格式或圖解堆疊在記憶體中的運作嗎?
## 🎯 更多堆疊應用與範例(8086組合語言)
---
### ✅ 範例 1:交換兩個變數的值(使用堆疊)
```assembly
MOV AX, 1111h ; AX = A
MOV BX, 2222h ; BX = B
PUSH AX ; 將A值存入堆疊
PUSH BX ; 將B值存入堆疊
POP AX ; 先取出B → AX
POP BX ; 再取出A → BX
```
📌 結果:AX = B、BX = A → 成功交換值
🧠 概念:利用堆疊「後進先出」的特性來調換順序。
---
### ✅ 範例 2:副程式呼叫儲存返回位址(CALL/RET 搭配堆疊)
```assembly
CALL MySub ; 呼叫副程式,返回位址自動存入堆疊
MySub:
MOV AX, 9999h
RET ; 從堆疊取出返回位址並跳回主程式
```
📌 說明:`CALL` 自動把返回地址 PUSH 到堆疊,`RET` 自動 POP 回來 → 回到主程式。
---
### ✅ 範例 3:儲存與恢復暫存器值(中斷或臨時用途)
```assembly
PUSH AX ; 保存AX內容
MOV AX, 0000h ; 改變AX的內容
; ... 做其他事 ...
POP AX ; 還原原本的AX內容
```
📌 說明:像暫時借用一張便條紙記下東西,做完再還原。
---
### ✅ 範例 4:多層副程式呼叫(堆疊儲存多層返回位址)
```assembly
CALL A
A: CALL B
RET
B: CALL C
RET
C: MOV AX, 1
RET
```
📌 說明:每次 `CALL` 都會把回去的位置壓入堆疊,`RET` 時會一層一層回去。
🧠 概念:像是「巢狀任務」,堆疊幫你記得怎麼回家。
---
### ✅ 範例 5:計算簡單算式(模擬運算順序)
若有表達式:`(5 + 3) * 2`
你可以這樣使用堆疊模擬運算步驟:
```assembly
MOV AX, 5
PUSH AX ; 放入5
MOV AX, 3
PUSH AX ; 放入3
POP BX ; 取出3
POP AX ; 取出5
ADD AX, BX ; AX = 5 + 3 = 8
PUSH AX ; 結果再放回堆疊
MOV AX, 2
PUSH AX ; 放入2
POP BX ; 取出2
POP AX ; 取出8
MUL BX ; AX = 8 * 2 = 16
```
📌 說明:一步一步用堆疊暫存中間運算結果。
---
### ✅ 小挑戰練習題(給學生)
1. 用堆疊交換 CX 與 DX 的值。
2. 寫一段組合語言,用堆疊儲存三個數字,並逆序取出。
3. 試著模擬兩層副程式呼叫(CALL A → CALL B),畫出堆疊變化。
---
需要我幫你這些內容整理成圖解或PPT檔案嗎?或者畫出堆疊記憶體變化圖?