汇编语言笔记17-使用BIOS进行键盘输入和磁盘读写
轉(zhuǎn)載必須注明出處,違者必究。http://www.cnblogs.com/dennisOne
?使用BIOS進(jìn)行鍵盤輸入和讀取鍵盤緩沖區(qū)
(1). BIOS鍵盤緩沖區(qū)是系統(tǒng)啟動后,BIOS用于存放int 9中斷例程所接受的鍵盤輸入的內(nèi)存區(qū)。鍵盤緩沖區(qū)有16個字單元,可以存儲15個按鍵的掃描碼和對應(yīng)的ASCII碼,高位字節(jié)是掃描碼,低位字節(jié)是字符碼。
(2). 狀態(tài)字節(jié)存放在0040:17單元。該字節(jié)記錄了控制鍵和切換鍵的狀態(tài)。
鍵盤輸入將引發(fā)9號中斷,BIOS提供了int 9中斷例程。CPU在9號中斷發(fā)生后,執(zhí)行9號中斷例程,從60號端口讀出掃描碼,將其轉(zhuǎn)化為相應(yīng)的ASCII碼或者狀態(tài)信息,存儲在內(nèi)存的指定空間(鍵盤緩沖區(qū)或狀態(tài)字節(jié))中。
示意圖:
簡述Shift_A:
(1). 按下左Shift鍵,引發(fā)鍵盤中斷;int 9中斷例程接受左Shift鍵的通碼,設(shè)置0040:17處的狀態(tài)字節(jié)的第1位為1,表示左Shift鍵按下。
(2). 按下A鍵,引發(fā)鍵盤中斷;CPU執(zhí)行int 9中斷例程,從60h端口讀出A鍵的通碼;檢測狀態(tài)字節(jié),看看是否有切換鍵按下,發(fā)現(xiàn)左Shift鍵被按下,則將A鍵的掃描碼1Eh和Shift_A對應(yīng)的ASCII碼,即大"A"的ASCII碼41h,寫入鍵盤緩沖區(qū)。
(3). 松開左Shift鍵,引發(fā)鍵盤中斷;int 9中斷例程接受左Shift鍵的斷碼,設(shè)置0040:17處的狀態(tài)字節(jié)的第1位為0,表示左Shift鍵松開。
mov ah, 0
int 16h
結(jié)果: (ah)=掃描碼,(al)=ASCII碼。? ?
int 16h中斷例程檢測鍵盤緩沖區(qū),發(fā)現(xiàn)緩沖區(qū)空,則循環(huán)等待,直到緩沖區(qū)中有數(shù)據(jù)。
? ?
?模擬dos的字符串輸入程序
完整代碼:
1 assume cs:code, ds:data 2 3 data segment 4 dw 100 dup (0) ; 模擬讀取字符的棧 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov si, 0 12 ; 將ds:si設(shè)置為存放字符的棧 13 call getstr 14 return: 15 mov ax, 4c00h 16 int 21h 17 18 ; 完整的接受字符串輸入的子程序 19 getstr: 20 push ax 21 22 getstrs: 23 mov ah, 0 24 int 16h 25 cmp al, 20h 26 jb nochar ; ASCII碼小于20h, 說明不是字符 27 28 ; 字符的處理分為兩步,1:入棧,2:顯示棧中的字符 29 mov ah, 0 ; 1: 字符入棧 30 call charstack 31 mov ah, 2 ; 2: 顯示棧中的字符 32 call charstack 33 jmp getstrs 34 35 nochar: 36 cmp ah, 0eh ; 退格鍵的掃描碼 37 je backspace 38 cmp ah, 1ch ; Enter鍵的掃描碼 39 je enters 40 jmp getstrs ; 其他控制鍵忽略 41 42 backspace: 43 mov ah, 1 44 call charstack ; 字符出棧 45 mov ah, 2 46 call charstack ; 字符顯示 47 jmp getstrs 48 49 enters: 50 mov al, 0 51 mov ah, 0 52 call charstack ; 0入棧 53 mov ah, 2 54 call charstack ; 顯示棧中的字符串 55 56 pop ax 57 ret 58 59 60 ; 子程序: 字符棧的入棧、出棧和顯示 61 ; 參數(shù)說明:(ah)=功能號,0表示入棧,1表示出棧,2表示顯示 62 ; ds:si指向字符棧的空間 63 ; 對于0號功能:(al)=入棧字符; 64 ; 對于1號功能: (al)=返回的字符; 65 ; 對于2號功能:(dh)、(dl)=字符串在屏幕上顯示的行、列位置。 66 67 charstack: jmp short charstart 68 table dw charpush, charpop, charshow 69 top dw 0 ; 棧頂 70 71 charstart: 72 push bx 73 push dx 74 push di 75 push es 76 77 cmp ah, 2 78 ja sret 79 mov bl, ah 80 mov bh, 0 81 add bx, bx 82 jmp word ptr table[bx] 83 84 charpush: 85 mov bx, top 86 mov [si][bx], al 87 inc top 88 jmp sret 89 90 charpop: 91 cmp top, 0 92 je sret 93 dec top 94 mov bx, top 95 mov al, [si][bx] 96 jmp sret 97 98 charshow: ;(dh)、(dl)=字符串在屏幕上顯示的行、列位置。 99 cmp bx, 0b800h 100 mov es, bx 101 mov al, 160 102 mov ah, 0 103 mul dh 104 mov di, ax 105 add dl, dl 106 mov dh, 0 107 add di, dx ; 設(shè)置 es:di 108 109 mov bx, 0 110 charshows: cmp bx, top 111 jne noempty 112 mov byte ptr es:[di], ' ' 113 jmp sret 114 noempty: 115 mov al, [si][bx] 116 mov es:[di], al 117 mov byte ptr es:[di+2], ' ' 118 inc bx 119 add di, 2 120 jmp charshows 121 sret: 122 pop es 123 pop di 124 pop dx 125 pop bx 126 ret 127 128 code ends 129 130 end start?
?使用BIOS進(jìn)行磁盤的讀寫
磁盤的實際訪問由磁盤控制器進(jìn)行,可以通過磁盤控制器訪問磁盤。扇區(qū)是磁盤讀寫的最小單位。
磁盤尋址: 面號(從0開始)->磁道號(從0開始)->扇區(qū)號(從1開始)
示例代碼: 讀取軟盤的0面0道1扇區(qū)的內(nèi)容到0:200。
1 assume cs:code 2 3 code segment 4 start: 5 ; 入口參數(shù)設(shè)置 6 mov ax, 0 7 mov es, ax 8 mov bx, 200 ; 1. es:bx 指向接受從扇區(qū)讀入數(shù)據(jù)的內(nèi)存區(qū) 9 10 mov al, 1 ; 2. (al)=需要讀取扇區(qū)的數(shù) 11 12 mov dl, 0 ; 3. (dl)=驅(qū)動器號 軟驅(qū)從0開始, 0:軟驅(qū)A,1:軟驅(qū)B 13 ; 硬盤從80h開始,80h:C盤,81h:D盤 14 mov dh, 0 ; 4. (dh)=磁頭號(對于軟盤即面號,一個面對應(yīng)一個磁頭) 15 mov ch, 0 ; 5. (ch)=磁道號 16 mov cl, 1 ; 6. (cl)=扇區(qū)號 17 18 mov ah, 2 ; 7. (ah)=int 13h的功能號(2表示讀扇區(qū)) 19 int 13h 20 ; 返回參數(shù): 21 ; 操作成功: (ah)=0, (al)=讀入的扇區(qū)數(shù) 22 ; 操作失敗: (ah)=出錯代碼 23 24 mov ax, 4c00h 25 int 21h 26 code ends 27 end start?
示例代碼:將0:200的內(nèi)容寫入軟盤的0面0道1扇區(qū)。
assume cs:codecode segmentstart:; 入口參數(shù)設(shè)置mov ax, 0mov es, axmov bx, 200 ; 1. es:bx 指向?qū)懭氪疟P的數(shù)據(jù)mov al, 1 ; 2. (al)=需要寫入扇區(qū)數(shù)mov dl, 0 ; 3. (dl)=驅(qū)動器號 軟驅(qū)從0開始, 0:軟驅(qū)A,1:軟驅(qū)B; 硬盤從80h開始,80h:C盤,81h:D盤mov dh, 0 ; 4. (dh)=磁頭號(對于軟盤即面號,一個面對應(yīng)一個磁頭)mov ch, 0 ; 5. (ch)=磁道號mov cl, 1 ; 6. (cl)=扇區(qū)號mov ah, 3 ; 7. (ah)=int 13h的功能號(3表示寫扇區(qū))int 13h; 返回參數(shù):; 操作成功: (ah)=0, (al)=寫入的扇區(qū)數(shù); 操作失敗: (ah)=出錯代碼mov ax, 4c00hint 21hcode endsend start總結(jié)
以上是生活随笔為你收集整理的汇编语言笔记17-使用BIOS进行键盘输入和磁盘读写的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 8086汇编学习笔记9-中断
- 下一篇: 汇编语言笔记14-端口