ITEEDU

6.5 键盘输入

6.5导航:第一页 第二页 第三页 第四页

 我们早已研究了如何通过21H或16H中断调用来取得按键的信息,但我们对这些信息究竟是如何产生的还一无所知,这一节我们就要更细致地讨论这个问题。那么首先我们把上一节留下的问题解决掉。
我们在前面编制过一个"TESTKEY"程序,下面这个程序是"TESTKEY"的一个升级版本:

TESTKEY2	.ASM		
     ESC_KEY  equ       01h	;一个与ESC键有关的常量
        code  segment
              assume    cs:code
              org       100h
        main  proc      far
              jmp       continue	;跳过数据区
       ascii  db        '0123456789ABCDEF'	;十六进制数对应的ASCII码
   continue:
              push      cs	;通过堆栈将CS寄存器送入DS寄存器
              pop       ds
    waitkey:
              mov       ah,0	;等待键盘输入
              int       16h
              call      out_ax	;调用OUT_AX子过程输出AX寄存器的值
              cmp       ah,ESC_KEY	;输入的是ESC键吗?
              jnz       waitkey	;不是ESC键则转WAITKEY继续
              mov       ah,4ch	;结束程序
              int       21h
        main  endp
			
      out_ax  proc      near	;OUT_AX子过程
              push      ax	;暂存AX寄存器
              mov       bx,offset ascii	;BX寄存器指向ASCII表
              mov       cx,0404h	;设置循环计数与移位计数
    outloop:
              rol       ax,cl	;将AX寄存器的高4位移至低4位
              mov       dx,ax	;用DX寄存器暂存移位后的结果
              and       ax,000fh	;保留AX低4位(实际是移位前的高4位)
              xlat      ascii	;取得对应的ASCII码
              mov       ah,0eh	;利用10H中断的0EH功能
              int       10h	;输出一个数字
              mov       ax,dx	;取回DX寄存器中的移位结果
              dec       ch	;循环计数减1
              jnz       outloop	;循环至OUTLOOP继续输出下一个数位
			
              mov       ax,0e0dh	;输出回车符
              int       10h
              mov       al,0ah	;输出换行符
              int       10h
              pop       ax	;恢复AX寄存器
              ret       ;返回
      out_ax  endp
        code  ends
              end       main

这个程序不仅可以显示出按键的ASCII码,还可以显示出16H中断的0号功能在AH寄存器中返回的数据。运行这个程序,会发现AH寄存器中的数据与所按键的ASCII码好象并无关系,比如按下打字键盘上的数字"1"键,可以看到AX寄存器返回的数据是0231H,其中31H是按键的ASCII码;如果按住Shift键再按下数字"1"键,此时AX寄存器返回0221H,21H是"!"的ASCII码,而AH寄存器中的数据竟然没变;如果按下右边数字小键盘上的"1",就会看到AX寄存器中返回4F31H,31H仍是"1"的ASCII码,而AH寄存器中的数据却变成了4FH。

如果我们暂时给AH寄存器中的数据命名为"幻码"的话那么我们现在就可以总结出这样两条规律:

(1)Shift键可以改变同一按键的ASCII码,但同一键的"幻码"固定不变;
(2)分在不同键区的同名键具有相同的ASCII码,但具有不同的"幻码"。这个规律是否绝对,我们可以按下其它的键来检验,最后我们可以发现这个规律对于大多数键来讲是正确的,个别的一些键无此规律。

  那么就"幻码"本身而言,各个键所对应的"幻码"有没有什么规律呢?我们再次运行这个程序,然后由"1"至"0"顺次按下打字键区中的数字键,再由左至右顺次按下第一行字母键,看看是否得到了下面的结果: