<!--
* @Author: error: git config user.name && git config user.email & please set dead value or install git
* @Date: 2022-11-10 20:28:59
* @LastEditors: error: git config user.name && git config user.email & please set dead value or install git
* @LastEditTime: 2022-11-11 21:27:11
* @FilePath: \筆記本\8086\8086.md
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
# 組合語言考試筆記
## 8086的結構
8086的結構如下圖所示
![arch](https://cdn.discordapp.com/attachments/868759966431973416/1040246498077724802/image.png)
![arch2](https://github.com/gurugio/book_assembly_8086/raw/master/assets/model.gif)
## 暫存器(Registers)
暫存器位於中央處理器(CPU)內部,用來暫存指令、位址或是一些數據。
總共14個暫存器:
- 通用暫存器:AX、BX、CX、DX
- 指標索引暫存器:SP、BP、IP、SI、DI
- 區段暫存器:CS、DS、ES、SS
- 旗標暫存器:Flag
![reg](https://ithelp.ithome.com.tw/upload/images/20181019/20106865Z5ttfAA2A7.jpg)
### 通用暫存器
- `AX`:可用來做加減乘除運算、邏輯運算、字串運算,或是I/O處理。
- `BX`:可用來進行資料運算,或是加強索引及定址功能。可以直接當作記憶體位址的基底運算元。
- `CX`:可用來進行資料運算、存放迴圈次數、字串處理的重複次數、資料位移或是旋轉的次數。
- `DX`:可用來進行資料運算、乘除運算,或是拿來存放I/O的位址。
### 指標索引暫存器
- `SP` : 永遠指向堆疊頂端的最新資料儲存位址。當堆疊資料有進(PUSH)出(PUP)時,SP的位址也會隨之加減更動。
- `BP` : 可以指向堆疊的任何位置,也能用來做間接定址、運輸和運算。
- `IP` : 用來指向指令的所在位置,一旦CPU執行完IP所指的指令後,IP便會再指向到下一個指令,讓CPU去讀取執行。負責掌管CPU執行程式的流程。
- `SI` : 作為資料來源的記憶區索引。
- `DI` : 作為資料目的地的記憶區索引。
### 區段暫存器
- `CS` : 用來存放程式指令的位址。若配合IP(CS:IP)使用,可以得到指令存放的實際位址。
- `DS` : 用來存放及設定資料的位址。若配合SI(DS:SI)使用,可以得到資料存放的實際位址。
- `EX` : 若DS資料太多(超過64 Kbytes)時,可以使用ES來存放資料。若要進行字串運算,必須配合DI來使用。
- `SS` : 用來存放堆疊的位址。若配合SP(SS:SP)使用,可以得到堆疊頂端的實際位置。
### 旗標暫存器
- `CF(Carry Flag)` 進位旗標 : 在加減運算後,當最高位元(MSB)有進位或借位時,CF=1;否則CF=0。
```txt
EX1 : 10001011(2) + 01011001(2) = 01100100(2) => CF=0 因為最高位元沒有進位
EX2 : 10110011(2) + 10101100(2) = 101011111(2) => CF=1 因為最高位元有進位
```
- `PF(Parity Flag)` 奇偶(同位元)旗標 : 用來判斷指令在算術或邏輯運算後之結果值二進制數最低8個位元的1數量。若有奇數個1,則PF=0;偶數個1則PF=1。
```txt
EX1 : 10001011(2) + 01011001(2) = 011100100(2),因為有偶數個1,因此PF=1。
EX2 : 10110011(2) + 10101000(2) = 101011011(2),因為有奇數個1,因此PF=0。
```
- `AF(Auxiliary Carry Flag)` 輔助進位旗標 : 在算術或邏輯運算後,若第3位元(從0算起)產生進位或是借位,則AF=1;否則AF=0。
```txt
EX1 : 10001011(2) + 01011001(2) = 011100100(2),發生進位,因此AF=1。
EX2 : 10110011(2) + 10101000(2) = 101011011(2),沒發生進位,因此AF=1。
```
- `ZF(Zero Flag)` 零旗標 : 在算術或邏輯運算後,若結果為0,則ZF=1;否則ZF=0。
```txt
EX1 : 10001011(2) + 01011001(2) = 11100100(2),結果值不為零,因此ZF=0。
EX2 : 11111111(2) + 00000001(2) = 100000000(2),結果值為零(但有進位),因此ZF=1。
```
- `OF(Overflow Flag)` 溢位旗標 : 在算術運算後,當結果發生溢位時,則OF=1;否則OF=0。判斷溢位最簡單的方法就是看他是否由正轉負或是負轉正,且只有正加正或是負加負才會有溢位的可能。
```txt
EX1 : 11001011(2) + 01011001(2) = 100100100(2),雖有進位,但負加正不可能發生溢位,因此OF=0。
EX2 : 10111111(2) + 10000001(2) = 101000000(2),負加負變為正,發生溢位,因此OF=1。
```
- `SF(Sign Flag)` 符號旗標 : 在算術或邏輯運算後,若結果為負數,則SF=1;否則SF=0。
```txt
EX:
無號數:
0D5+0CC=CF+0A1 // 產生進位,所以CF=1
213+204=417
有號數:
0D5+0CC=0A1 // 負數,所以SF=1
(-43)+(-52)=(-95)
CF = 1 and SF = 1
```
- `DF(Direction Flag)` 方向旗標 : 主要用於字串運算,若DF=0,做字串運算時,CPU會由低位址的字串處理到高位址字串;若DF=1,則反之。
## 匯流排(BUS)
用來連接CPU與記憶體、輸入輸出裝置的傳輸路徑。
- 16條資料線(Data Lines):負責資料傳送於五大單元之間,是雙向傳輸的匯流排,一般而言,資料匯流排線有幾位元可以決定一台電腦是幾位電腦,也就是說,電腦的資料匯流排如有32條,則稱此電腦為32位元的電腦,這是因為資料匯流排的傳輸位元數與CPU一次能處理的位元數通常是相等的。Data bus寬度=MDR寬度.
- 20條地址線(Address Lines):
每條排線代表0或1 bit,與控制訊號配合負責傳送位址,為一種CPU對記憶體單向輸出的排線,位址匯流排可決定主記憶體的最大記憶體容量,例如︰如果位址匯流排有N條排線(N位元),則主記憶體最大可定址到2^N^個記憶體位址,因為記憶體位址可存放一個位元組(Byte),所以最大可有2^N^ Bytes的記憶體空間,如果有一台電腦的位址匯流排有32條線,則其記憶體的定址空間最大為2^32^bytes,也就是4GB。也就是32條位址線2^32^ Bytes=2^28^ Words 亦即Address bus寬度28 bit=PC=MAR寬度.
- 控制匯流排 : 負責傳送CPU執行指令時所發出之控制訊號,為一種CPU對其他單元單向輸出的排線,由控制單元傳送控制訊號給其他單元。
## 指令集
- 七大功能
- 資料轉移指令
- 算術指令
- 位元處理指令
- 控制轉移指令
- 字串指令
- 中斷指令
- 處理器控制指令
## 定址法
- 暫存器定址法
- 用暫存器的位址當作指令的位址,指令的位址由暫存器的位址決定。
```asm
EX:
MOV AX,BX
```
- 立即定址法
- 把資料放在指令中,不需要去讀取記憶體中的資料。
```txt
EX:
MOV AX,111b
```
- 直接定址法
- 直接給定資料的記憶體實際位址(物理位置),直接讀取記憶體中的資料。
```asm
EX:
MOV AX,[001H]
```
- 間接定址法
- 指令的運算元欄內的值為有效位址的位址值,故需做二次的記憶體讀取,以取得所需之資料。(有點類似C++指標)
```txt
EX:
MOV AX,[BX]
```
- 基底定址法
- 使用基底暫存器(BX)加上位址偏移量(Offset)的方式來定址。
```txt
EX:
MOV AX,[BX+0D5H]
```
- 索引定址法
- 索引定址法是以固定的地址加上索引暫存器(SI,DI)的值,來得出位置。(通常用於陣列)
```txt
EX:
MOV AX,[0000H+SI]
```
- 基底索引定址法
- 基底索引定址法是以基底暫存器(BX)加上索引暫存器(SI,DI)的值,來得出位置。(通常用於2維陣列)
```txt
EX:
MOV AX,[BX+SI+2]
```
## 習題
***
Q : `40.請試著上網搜尋「基底索引定址法」,並簡述其在資料結構上的用途。`</br>
A : 基底索引定址法是以基底暫存器(BX)加上索引暫存器(SI,DI)的值,來得出位置。(通常用於2維陣列)
***
Q : `2.8086 處理機為 (a) 8 位元 (b) 16 位元 (c) 32 位元 (d) 64 位元 (e) 以上皆非 處理機`</br>
A : (b) 16 位元
***
Q : `3.8086處理機有 (a) 2 (b) 4 (c) 6 (d) 8 (e) 以上皆非 個區段暫存器。`</br>
A : (b) 4
***
Q : `4.8086處理機的任一區段為(a)64K位元組(b)4K位元組(c)1M位元組(d)1G位元組(e)以上皆非 處理權。`</br>
A : (a) 64K位元組</br>
ref : [Features of 8086 Microprocessor](https://www.davuniversity.org/images/files/study-material/Intel%208086.pdf)
***
Q : `5.若採2的補數表示有符號的整數,則16位元所能表達的數值範圍為?`</br>
A : -32768 ~ 32767
***
Q : `6.在暫存器、主記憶體、快取記憶體、與磁碟4種記憶中,何者存取速度最快?`</br>
A : 暫存器
***
Q : `7.數值12345的MSD為何? (a)1 (b)2 (c)3 (d)4 (e)5 (f)無 `</br>
A : (a)
***
Q : `8.MOV [SI],AX 屬於合種定址法?(a)暫存器定址法(b)基底定址法(c)直接定址法(d)立即定址法(e)以上皆非`</br>
A : (b) 基底定址法
//幹你娘我不知道
***
Q : `9.MOV [89],AX 屬於合理定址法?(a)暫存器定址法(b)基底定址法(c)直接定址法(d)立即定址法(e)以上皆非`</br>
A : (c) 直接定址法
***
Q : `10.MOV AH,[0H] 關於何種定址法?`</br>
A : 直接定址法
***
Q : `11.MOV AH,[BP]屬於合種定址法?`</br>
A : 間接定址法
***
Q : `12.MOV AH,0BH 屬於合種定址法?`</br>
A : 立即定址法
***
不確定</br>
Q : `13.若已知CS=4H, DS=5H, SS=6H, SP=7H, IP=8H,試計算即將執行指令的實際位址。`</br>
A : 4H:8H (CS:IP)
***
不確定</br>
Q : `14.若已知CS=4H, DS=5H, SS=6H, SP=7H, IP=8H,試計算堆疊頂端的實際位址。`</br>
A : 6H:7H (SS:SP)
***
Q : `15.JAVA C, Assembly, Python, 與Basic等,那一種程程式語言其原始程式和機器的相關性最高?`</br>
A : Assembly
***
Q : `16.一般而言,JAVA, C, Assembly, Python, 與Basic等,用那一種程程式語言撰寫的程式執行的速度最快?`</br>
A : Assembly
***
Q : `17.X86組合語言的註解符號為何?(a) : (b) ; (c) // (d) \ (e) # (f) ? (g) 以上皆非`</br>
A : (b) ;
***
Q : `18.若已知AX的內容為1234,BX的內容為5678,則執行 MOV BX,AX指令之後,AX與BX的內容為何?`</br>
A : AX=1234, BX=1234
***
Q : `19.下列那一些指令與 XOR AX,AX 功能等價?(a) OR AX,0 (b) AND AX,0 (c) NOT AX (d) INC AX (e) MOV AX,0 (f) 以上皆非`</br>
A : (b) AND AX,0 (e) MOV AX,0
***
Q : `20.如果乘數存放於CX暫存器,執行IMUL 指令之後,則乘積存放於何處?`</br>
A : DX:CX
![REF](https://media.discordapp.net/attachments/991673355231039549/1041932973060149318/image.png)
***
我不確定</br>
Q : `21.使用IDIV 指令時,若除數為DL,則被除數應存放在那個暫存器中?`</br>
A : AX
***
Q : `22.若暂存器AH與AL内容分別為1FH與3FH,則執行AND AH AL之後,AH內容為何?`</br>
A : 1FH
***
Q : `23.若暫存器AH與AL內容分別為1FH與3FH,則執行OR AHAL之後,AH內容為何?`</br>
A : 3FH
***
Q : `24.若暫存器AH與AL內容分別為1FH與3FH,則執行TEST AH,AL之後,AH內容為何?`</br>
A : 1FH or `0001 1111b`</br>
ref : [What does the `TEST` instruction do](https://reverseengineering.stackexchange.com/questions/15184/what-does-the-test-instruction-do)
***
Q : `25.若暫存器AH與AL內容分別為1FH與3FH,則執行NEG AH之後,AH內容為何?`</br>
A : `1110 0001b`</br>
ref : [The NEG Instruction](http://www.c-jump.com/CIS77/ASM/Flags/F77_0130_neg_instruction.htm)
***
Q : `26.BCD碼用多少位元来表示一個十進位數字?(a)1(b)2(c)3 (d) 4 (e) 8 (f) 16 (g) 以上皆非`</br>
A : (d) 4
***
Q : `27.虛擬指令END之功用為何?`</br>
A : 指示原始程式的結束處
***
Q : `28.將十進位數值301轉換成六進位。`</br>
A : 1221(6) = 216 + 21 + 1 = 301(10)
***
Q : `29.將八進位數值123.45轉換成二進位。`</br>
A : 1010011.100101
***
Q : `30.簡述虛擬指令DB的作用為何?`</br>
A : 定義一個位元組的資料
ref : [DB](https://jbwyatt.com/253/emu/asm_tutorial_03.html)
***
Q : `31.間述OF旗標的功能為何?`</br>
A : 溢位旗標,用來檢查算術運算的結果是否超出範圍
***
Q : `32.任寫一條指令,該指令執行之後會設定ZF旗標。`</br>
A : `TEST AX,0b`
***
Q : `33.任寫一條指令,該指令執行之後不會影響任何旗標。`</br>
A : `NOP`
## 連結推薦
[8086 instruction](http://www.gabrielececchetti.it/Teaching/CalcolatoriElettronici/Docs/i8086_instruction_set.pdf)
[8086 Flag](https://www.geeksforgeeks.org/flag-register-8086-microprocessor/)
[8086 REG](https://www.geeksforgeeks.org/general-purpose-registers-8086-microprocessor/)