|
概述: 在编制键盘输入程序时常常要用到一个键的扫描码或ASC码,如用到 Foxpro 的 inkey() 函数,以及用到 BIOS 的 INT 16H时,但找一个编码表不太容易,有时候找到的编码表又不全,无法查到组合键的编码,本程序就是一个随时用来显示按键的ASC码及扫描码的程序,可以用 16 进制和 10 进制同时显示一个键按下和放开的扫描码,以及ASC码,同样也支持组合键。这里是编译好的可执行文件:scancode.com 在本程序中,查表的编程方法可用做参考,一般来说,如果程序有以下的结构: ... cmp al,value1 jz offset1 cmp al,value2 jz offset2 cmp al,value3 jz offset3 ... 且要比较的值很多时,可以考虑查表的方法。程序改为以下结构后,修改起来很容易,可读性也大大增强了,如果要继续添加分支时,只需在表中加上一项就行。 ... table db value1,value2,value3 ... table1 dw offset1,offset2,offset3 ... mov di,offset table mov cx,table的长度 repnz scasb jnz not_found dec di sub di,offset table ;取出表的地址 mov si,di shl si,1 ;x2 add si,offset table1 jmp [si] ;跳转到表中的地址 ... 源程序: ; Scan code viewer ; Aug 3,1995 ; by Luo Yun Bin .286 CODE SEGMENT ASSUME CS:CODE,DS:CODE ORG 100H start: jmp install KEY_BUFF DB ? ;INT 9H中按下一个键产生的扫描码 KEY_BUFF1 DB ? ;INT 9H中松开一个键产生的扫描码 AAH DB ? AAL DB ? D_COPYRIGHT DB "<< ScanCode viewer >>",0dh,0ah DB ';(C) Copyright by Luo Yun Bin, May 26,1996';,0dh,0ah DB 'hone: 0576-4114689.';,0dh,0ah,0ah DB "ress any key to view it';s scan code...",0dh,0ah DB ';or press Esc key to return DOS...';,0dh,0ah,0ah,24h D_MES1 DB ';Scan Code: %02shh (%2sd) ... '; DB ';Release: %02shh (%3sd) ... Key: ';,0 DW KEY_BUFF,KEY_BUFF,KEY_BUFF1,KEY_BUFF1 D_MES2 DB 0dh,0ah,0 D_MES3 DB ';Key value: %02sh%02shh ...... '; DB ';(AH=%sd,AL=%sd)';,0dh,0ah,0ah,0 DW AAH,AAL,AAH,AAL D_MES4 DB ';This is Scan Code viewer by LYB.';,0dh,0ah,24h ;键盘扫描码编码表 ; 0123456789abcdef ; KEY_TABLE DB ';??1234567890-=??'; ;0 DB ';QWERTYUIOP[]??AS'; ;1 DB "DFGHJKL;';`?\\ZXCV" ;2 DB ';BNM,./?*????????'; ;3 DB ';??????????-?5?+?'; ;4 DB ';????????????????'; ;5 DB ';????????????????'; ;6 DB ';????????????????'; ;7 ;特殊键的说明字符串编码表 KEY_TABLE1 DB 3bh,3ch,3dh,3eh,3fh,40h,41h,42h,43h,44h,57h,58h DB 0eh,0fh,3ah,2ah,1dh,38h,36h,1ch,39h,1 DB 52h,53h,47h,4fh,49h,51h,48h,50h,4bh,4dh,46h,45h ;对应上表 KEY_TABLE1_END EQU THIS BYTE DW f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12 DW bks,tab,cap,lsh,ctr,alt,rsh,ent,spa,_esc DW _ins,del,hom,_end,pgu,pgd,up,dow,lef,rig,sco,num ;特殊键的说明字符串 f1 db ';F1';,0 ; f2 db ';F2';,0 f3 db ';F3';,0 f4 db ';F4';,0 f5 db ';F5';,0 f6 db ';F6';,0 f7 db ';F7';,0 f8 db ';F8';,0 f9 db ';F9';,0 f10 db ';F10';,0 f11 db ';F11';,0 f12 db ';F12';,0 bks db ';Back Space';,0 tab db ';Table';,0 cap db ';Caps Lock';,0 lsh db ';Left Shift';,0 ctr db ';Ctrl';,0 alt db ';Alt';,0 rsh db ';Right Shift';,0 ent db ';Enter';,0 spa db ';Space';,0 _ins db ';Insert';,0 del db ';Delete';,0 hom db ';Home';,0 _end db ';End';,0 pgu db 'age Up';,0 pgd db ':犯困age Down';,0 up db ';Up';,0 dow db ';Down';,0 lef db ';Left';,0 rig db ';Right';,0 sco db ';Scroll Lock';,0 num db ';Num Lock';,0 _esc db ';Esc';,0 PRINT_KEY PROC mov bl,key_buff ;取扫描码到BL xor bh,bh mov al,key_table [bx] ;查扫描码表 cmp al,';?'; ;如果为?则继续查特殊码表 jz pk1 pk0: call prt_to_scr ret pk1: mov al,key_buff ;在特殊码表内扫描 mov di,offset key_table1 mov cx,offset key_table1_end-offset key_table1 repnz scasb jnz pk0 dec di sub di,offset key_table1 ;取出说明字符串地址 mov si,di shl si,1 add si,offset key_table1_end mov si,[si] call printf ;显示到屏幕 ret PRINT_KEY ENDP ;新的 INT 09H 键盘中断程序 int9: pushf pusha push ds push es push cs pop ds push cs pop es in al,60h ;读入扫描码 mov key_buff,al test al,80h ;如果>80H则为放开一个键 jnz int9_quit or al,80h mov key_buff1,al mov si,offset d_mes1 call printf call print_key mov si,offset d_mes2 call printf int9_quit: pop es pop ds popa popf DB 0EAH OFF9 DW ? SEG9 DW ? install: mov ah,9 ;显示版权信息 mov dx,offset d_copyright int 21h mov ax,3509h ;保留INT 09H的中断向量 int 21h mov off9,bx mov seg9,es mov ax,2509h ;把INT 09H指到 offset int9 mov dx,offset int9 int 21h push cs pop es lop: mov ah,10h ;扩展键盘输入 int 16h mov aah,ah ;显示键盘输入的编码 mov aal,al mov si,offset d_mes3 call printf cmp key_buff,1 ;如果非按下Esc,继续循环 jnz lop lds dx,dword ptr off9 ;恢复INT 09H中断向量 mov ax,2509h int 21h push cs pop ds mov ah,9 mov dx,offset d_mes4 int 21h int 20h INCLUDE PRINTF.ASM ;一个公用的显示子程序 CODE ENDS END START
|