<!-- * @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/)