咱们都知道,若是想让一个程序,同时又干这个,又干那个,最好的办法就是多线程。这个在高级语言里面已经用烂了。程序员
可是,DOS是只有单线程的。我若是想让程序在运行的同时,又能接受我键盘的输入,那要怎么办呢?多线程
例如,我有一个DOS彩票开奖软件。屏幕上有十个数字在滚动,当我按下空格键的时候,它会中止跳动,按别的键无效。那么要怎么操做?框架
首先,接收输入最经常使用的是int 21h中断里的7号功能调用。可是它是一个中断输入,也就是为了接收这个输入,个人程序就暂停在这儿不动了。可是我彩票开奖数字一直在滚动,那要怎么办啊?不能说我按一下它滚动一下吧。oop
因而请来了今天的主角,int16h中断。spa
首先咱们看看int 16h中断有哪些功能?线程
BIOS提供了int 16h中断例程供程序员调用,且功能是从软件层面上实现键盘I/O功能中断调用,功能号为0,1,2,而且必须把功能号放在ah寄存器中。code
mov ah,01h int 16h
功能:从键盘读入字符送进al寄存器,执行时,等待键盘输入,一旦输入,输入字符的ASCII码放入al中。若al为0,则ah为输入的扩展码。可是,若是键盘缓冲区已有数据,则会读取键盘缓冲区数据,而且将其从缓冲区中删除。内存
0号功能的工做流程为:工作流
mov ah,01h int 16h
功能:用于查询键盘缓冲区,对键盘扫描可是不等待(也就是不会中断程序),并设置标志寄存器中的ZF。若是有键盘输入(即键盘缓冲区不空),则ZF=0,AL存放的是当前输入的ASCII码,AH存放的是输入字符的扩展码。若无键盘操做,则标志位ZF=1。class
mov ah,02h int 16h
功能:检查键盘上各特殊功能键的状态。执行后,各类特殊功能键的状态放入AL寄存器中,这个状态字记录在内存0040H:0017H单元中,若对应位为“1”,表示该键状态为“ON”,处于按下状态;若对应位为“0”,表示该键状态为“OFF”,处于断开状态。
mov ah,02h int 16h ;从键盘输入 and al,04h ;判断是否按下Ctrl jnz Ctrl_on Ctrl_on: ......
了解了以上功能,咱们来看如何实现伪多线程输入。
mainLoop: mov ah,01h ;检测是否有输入 int 16h jz offKey ;jz是当zf=1时跳转,也就是无输入 ;若是有输入,没有跳转 mov ah,00h ;那么键盘缓冲区已不为空 int 16h cmp al,32 ;和空格的ASCII码比较 je spaceProc ... spaceProc: ... offKey: ...
这个框架简单易懂,先从mainLoop中判断是否有输入:
这样,利用int 16h中断中0号功能和1号功能的联动,咱们实现了在只支持单线程的DOS中,实现了伪多线程的输入判断。