1. 程式人生 > 其它 >讀書筆記——組合語言 第四版 王爽著

讀書筆記——組合語言 第四版 王爽著

同步釋出於

http://mp.weixin.qq.com/s?__biz=Mzg5OTU1NDEyOA==&mid=2247483683&idx=1&sn=5b45dddcc8ddc5cb24c0b4e1be13cbd9&chksm=c050cf1cf727460a8f11d4d61b245fdbd8cfb5d2ddacc99813f92acd21ee9086afd79ae364e9#rd

獲取相關資源, 請在文章末尾掃描微信公眾號

            組合語言 第4版 王爽 著
                    (學習筆記)

第一章  基礎知識
  0.彙編指令是機器指令便於記憶的書寫格式
  
1.暫存器是CPU中儲存資料的器件 2.編譯器將彙編指令轉換為機器指令 3.彙編指令有對應的機器碼 4.偽指令由編譯器執行, 沒有對應的機器碼 5.符號由編譯器識別, 沒有對應的機器碼 6.儲存器被劃分為多個儲存單元, 儲存單元從零開始順序編號(地址) 7.一根根導線集合為匯流排, 分為地址, 控制, 資料匯流排 8.N根線可以說匯流排寬度為N 9.8088CPU資料匯流排寬度為8, 8086CPU資料匯流排寬度為16 10.CPU通過匯流排向介面卡傳送命令, 間接控制外設工作 11.CPU將系統中各類儲存器(一段地址空間)看作一個邏輯儲存器(記憶體地址空間)
12.地址0x0000~0x7FFF為主隨機儲存器的地址空間 13.地址0x8000~0x9FFF為視訊記憶體的地址空間 14.地址0xA000~0xFFFF為各個ROM的地址空間 第二章 暫存器 0.典型的CPU由運算器,控制器,暫存器構成依靠內部匯流排相連 1.通用暫存器[A~D]X可分為[A~D]H和[A~D]L兩個獨立的暫存器使用(Word = 0x02 * Byte) 2.在資料運算或傳輸時, 指令操作的兩個物件的位數應該一致 3.實體地址 = 基礎地址(段地址 * 0x10) + 偏移地址, 將地址連續起始地址為16的倍數的一組記憶體單元定義為段 4.一個X進位制的數左移0x01位=乘以X
5.在8086機中, 任意時刻CPU將cs:ip指向的內容當做指令執行 6.從cs:ip指向的記憶體讀取一條指令(送入指令緩衝器)後, ip中的值自動增加該指令的長度, 執行控制器執行該指令 7.mov指令被稱為傳送指令 8.能夠改變cs,ip內容的指令被統稱為轉移指令 9.8086CPU工作過程 a. 從cs:ip指向的記憶體單元讀取指令, 讀取的指令進入指令緩衝器 b. (IP) = (IP) + 讀取的指令長度, 指向下一條指令 c. 執行指令 d. 轉到a, 重複該過程 10.DEBUG指令(常用) A: 以彙編指令的格式在記憶體中寫入一條機器指令(A 段地址:偏移地址) D: 檢視記憶體(D 段地址:起始偏移地址 [結束偏移地址]) E: 向記憶體中寫入機器碼(E 段地址:偏移地址 資料 [資料 [...]]) G: 程式直接執行到指定地址位置(G 偏移地址) R: 檢視, 改變暫存器(R 暫存器) T: 執行一條機器指令 U: 檢視記憶體指令翻譯的彙編指令(U 段地址:偏移地址) P: 當遇到 int 21H 正常結束指令時使用P指令 當遇到 loop 指令時, Debug會自動重複執行迴圈中的指令直到(CX)=0x00為止 第三章 暫存器(記憶體訪問) 0.存放一個字型資料(0x10 Bit)的記憶體單元為字單元 1.8086CPU自動取ds的資料作為[addr]記憶體單元的段地址 2.8086CPU不支援將資料直接送入段暫存器 3.8086CPU的記憶體傳送指令push(入棧)和pop(出棧)操作都是以字為單位進行的 4.任意時刻ss:sp指向棧頂元素 5.push(入棧)執行步驟(棧頂從高地址向低地址方向移動) a. (SP) = (SP) - 0x02, ss:sp指向當前棧頂前面的單元作為新的棧頂 b. 將記憶體資料送入ss:sp指向的記憶體單元, 此時ss:sp指向新棧頂 6.棧空ss:sp指向棧空間最高地址單元的後一個單元(棧最底部的字單元的偏移地址 + 0x02) 7.pop(出棧)執行步驟(棧頂從低地址向高地址方向移動) a. 將SS:SP指向的記憶體單元處的資料讀出(已不在棧中) b. (SP) = (SP) + 0x02, ss:sp指向當前棧頂後面的單元, 以當前棧頂後面的單元為新的棧頂 8.棧操作要注意防止越界 9.Debug的T命令在執行修改暫存器ss的指令時, 下一條指令也緊接著被執行 第四章 第一個程式 0.偽指令 段(segment/ends)成對使用的偽指令 格式: 段名 segment ;段開始 段名 ends ;段結束 例子: msCode segment msCode ends 1.偽指令 假設(assume)將段暫存器和某一具體的段相聯絡 格式: assume 暫存器:段名 例子: assume cs:msCode 2.偽指令 程式結束(end)與程式入口 格式: end [enter-flag] 例子: end sMain 3.程式返回指令(Debug按 P 命令執行正常結束) mov ax, 4c00H int 21H 4.Debug將程式載入入記憶體(=sa:0)區後, cx中存放程式的長度 5.記憶體區前0x100個位元組為程式段字首(PSP)頭位元組為{0xCD 0x20} 6.ds(=sa:0)中存放程式所在記憶體區(含PSP)的段地址 7.則程式的地址為(CS) = (DS + 10H):(0) 第五章 [BX]和loop指令 0.約定符號()表示一個暫存器或記憶體單元的內容, 符號idata表示常量 1.在組合語言中, 標號代表一個地址 2.loop指令 格式: loop 標號 功能: a. (CX) = (CX) - 0x01 b. 判斷(CX)值 {=0x00 向下執行}, {!=0x00 轉至loop標號處執行} 3.在組合語言中, 以字母開頭的資料要在前面補0 如:ABCDH => 0ABCDH 4.在彙編源程式中指令 {[idata]} 被編譯器當做指令 {idata} 處理 5.在[]中用暫存器, 段地址預設在DS中 6.目前對於兩個運算物件(8位, 16位)的型別不匹配, 結果可能越界的解決方法 用一個16位暫存器將其高8位置0, 用其低8位做中介 7.用於顯示指明記憶體單元的段地址成為段字首 第六章 包含多個段的程式 0.合法的通過作業系統取得的空間都是安全的 1.偽指令dw(Define Word)定義字型資料(雙位元組) 例子: dw 0123H, 3456H [,...] 2.可執行檔案中的描述資訊主要是編譯連結程式對源程式中的偽指令進行處理得到的 3.若dw定義的資料處於程式碼段的最開始, 則偏移地址是0x00, 段地址是cs 4.段名相當於一個標號(數值), 代表段地址 5.8086CPU不支援將資料直接送入段暫存器(溫故) 6.偽指令db(Define Byte)定義位元組資料(單位元組) 例子: db 01H, 23H [,...] db '...' ;字串 7.段資料所佔空間為10H倍數, 不足空間補零 第七章 更靈活的定位記憶體地址的方法 0.轉大寫字母 {and al, 0DFH}(11011111B), 轉小寫字母 {or al, 020H}(00100000B) 1.定址方式[bx + idata]表現形式(ds為段地址) a. mov ax, [bx + 200] b. mov ax, [200 + bx] c. mov ax, 200[bx] d. mov ax, [bx].200 2.暫存器di,si功能同BX相近, 但他們不能分成兩個8位暫存器來使用 3.定址方式[bx + si/di]表現形式 a. mov ax, [si/di] b. mov ax, [si/di + 200] c. mov ax, [bx][si/di] d. mov ax, [bx + si/di] 4.定址方式[bx + si/di + idata]表現形式 a. mov ax, [bx + 200 + si/di] b. mov ax, [200 + bx + si/di] c. mov ax, 200[bx][si/di] d. mov ax, [bx].200[si/di] e. mov ax, [bx][si/di].200 5.在需要暫存資料時, 應該使用棧(暫存器太少) 第八章 資料處理的連個基本問題 0.在機器指令中必須明確或隱含說明處理的資料及其長度 1.在8086CPU中,只有bx, si, di, bp暫存器可以用在'[...]'的定址方式中 a. [bx/bp/si/di] b. [bx + si/di] c. [bp + si/di] 2.只要在'[...]'中使用bp, 而指令中沒有明確的給出段地址, 則段地址預設在ss中 3.指令執行前, 要處理的資料所在位置 a. mov bx, [0] => 記憶體, ds:0單元 b. mov bx, ax => CPU內部, ax暫存器 c. mov bx, 1 => CPU內部, 指令緩衝器(立即數) 4.在沒有暫存器參與的記憶體單元訪問指令中用 'word/byte ptr' 指明訪問記憶體單元的長度 a. add word ptr ds:[0], 10H b. inc byte ptr [bx], 02H 5.表示式 '被除數 ÷ 除數 = 商 ··· 餘數' 的彙編對映 a. AX(word) (byte) AL AH b. DX(word)+AX(word) (word) AX DX 高16位 低16位 格式: div 除數(暫存器/記憶體單元) 例子: div bl div word ptr es:[0] 技巧: 對摺看, 摺疊點除數 6.偽指令dd(Define Double-Word)定義雙字型資料(四位元組) 例子: dd 01234567H, 89abcdefH [,...] 7.偽指令dup來進行資料重複定義 格式: db/dw/dd 重複次數 dup (重複的資料集合) 例子: dw 2 dup (1234H, 5678H) => dw 1234H, 5678H, 1234H, 5678H 第九章 轉移指令的原理 0.操作符 offset 取得標號的偏移地址 例子: mov ax, offset sMain 1.可以修改IP, 或同時修改cs和ip的指令統稱為轉移指令 a. 段內轉移, 只修改ip(短轉移/近轉移) 例子: jmp ax b. 段間轉移, 同時修改cs和ip 例子: jmp far ptr 標號 2.8086CPU的轉移指令分為 a. 無條件轉移指令 b. 條件轉移指令 c. 迴圈指令 d. 中斷 e. 過程 3.jmp指令的位移計算是補碼方式(符號位不變, 取反加一) 4.nop指令的機器碼佔一個位元組 5.jmp指令要給出兩種資訊 a.轉移的距離(段內短轉移, 段內近轉移, 段間轉移) b.轉移的目的地址 6.無條件轉移指令 jmp 轉移指令結束後, cs:ip指向標號處的指令(編譯器根據標號計算IP的轉移的位移) a.段內短轉移(byte) 格式: jmp short 標號 功能: (IP) = (IP) + 8位位移(= 標號處的地址 - jmp指令後的第一個位元組的地址) b.段內近轉移(word) 格式: jmp near ptr 標號 功能: (IP) = (IP) + 16位位移(= 標號處的地址 - jmp指令後的第一個位元組的地址) 格式: jmp 暫存器(16位) 功能: (IP) = (暫存器的值, 是轉移的目的偏移地址) 格式: jmp word ptr 記憶體單元地址處一個字 功能: (IP) = (記憶體單元地址處一個字的值, 是轉移的目的偏移地址) c.段間轉移(遠轉移) 格式: jmp far ptr 標號 功能: (CS) = 標號所在段的段地址, (IP) = 標號所在段的偏移地址 格式: jmp dword ptr 記憶體單元地址處兩個字 功能: (CS) = 高地址處的一個字的值, (IP) = 低地址處的一個字的值 7.所有的(有條件轉移, 迴圈)指令都是短轉移(機器碼中包含轉移的位移, 不是目的地址) 格式: jcxz 標號 功能: if(0x00 == (CX)) jmp short 標號 格式: loop 標號 功能: a. (CX) = (CX) - 0x01 b. if(0x00 != (CX)) jmp short 標號 8.dec指令的功能和inc指令相反 例子: dec bx 功能: (BX) = (BX) - 0x01 第十章 CALL和RET指令 0.複習jmp指令 1.近轉移指令ret(用棧中的資料修改ip) 格式: ret 功能: pop ip 2.遠轉移指令retf(用棧中的資料修改cs和ip) 格式: retf 功能: a. pop ip b. pop cs 3.轉移指令call(將ip/cs:ip入棧, 然後轉移) a.段內轉移(= 標號處的地址 - call指令後的第一個位元組的地址)(匹配ret) 格式: call 標號 功能: a. push ip b. jmp near ptr 標號 b.段間轉移((CS) = 標號所在段的段地址, (IP) = 標號所在段的偏移地址)(匹配retf) 格式: call far ptr 標號 功能: a. push cs b. push ip c. jmp far ptr 標號 c.段內轉移(暫存器的值, 是轉移的目的偏移地址)(匹配ret) 格式: call 暫存器(16bit) 功能: a. push ip b. jmp 暫存器(16位) d.段內轉移(記憶體單元地址處一個字的值, 是轉移的目的偏移地址)(匹配ret) 格式: call word ptr 記憶體單元地址 功能: a. push ip b. jmp word ptr 記憶體單元地址處一個字 e.段間轉移((CS) = 高地址處的一個字的值, (IP) = 低地址處的一個字的值)(匹配retf) 格式: call dword ptr 記憶體單元地址 功能: a. push cs b. push ip c. jmp dword ptr 記憶體單元地址處兩個字 4.表示式 '因子 x 因子 = 積' 的彙編對映 a. (byte) AL(byte) AX(word) b. (word) AX(word) DX(word)+AX(word) 高16位 低16位 格式: mul 因子(暫存器/記憶體單元) 例子: mul byte ptr es:[0] mul word ptr es:[0] 5.用div指令做除法時, 如果結果超出了暫存器所能儲存的範圍, CPU將引發稱為除法溢位的內部錯誤 6. X / N = int(H / N) * 10000H + [rem(H / N) * 10000H + L] / N X:被除數[0, FFFFFFFF] N:除數[0, FFFF] H:X高16位[0, FFFF] L:X低16位[0, FFFF] int():取商 rem():取餘 第十一章 標誌暫存器 0.大多數傳送指令的執行對標誌暫存器沒有影響 1.標誌暫存器的作用 a.用來儲存相關指令的某些執行結果 b.用來為CPU執行相關指令提供行為依據 c.用來控制CPU的相關工作方式 2.標誌暫存器的結構 索引 -> 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01 00 標誌 -> OF DF IF TF SF ZF AF PF CF 假=0 -> NV UP DI PL NZ NA PO NC 真=1 -> OV DN EI NG ZR AC PE CY 詞彙 -> NV(Not Overflow) UP(Up) DI(Disable Interrupt) PL(Positive) -> OV(Overflow) DN(Down) EI(Enable Interrupt) NG(Negative) -> NZ(Not Zero) NA(No Auxiliary Carry) PO(Parity Odd) NC(No Carry) -> ZR(Zero) AC(Auxiliary Carry) PE(Parity Even) CY(Carry) 3.標誌暫存器的行為 ZF(Zero-Flag)記錄相關指令執行後其結果是否為0x00 PF(Parity-Flag)記錄相關指令執行後其結果的所有Bit位中的1的個數是否為偶數 SF(Sign-Flag)記錄相關指令執行後其結果是否為負值 CF(Carry-Flag)記錄相關指令執行後其結果的最高有效位是否向更高位進位/借位 OF(Overflow-Flag)記錄相關指令執行後其結果是否發生了溢位(值超出範圍) DF(Direction-Flag)方向標誌位, 在串處理指令中, 控制每次操作後SI, DI的增減方式 4.標誌暫存器的意義 SF標誌是在將資料當作有符號來運算時通過其值得知結果的正負, 在將資料當作無符號來運算時雖然結果影響其值但忽略其意義(對暫存器值而言) CF標誌對無符號數運算有意義(邏輯值對暫存器值而言) OF標誌對有符號數運算有意義(邏輯值對暫存器值而言) 5.adc指令是帶進位加法指令 格式: adc 操作物件1, 操作物件2 功能: (操作物件1) = (操作物件1) + (操作物件2) + (CF) 例子: adc ax, bx 功能: (AX) = (AX) + (BX) + (CF) 6.sbb指令是帶進位減法指令 格式: sbb 操作物件1, 操作物件2 功能: (操作物件1) = (操作物件1) - (操作物件2) - (CF) 例子: sbb ax, bx 功能: (AX) = (AX) - (BX) - (CF) 7.cmp指令比較指令, 功能相當於減法, 只是不儲存結果, 暫存在CPU內部的暫存器中 格式: cmp 操作物件1, 操作物件2 功能: 計算 (操作物件1) - (操作物件2), 根據結果對標誌暫存器進行設定 例子: cmp ax, bx 功能: 計算 (AX) - (BX), 結果影響標誌暫存器的相關各位值 8.cmp指令進行無符號數比較結果 if((AX) == (BX)) { ZF=1 } if((AX) != (BX)) { ZF=0 } if((AX) < (BX)) { CF=1 } if((AX) =< (BX)) { CF=1 || ZF=1 } if((AX) > (BX)) { CF=0 && ZF=0 } if((AX) >= (BX)) { CF=0 } 9.cmp指令進行有符號數比較結果 if((AX) == (BX)) { ZF=1 } if((AX) != (BX)) { ZF=0 } if((AX) < (BX)) {(SF=1 && OF=0) || (SF=0 && OF=1)} if((AX) <= (BX)) { } if((AX) > (BX)) { SF=1 && OF=1 } if((AX) >= (BX)) { SF=0 && OF=0 } 10.所有條件轉移指令的轉移位移都是[-128, 127] 11.根據無符號數的比較結果進行轉移的條件轉移指令 格式 -> 指令 標號 指令 -> je jne jb jnb ja jna 含義 -> == != < >= > <= 標誌 -> ZF=1 ZF=0 CF=1 CF=0 CF=0 && ZF=0 CF=1 || ZF=1 詞彙 -> j(Jump) -> a(Above) na(Not Above) -> b(Below) nb(Not Below) -> e(Equal) ne(Not Equal) 12.movsb串傳送指令 格式: movsb 功能: a. mov es:[di], byte ptr ds:[si] b. if(0x00 == (DF)) inc si inc di c. if(0x01 == (DF)) dec si dec di 13.movsw串傳送指令 格式: movsw 功能: a. mov es:[di], word ptr ds:[si] b. if(0x00 == (DF)) add si, 02H add di, 02H c. if(0x01 == (DF)) sub si, 02H sub di, 02H 14.rep指令根據(CX)值重複執行後面的串傳送指令 格式: rep movsb/movsw 功能: s:movsb/movsw loop s 15.cld指令將(DF)標誌位值置0 格式: cld 功能: (DF)=0 16.std指令將(DF)標誌位值置1 格式: std 功能: (DF)=1 17.pushf指令將標誌暫存器的值壓棧 格式: pushf 18.popf指令從棧中彈出資料送入標誌暫存器中 格式: popf 第十二章 內中斷 0.中斷是指CPU不再接著剛執行完的指令向下執行, 而是轉去處理中斷資訊 1.中斷資訊是CPU在執行完當前的指令後, 檢測到從外部或內部產生的並立即進行處理的特殊資訊 2.中斷資訊的產生 a.除法錯誤, 型別碼 0 b.單步執行, 型別碼 1 c.執行into指令, 型別碼 4 d.執行int指令, 型別碼 指令中的立即數 3.中斷向量是中斷處理程式的入口地址 4.中斷向量表是中斷處理程式的入口地址列表 5.對於8086CPU中斷向量表指定存放在記憶體0000:0000~0000:03FF的1024個單元中, 0000:0200~0000:02FF對應的中斷向量表一般是空的 6.在中斷向量表中, 一個表項存放一箇中斷向量即一箇中斷處理程式的入口地址 7.一個表項佔兩個字, 低地址字存放偏移地址, 高地址字存放段地址 8.中斷過程(由硬體自動執行) a.取得中斷型別碼N b.pushf c.(TF)=0, (IF)=0 d.push cs e.push ip f.(IP)=(N * 04H), (CS)=(N * 04H + 02H) 9.編寫中斷處理程式常規步驟 a.儲存用到的暫存器 b.處理中斷 c.恢復用到的暫存器 e.用iret指令返回 10.iret指令通常和硬體自動完成的中斷過程配合使用 格式: iret 功能: a. pop ip b. pop cs c. popf 11.CPU執行完一條指令後, 如果(TF)=1則產生單步中斷, 所以在進入中斷處理程式前設定(TF)=0, 避免在處理中斷程式時發生單步中斷 12.在執行完向ss暫存器傳送資料指令後, 即使發生中斷, CPU也不會響應, 保證ss:sp指向正確的棧頂 第十三章 int指令 0.int指令由中斷型別碼引發中斷過程 格式: int n 1.CPU執行int n指令引發一個n號中斷的中斷過程 a.取中斷型別碼N b.標誌暫存器入棧 c.(TF)=0, (IF)=0 d.push cs e.push ip f.(IP)=(N * 04H), (CS)=(N * 04H + 02H) 2.中斷處理程式簡稱中斷例程 3.在系統板的ROM中存放著稱為BIOS(基本輸入輸出系統)的程式, 主要包含 a.硬體系統的檢測和初始化程式 b.外部中斷和內部中斷的中斷例程 c.用於對硬體裝置進行I/O操作的中斷例程 d.其他和硬體系統相關的中斷例程 4.BIOS和DOS提供的中斷例程安裝到記憶體的過程 a.CPU加電初始化cs:ip=FFFF:0, 此處有一條跳轉指令, CPU執行該指令後轉去執行BIOS中的硬體系統檢測和初始化程式 b.初始化程式將BIOS提供的中斷例程的入口地址登記在中斷向量表中, 中斷例程是固化在ROM中的 c.硬體系統檢測和初始化完成後, 呼叫int 19H進行作業系統的引導, 將計算機交給作業系統控制 d.DOS啟動後, 除完成其他工作外, 還將它提供的中斷例程裝入記憶體, 建立相應的中斷向量 5.int 21H是DOS提供的中斷例程, 返回功能mov ax 4c00H是4cH號子程式00H返回值 6.設定游標位置功能例子 mov ah, 02H ;int 10H功能2號子程式 mov bh, 00H ;螢幕頁號[0, 7] mov dh, 05H ;螢幕行號[0, 24] mov dl, 0CH ;螢幕列號[0, 79] int 10H 7.在游標位置顯示字元功能例子 mov ah, 09H ;int 10H功能9號子程式 mov al, 'a' ;顯示的字元 mov bl, 07H ;顯示的字元的屬性 mov bh, 00H ;螢幕頁號[0, 7] mov cx, 03H ;重複顯示字元的數量 int 10H 8.在游標位置顯示字串功能例子 mov ds, 00H mov dx, 00H ;ds:dx指向以'$'結尾要顯示的字串 mov ah, 09H ;int 21H功能9號子程式 int 21H 第十四章 埠 0.CPU在操控各種儲存器時把它們總體看作一個由若干儲存單元組成的邏輯儲存器(記憶體地址空間) 1.和CPU通過匯流排相連的晶片除了各種儲存器還有 a.各種介面卡上的介面晶片, 它們控制介面卡工作 b.主機板上的介面晶片, CPU通過它們對部分外設進行訪問 c.其他晶片, 用來儲存相關的系統資訊, 或進行相關的輸入輸出處理 2.這些晶片都有一組可以由CPU讀寫的暫存器, 在物理上可能處於不同的晶片中, 但以下相同 a.都和CPU的匯流排相連, 通過它們所在的晶片連線 b.CPU對它們的讀寫都通過控制線向它們所在的晶片發出埠讀寫命令 3.從CPU的角度, 將這些暫存器都當作埠, 對它們進行統一編址, 建立統一的埠地址空間, 每個埠在地址空間上都有一個地址 4.CPU可以直接讀寫資料的地方 a.CPU內部的暫存器 b.記憶體單元 c.埠 5.CPU通過埠地址來定位埠, 通過地址匯流排來傳送, 埠地址範圍0~65535 6.in指令從埠讀取資料 格式: in al/ax, 埠 例子: in al, 20H 7.out指令向埠寫入資料 格式: out 埠, al/ax 例子: out dx, al/ax 8.在in和out指令中, 只能用al或ax來存放讀取或寫入埠的資料, 訪問8位埠用al, 訪問16位埠用ax 9.對256~65535埠進行讀寫時用dx存放埠號 10.CMOS RAM晶片有兩個不同的埠, 70H為地址埠, 71H為資料埠 11.shl邏輯左移指令 格式: shl 暫存器/記憶體單元, cl 功能: a. 將暫存器或記憶體單元中的資料向左位移 b. 將最後移出的一Bit位寫入cf中 c. 最低位用0補充 d. 相當於執行X = X * 02H 12.shr邏輯右移指令 格式: shr 暫存器/記憶體單元, cl 功能: a. 將暫存器或記憶體單元中的資料向右位移 b. 將最後移出的一Bit位寫入cf中 c. 最高位用0補充 d. 相當於執行X = X / 02H 13.邏輯位移指令的移動位數大於1時, 必須將移動位數放於cl中 14.BCD碼是用4位二進位制數表示一位十進位制數的編碼方法 第十五章 外中斷 0.CPU除了有運算能力外, 還有I/O(Input/Output)能力 1.外設的輸入不直接送入記憶體和CPU, 而是送入相關的介面晶片的埠中 2.CPU向外設的輸出也不直接送入外設, 而是先送入埠中, 再由相關的晶片送到外設 3.外中斷源分為可遮蔽中斷和不可遮蔽中斷 4.可遮蔽中斷是CPU可以不響應的外中斷, 當CPU檢測到可遮蔽中斷資訊時, 如果(IF)=1則CPU執行完當前指令後響應中斷引發中斷過程, 如果(IF)=0則不響應可遮蔽中斷 5.可遮蔽中斷引發的中斷過程和內中斷的中斷過程相同, 只是中斷型別碼是通過資料匯流排送入CPU的, 而內中斷的中斷型別碼是在CPU內部產生的 6.cli指令將(IF)標誌位值置0 格式: cli 功能: (IF)=0 7.sti指令將(IF)標誌位值置1 格式: sti 功能: (IF)=1 8.不可遮蔽中斷是CPU必須響應的外中斷, 當CPU檢測到不可遮蔽中斷資訊時, 則在執行完當前指令後立即響應引發中斷過程 9.對於8086PC不可遮蔽中斷的中斷型別碼固定為2, 則不可遮蔽中斷的中斷過程是 a.標誌暫存器入棧 b.(TF)=0, (IF)=0 c.push cs d.push ip e.(IP)=(2 * 04H), (CS)=(2 * 04H + 02H) 10.鍵盤上的晶片對每個按鍵的開關狀態產生一個掃描碼送入主機板上相關的介面晶片的60H埠地址的暫存器中 11.按下一個鍵產生的掃描碼為通碼, 鬆開一個鍵產生的掃描碼為斷碼, 掃描碼長度為一個位元組, 斷碼 = 通碼 + 80H 12.鍵盤的輸入到達60H埠時, 相關的晶片就會向CPU發出中斷型別碼為9的可遮蔽中斷資訊 13.BIOS提供了int9中斷例程, 用來進行基本的鍵盤輸入處理 a.讀取60H埠中的掃描碼 b.如果是字元鍵的掃描碼, 將該掃描碼和對應的ASCII碼送入記憶體中的BIOS鍵盤緩衝區 c.如果是控制鍵和切換鍵的掃描碼, 則將其轉變為狀態位元組(用二進位制位記錄控制鍵和切換鍵狀態的位元組)寫入記憶體中儲存狀態位元組的單元 d.對鍵盤系統進行相關的控制 14.BIOS鍵盤緩衝區是系統啟動後, BIOS用於存放int9中斷例程所接收的鍵盤輸入的記憶體區, 一個鍵盤輸入用一個字單元存放, 高位位元組存放掃描碼, 低位位元組存放字元碼 15.0040:17單元儲存鍵盤狀態位元組, 各位記錄的資訊 a. 0:右Shift狀態, 置1表示按下右Shift鍵 b. 1:左Shift狀態, 置1表示按下左Shift鍵 c. 2:Ctrl狀態, 置1表示按下Ctrl鍵 h. 3:Alt狀態, 置1表示按下Alt鍵 d. 4:ScrollLock狀態, 置1表示Scroll燈亮 e. 5:NumLock狀態, 置1表示小鍵盤輸入的是數字 f. 6:CapsLock狀態, 置1表示輸入大寫字母 g. 7:Insert狀態, 置1表示處於刪除態 16.鍵盤輸入的處理過程 a.鍵盤產生掃描碼 b.掃描碼送入60H埠 c.引發9號中斷 d.CPU執行int9中斷例程處理鍵盤輸入 17.讀出鍵盤的輸入 in al, 60H 第十六章 直接定址表 0.在標號後面有':'號時, 標號描述記憶體地址, 此標號只能在程式碼段中使用 1.在標號後面沒有':'號時, 標號同時描述記憶體地址和單元長度(位元組, 字, 雙字), 此標號代表一個段中的記憶體單元, 稱為資料標號 2.如果在程式碼段中直接用資料標號訪問資料, 則需要用偽指令assume將標號所在的段和一個段暫存器聯絡起來 3.可以將資料標號當作資料來定義, 此時編譯器將資料標號所表示的地址值當作資料的值 例子: data segment a db ... b dw ... c dw a, b data ends 功能: data segment a db ... b dw ... c dw offset a, offset b data ends 4.seg操作符為取得某一標號的段地址 例子: data segment a db ... b dw ... c dd a, b data ends 功能: data segment a db ... b dw ... c dw offset a, seg a, offset b, seg b data ends 5.直接定址表是通過資料直接計算出要找的元素的位置的表 第十七章 使用BIOS進修鍵盤輸入和磁碟讀寫 0.鍵盤輸入將引發9號中斷, CPU在9號中斷髮生後執行int 9H中斷例程, 從60H埠讀出掃描碼, 將其轉化為相應的ASCII碼或狀態資訊, 儲存在鍵盤緩衝區或狀態字中 1.鍵盤緩衝區有16個字單元是環形佇列結構管理的記憶體, 高位元組儲存掃描碼, 低位元組儲存ASCII碼 2.BIOS提供了int 16H的0號功能從鍵盤緩衝區讀取一個鍵盤輸入, 並將其從緩衝區中刪除 功能: a.檢測鍵盤緩衝區中是否有資料 b.沒有則繼續第一步 c.讀取緩衝區第一個字單元的鍵盤輸入 d.將讀取的掃描碼送入ah, ASCII碼送入al e.將已讀取的鍵盤輸入從緩衝區中刪除 例子: mov ah, 00H int 16H 結果: (AH)=掃描碼, (AL)=ASCII碼 3.3.5英寸的軟盤: a. 分為上下兩面(磁頭), 面號從0開始 b. 每面有80個磁軌, 磁軌號從0開始 c. 每個磁軌有18個扇區, 扇區號從1開始 d. 每個扇區有512個位元組 4.BIOS提供訪問磁碟的int 13H中斷例程 引數: ah=功能號02H讀扇區, 03H寫扇區 al=讀寫的扇區數 cl=扇區號(01H~12H) ch=磁軌號(00H~4FH) dh=面號(00H~01H)(磁頭) dl=驅動器號(00H:軟碟機A, 01H:軟碟機B, 80H:硬碟C, 81H:硬碟D) es:bx=指向讀取或寫入的資料記憶體區 結果: 返回成功(ah)=00H, (al)=讀入的扇區數 返回失敗(ah)=錯誤碼 綜合研究 0.在TC 2.0下C語言中main函式地址為0x01FA 1.C語言將函式實現為組合語言中的子程式 2.C 語言: *(char*)0x2000 = 'a'; 偽彙編: mov byte ptr ds:[2000H], 'a' 3.C 語言: *(int*)0x2000 = 'a'; 偽彙編: mov word ptr ds:[2000H], 'a' 4.C 語言: *(char far*)0x20001000 = 'a'; 偽彙編: mov es, 2000H mov es:[1000H], 'a' 5.xor指令異或運算, 同0異1 格式: xor 操作物件1, 操作物件2 例子: xor (AX=1), (BX=0) 功能: (AX) = (AX) 例子: xor (AX=0), (BX=1) 功能: (AX) = (BX) 附註 0.ret n指令將棧頂指標修改為呼叫前的值, n為呼叫子程式前壓入棧中的引數數量*02H 1.詳情看書吧 歡迎關注 iF8s 微信公共號

課程設計2部分效果圖