一、鍵的類型
鍵盤是計算機(jī)最基本的一種輸入設(shè)備,用以輸入信息,以達(dá)到人機(jī)對話的目的
鍵盤提供了三種基本類型的鍵
1)字符鍵:傳送一個ascii碼字符給計算機(jī)。如a~z,0~9,%,$ 等。
2)擴(kuò)展功能鍵:產(chǎn)生一個動作。如home,end,enter等,不能用標(biāo)準(zhǔn)ascⅱ碼表示的特殊鍵或組合鍵。
f1~f10:3b~44h
↑ ↓ ← → :48 50 4b 4dh
pgdn pgupins del: 50 48 4b 4d 52 53h
3)組合功能鍵:改變其它鍵所產(chǎn)生的字符碼。如alt,ctrl,shift等
二、字符碼與掃描碼
字符碼與掃描碼
bios的鍵盤中斷:當(dāng)8259a的21h端口第1位(d1)為0,就允許鍵盤中斷,在鍵盤上“按下”或“放開”一個鍵時都會產(chǎn)生一個類型號為9的中斷。并轉(zhuǎn)入bios的鍵盤中斷處理程序。
1)掃描碼:鍵盤中斷處理程序從8255的60h端口讀取一個字節(jié),該字節(jié)的低7位就是鍵的掃描碼。鍵盤上的每一個鍵對應(yīng)一個掃描碼,從01h~51h。
通碼:“按下”時取得的字節(jié)為通碼,d7位=0。
斷碼:“放開”時取得的字節(jié)為斷碼,d7位=1。
2)字符碼:bios鍵盤處理程序?qū)⑺〉玫膾呙璐a轉(zhuǎn)換成相應(yīng)的字符碼。大部分鍵的字符碼為ascii碼,沒有ascii碼的鍵其字符碼為0或一個指定的操作(如屏幕打印等)。
bios數(shù)據(jù)區(qū)的鍵盤緩沖區(qū)kb_buffer?。阂粋€先進(jìn)先出(fifo)并具有雙指針的循環(huán)隊列。存放轉(zhuǎn)換成的字符碼和掃描碼(掃描碼存放在字的高8位上)。當(dāng)cpu想要得到鍵盤輸入時,就調(diào)用bios鍵盤例行程序,它按其接收時的次序從緩沖區(qū)取出字符和掃描碼,回送給cpu。鍵盤緩沖區(qū)結(jié)構(gòu)如下:
0040:001abuff_headdw??。绘I盤緩沖區(qū)的首地址指針
0040:001cbuff_tail dw??。绘I盤緩沖區(qū)的末地址指針
0040:001ekb_buffer dw16 dup (?)??;16個輸入量的空間
0040:003ekb_buffer_end labelword
3)bios鍵盤中斷:int 16h調(diào)用(從鍵盤緩沖區(qū)輸入)。
ah=0:從鍵盤讀一字符。此時一直要等到鍵盤緩沖區(qū)有輸入才返回。返回時al=字符碼,ah=掃描碼。
ah=1:讀鍵盤緩沖區(qū)的字符。如zf=1則鍵盤緩沖區(qū)空;zf=0則al=字符碼,ah=掃描碼。
ah=2:取鍵盤狀態(tài)字節(jié)。al=鍵盤狀態(tài)字節(jié)(kb_flag:0040:0017h單元)。
鍵盤狀態(tài)字節(jié)kb_flag:內(nèi)存的0040:0017h單元,由類型 9的硬件鍵盤中斷置入鍵盤的對應(yīng)狀態(tài)到該單元。低4位是alt、ctrl、shift左、shift右的標(biāo)志位,這4位在相應(yīng)鍵按下時置位,該鍵一抬起即復(fù)位。kb–flag的高4位是ins、caps lock、num lock、scroll lock鍵的標(biāo)志位,這些位在相應(yīng)鍵奇次按下時置位,偶次按下時復(fù)位。具體含義如下:
鍵盤的其它標(biāo)志區(qū):
kb–flag1:0040:0018h單元如下。
其中的高4位是ins、caps lock、num lock、scroll lock鎖定功能鍵的動態(tài)(臨時)標(biāo)志位,即這些鍵按下時該位置1,鍵釋放即被置0。這4位動態(tài)標(biāo)志位用于對這些鍵本身進(jìn)行處理,而kb–flag中的這4位靜態(tài)標(biāo)志位反映了它們的鎖定狀態(tài),用于控制其它鍵的鍵意確認(rèn)。kb–flag1中的d3位為hold–state保持狀態(tài)位,ctrl+num鍵按下時該位置1;非num鍵的任一鍵按下就使其復(fù)位。暫停過程就是將該位置1后進(jìn)入一個無限循環(huán)過程,判斷該位是否變?yōu)椤?”,一但為“0”,即退出循環(huán)。
alt–input:0040:0019h單元。此單元不是標(biāo)志單元,而是寄存單元。在按著alt鍵不釋放的條件下,連續(xù)按下小鍵盤(右區(qū))的數(shù)字鍵×××(1~255)時,此1~3位的十進(jìn)制數(shù)的二進(jìn)制編碼即在此生成。當(dāng)alt鍵釋放時,第一字節(jié)為alt–input單元中的代碼、第二字節(jié)為00h的兩個字節(jié)存入鍵盤緩沖區(qū),alt–input單元又被清0。若打入的數(shù)字鍵大于255數(shù)值,則以256為模產(chǎn)生結(jié)果。這是一種直接在鍵盤緩沖區(qū)建立所期望的ascii代碼的一種方法,第二字節(jié)為00h就與其它鍵所建立的ascii代碼相區(qū)別。
bios–break:0040:0071h單元。此單元是中止或稱為間斷標(biāo)志單元。ctrl+scroll鍵按下時,該標(biāo)志字節(jié)置為80h,否則為00h,ctrl+scroll鍵的按下還清除鍵盤緩沖區(qū),并以兩個全0字節(jié)為其ascii碼,存入鍵盤緩沖區(qū)。此標(biāo)志和特征碼均可被其他軟件用來證實“間斷”鍵的按下。但是rom–bios并不直接提供間斷功能,在鍵盤中斷服務(wù)程序中,對該組合鍵的按下提供了一條int 1bh指令。在rom–bios中類型1bh中斷的服務(wù)程序只是一條中斷返回指令iret,其它什么都不做。其它軟件只需將其“間斷”功能程序的入口地址重新寫入中斷向量表的1bh×4的位置中去即可。因而即對其它軟件提供了查詢處理的方便,也提供了中斷處理的方便,用以實施“間斷”功能。
reset–flag:0040:0072h單元。是兩字節(jié)的復(fù)位標(biāo)志。當(dāng)ctrl+alt+del組合鍵按下時,就以1234h代碼填入,然后轉(zhuǎn)移到復(fù)位初始化程序,這就是熱啟動復(fù)位。
shift+prtsc組合鍵:是打印屏幕的特殊操作。按下時由鍵盤中斷服務(wù)程序執(zhí)行軟件中斷指令int 5產(chǎn)生的。這個組合鍵既不向鍵盤緩沖區(qū)存代碼,也不建立標(biāo)志,但是int 5軟件中斷服務(wù)程序使用status–byte標(biāo)志單元(0050:0000),使在打印屏幕過程中再按下shift+prtsc鍵將不被理睬。
三、dos鍵盤功能調(diào)用
(用bios鍵盤緩沖區(qū)輸入)設(shè)置ah,執(zhí)行int 21h的dos功能調(diào)用實現(xiàn)從鍵盤輸入字符。
單字符輸入:輸入的字符在al寄存器中返回。
ah=1:從鍵盤輸入一個字符并回顯在屏幕上,并檢驗是否按下了ctrl_break鍵,如按下則自動調(diào)用int 23h并結(jié)束程序。返回時al=字符。
ah=6:讀鍵盤字符,入口時dl=0ffh。如果準(zhǔn)備好,al=字符,未準(zhǔn)備好,al=0。
ah=7:從鍵盤輸入一個字符不回顯,也不檢驗是否按下了ctrl_break鍵。返回時al=字符。
ah=8:除不回顯以外,同功能1。
注意:若要求程序能接收功能鍵及具有鍵擴(kuò)展碼的組合鍵必須進(jìn)行兩次dos功能調(diào)用,第一次回送00,第二次回送掃描碼。
輸入字符串:ah=0ah。從鍵盤輸入一串字符并存入用戶定義的緩沖區(qū)中(ds:dx=緩沖區(qū)首地址)。
緩沖區(qū)的第一字節(jié)給出能輸入的最大字符數(shù)。由用戶程序給出。如下:
第二字節(jié)為調(diào)用后實際輸入的字符數(shù)。由功能0ah調(diào)用填入,不含回車符。
第三字節(jié)開始為調(diào)用后實際輸入的字符串。由功能0ah填入,不含回車符。
dos調(diào)用后,保持ds:dx=緩沖區(qū)首地址不變。
清除鍵盤緩沖區(qū):ah=0ch。清除后并再調(diào)用一種鍵盤功能。被調(diào)用的鍵盤功能號(只能是1、6、7、8、0ah)作為入口信息放在al寄存器中。
檢驗鍵盤狀態(tài):ah=0bh。返回時al=0ffh表示有鍵入,al=00則無鍵入。返回后執(zhí)行下一條指令。
四、鍵盤輸入
1、bios的鍵盤中斷
(1)字符輸入
mov ah,o
int 16h
(2)讀鍵盤狀態(tài)
mov ah,2
int 16h
xor ah,ah
mov bx,ax
mov ch,4
rotate:
mov cl,4
rol bx,cl
mov al,bl
and al,0fh
add al,30h
cmp al,3ah
jlprint
add al,7
print:
mov dl,al
mov ah,2
int 21h
dec ch
jnz rotate
2、dos字符輸入功能調(diào)用
(1)讀入單字符
mov ah,1
int 21h
(2)字符串輸入
maxlen db n
actlen db ?
string db n dup(?)
lea dx,maxlen
。。。
mov ah,0ah
int 21h
xor bh,bh
mov bl,actlen
mov string[bx],0;作文件名
或 mov string[bx],‘$’ ;顯示