我們通過討論鍵盤輸入和磁碟讀寫來理解cpu對i/o的控制。
鍵盤輸入會引發9號中斷,cpu會執行中斷例程,從60h埠讀出掃瞄碼,然後將其轉換為對應的ascii碼資訊,將掃瞄碼和對應的ascii碼存入記憶體中的指定空間中,這個空間一般是鍵盤緩衝區,鍵盤緩衝區是乙個環形佇列。
如果我們按下a鍵就會引發鍵盤中斷,cpu執行int9中斷例程,從60h埠讀出a鍵的通碼,然後檢測狀態位元組,將a的掃瞄碼1eh和對應的ascii碼61h寫入鍵盤緩衝區中:
接下來按下b、c、d、e後,緩衝區的內容如下,每個字單元的高位位元組儲存掃瞄碼,低位位元組儲存ascii碼:
然後我們按下左shift鍵,此時int9接受到左shift的通碼,設定0040:17處的狀態位元組的第一位為1,緩衝區不變。
此時按下a鍵,因為檢測到狀態位元組的改變,所以能確認左shift被按下,所以此時對應的ascii碼為大寫字母的ascii碼41h,緩衝區內容如下:
鬆開左shift鍵也會引發中斷例程,然後將對應狀態位元組恢復為0.
bios提供了int16h中斷例程供程式設計師使用,它有乙個功能是從鍵盤緩衝區中讀取乙個鍵盤輸入,該功能的編號為0,下列指令可以讀取乙個鍵盤輸入,同時將其從緩衝區中刪除:
mov ah,0
int 16h
執行完畢後,ah中是掃瞄碼,al中是ascii碼。
這段**執行後會檢查鍵盤緩衝區中是否有資料,如果沒有就一直檢測,如果有的話再執行讀取和從緩衝區中刪除。可見,int9中斷例程和int16h中斷例程是一對相互配合的程式。
最基本的字串輸入程式,需要具備下面的功能:
1、在輸入的同時需要顯示這個字串
2、一般在輸入回車符後,字串輸入結束
3、能夠刪除已經輸入的字元
我們輸入字元的時候是從左往右,但是刪除時是先刪除最右邊的字元,這說明字串應該用棧的形式儲存,每次輸入和刪除乙個字元的時候,應該將棧中的字串顯示到螢幕上,按下回車後可以在字串中加入0,代表字串結束。
程式的處理過程如下:
1、呼叫int16h讀取鍵盤輸入
2、如果是字元,進入字元棧,顯示字元棧中所有的字元,然後繼續執行1
3、如果是退格鍵,從字元棧中彈出乙個字元,顯示字元棧中所有的字元,繼續執行1
4、如果是enter就向字元棧中壓入0,然後返回
我們先把字元棧的入棧、出棧和顯示棧中的內容寫成子程式,引數說明:
ah是功能號,0表示入棧,1表示出棧,2表示顯示。ds:si指向字元棧空間,對0號功能,al是入棧字元;對1號功能,al是返回的字元;對於2號功能,dh和dl代表螢幕上顯示的行、列位置。
程式如下:
charstack: jmp short charstart
table dw charpush,charpop,charshow 建立定址表
top dw 0
charstart: push bx
push dx
push di
push es
cmp ah,2
ja sret 如果ah大於2跳轉到sret結束子程式
mov bl,ah
mov bh,0
add bx,bx 組成bx然後增加一倍
jmp word ptr table[bx] 呼叫對應的程式
charpush: mov bx,top
mov [si][bx],al
inc top 入棧後修改指標的值
jmp sret
charpop: cmp top,0
je sret 如果棧為空則直接跳轉到sret
dec top
mov bx,top
mov al,[si][bx] 出棧後修改指標的值
jmp sret
charshow: mov bx,0b800h
mov es,bx
mov al,160
mov ah,0
mul dh
mov di,ax
add dl,dl
mov dh,0
add di,dx
mov bx,0 初始化bx為0
charshows: cmp bx,top 比較bx和top的值判斷棧是否為空
jne noempty
mov byte ptr es:[di],' ' 為空則顯示空格
jmp sret
noempty: mov al,[si][bx]
mov es:[di],al
mov byte ptr es:[di+2],' '
inc bx 不為空顯示對應單元的值然後更新指標
add di,2
jmp charshows
sret: pop es
pop di
pop dx
pop bx
ret
完整程式如下:
getstr: push ax
getstrs:mov ah,0
int 16h 讀取鍵盤緩衝區
cmp al,20h
jb nochar ascii碼低於20h說明不是字元轉到nochar
mov ah,0
call charstack 如果是字元就將其入棧
mov ah,2
call charstack 顯示字串
jmp getstrs
nochar: cmp ah,0eh
je backspace 如果掃瞄碼為0eh就轉到backspace
cmp ah,1ch
je enter 如果掃瞄碼為1ch就轉到enter
jmp getstrs 否則繼續呼叫本程式
backspace: mov ah,1
call charstack
mov ah,2
call charstack 先出棧再顯示字串
jmp getstrs
enter: mov al,0
mov ah,0
call charstack 將0入棧,表示字串的輸入結束
mov ah,2
call charstack 顯示字串
pop ax
ret
bios提供的訪問磁碟的中斷例程為int 13h,讀取0面0道1扇區的內容到0:200的程式如下:
mov ax,0
mov es,ax
mov bx,200h es:bx指向接受資料的記憶體區
mov al,1 讀取的扇區數
mov ch,0 磁軌號為0
mov cl,1 扇區號為1
mov dl,0
mov dh,0 磁頭號,也就是面號為0
mov ah,2 2功能代表讀扇區
int 13h
dl是驅動器號,對於軟碟機來講0是軟碟機a,1是軟碟機b,對於硬驅來講,80h是硬碟c,81h是硬碟d。
如果讀取成功,則ah為0,al為讀入的扇區數,如果讀取失敗,ah裡面是出錯**。
如果是向磁碟寫入,只需要將ah代表的功能號改為3即可,就可以將0:200的內容寫入磁碟對應位置。
彙編第十七節 使用BIOS進行鍵盤輸入和磁碟讀寫
cpu在9號中斷發生後,執行int9中斷例程,從60h埠讀出掃瞄碼,並將其轉化為相應的ascii碼或狀態資訊,儲存在記憶體的指定空間 鍵盤緩衝區或狀態位元組 中 比如 a鍵的掃瞄碼1eh和對應的ascii碼,即字母 a 的ascii碼61h,寫入鍵盤緩衝區。緩衝區的字單元中,高位位元組儲存掃瞄碼,低...
用80x86組合語言程式設計 鍵盤輸入與顯示輸出
要求 從鍵盤輸入一行字元,要求第乙個鍵入的字元必須是空格,不是,就退出。如果是的話,開始接收字元並存放在首位址buffer的緩衝區內,直到接收到第二個空格時結束。然後輸出這個字串。懸賞分 15 下列程式,經過檢驗,符合條件要求。data segment buffer db 80 dup data e...
使用DFS進行拓撲排序,如果可以完成的話,輸出路徑
進行深度優先搜尋的時候,如果當前訪問的點是已經被訪問過的節點的話,說明出現了逆邊。因此有環,無法完成拓撲排序。如果可以完成拓撲排序,檢測點序列就是乙個合法的拓撲排序 include include using namespace std class solution cout endl bool d...