汇编语言笔记17-使用BIOS进行键盘输入和磁盘读写
轉載必須注明出處,違者必究。http://www.cnblogs.com/dennisOne
?使用BIOS進行鍵盤輸入和讀取鍵盤緩沖區
(1). BIOS鍵盤緩沖區是系統啟動后,BIOS用于存放int 9中斷例程所接受的鍵盤輸入的內存區。鍵盤緩沖區有16個字單元,可以存儲15個按鍵的掃描碼和對應的ASCII碼,高位字節是掃描碼,低位字節是字符碼。
(2). 狀態字節存放在0040:17單元。該字節記錄了控制鍵和切換鍵的狀態。
鍵盤輸入將引發9號中斷,BIOS提供了int 9中斷例程。CPU在9號中斷發生后,執行9號中斷例程,從60號端口讀出掃描碼,將其轉化為相應的ASCII碼或者狀態信息,存儲在內存的指定空間(鍵盤緩沖區或狀態字節)中。
示意圖:
簡述Shift_A:
(1). 按下左Shift鍵,引發鍵盤中斷;int 9中斷例程接受左Shift鍵的通碼,設置0040:17處的狀態字節的第1位為1,表示左Shift鍵按下。
(2). 按下A鍵,引發鍵盤中斷;CPU執行int 9中斷例程,從60h端口讀出A鍵的通碼;檢測狀態字節,看看是否有切換鍵按下,發現左Shift鍵被按下,則將A鍵的掃描碼1Eh和Shift_A對應的ASCII碼,即大"A"的ASCII碼41h,寫入鍵盤緩沖區。
(3). 松開左Shift鍵,引發鍵盤中斷;int 9中斷例程接受左Shift鍵的斷碼,設置0040:17處的狀態字節的第1位為0,表示左Shift鍵松開。
mov ah, 0
int 16h
結果: (ah)=掃描碼,(al)=ASCII碼。? ?
int 16h中斷例程檢測鍵盤緩沖區,發現緩沖區空,則循環等待,直到緩沖區中有數據。
? ?
?模擬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設置為存放字符的棧 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 ; 參數說明:(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 ; 設置 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進行磁盤的讀寫
磁盤的實際訪問由磁盤控制器進行,可以通過磁盤控制器訪問磁盤。扇區是磁盤讀寫的最小單位。
磁盤尋址: 面號(從0開始)->磁道號(從0開始)->扇區號(從1開始)
示例代碼: 讀取軟盤的0面0道1扇區的內容到0:200。
1 assume cs:code 2 3 code segment 4 start: 5 ; 入口參數設置 6 mov ax, 0 7 mov es, ax 8 mov bx, 200 ; 1. es:bx 指向接受從扇區讀入數據的內存區 9 10 mov al, 1 ; 2. (al)=需要讀取扇區的數 11 12 mov dl, 0 ; 3. (dl)=驅動器號 軟驅從0開始, 0:軟驅A,1:軟驅B 13 ; 硬盤從80h開始,80h:C盤,81h:D盤 14 mov dh, 0 ; 4. (dh)=磁頭號(對于軟盤即面號,一個面對應一個磁頭) 15 mov ch, 0 ; 5. (ch)=磁道號 16 mov cl, 1 ; 6. (cl)=扇區號 17 18 mov ah, 2 ; 7. (ah)=int 13h的功能號(2表示讀扇區) 19 int 13h 20 ; 返回參數: 21 ; 操作成功: (ah)=0, (al)=讀入的扇區數 22 ; 操作失敗: (ah)=出錯代碼 23 24 mov ax, 4c00h 25 int 21h 26 code ends 27 end start?
示例代碼:將0:200的內容寫入軟盤的0面0道1扇區。
assume cs:codecode segmentstart:; 入口參數設置mov ax, 0mov es, axmov bx, 200 ; 1. es:bx 指向寫入磁盤的數據mov al, 1 ; 2. (al)=需要寫入扇區數mov dl, 0 ; 3. (dl)=驅動器號 軟驅從0開始, 0:軟驅A,1:軟驅B; 硬盤從80h開始,80h:C盤,81h:D盤mov dh, 0 ; 4. (dh)=磁頭號(對于軟盤即面號,一個面對應一個磁頭)mov ch, 0 ; 5. (ch)=磁道號mov cl, 1 ; 6. (cl)=扇區號mov ah, 3 ; 7. (ah)=int 13h的功能號(3表示寫扇區)int 13h; 返回參數:; 操作成功: (ah)=0, (al)=寫入的扇區數; 操作失敗: (ah)=出錯代碼mov ax, 4c00hint 21hcode endsend start總結
以上是生活随笔為你收集整理的汇编语言笔记17-使用BIOS进行键盘输入和磁盘读写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 8086汇编学习笔记9-中断
- 下一篇: 汇编语言笔记14-端口