x86彙編利用int 16h中斷實現僞多線程輸入

x86彙編利用int 16h中斷實現僞多線程輸入

咱們都知道,若是想讓一個程序,同時又幹這個,又幹那個,最好的辦法就是多線程。這個在高級語言裏面已經用爛了。程序員

可是,DOS是隻有單線程的。我若是想讓程序在運行的同時,又能接受我鍵盤的輸入,那要怎麼辦呢?多線程

例如,我有一個DOS彩票開獎軟件。屏幕上有十個數字在滾動,當我按下空格鍵的時候,它會中止跳動,按別的鍵無效。那麼要怎麼操做?框架

首先,接收輸入最經常使用的是int 21h中斷裏的7號功能調用。可是它是一箇中斷輸入,也就是爲了接收這個輸入,個人程序就暫停在這兒不動了。可是我彩票開獎數字一直在滾動,那要怎麼辦啊?不能說我按一下它滾動一下吧。oop

因而請來了今天的主角,int16h中斷。spa

首先咱們看看int 16h中斷有哪些功能?線程

BIOS提供了int 16h中斷例程供程序員調用,且功能是從軟件層面上實現鍵盤I/O功能中斷調用,功能號爲0,1,2,而且必須把功能號放在ah寄存器中。code

0號功能調用

mov ah,01h
int 16h

功能:從鍵盤讀入字符送進al寄存器,執行時,等待鍵盤輸入,一旦輸入,輸入字符的ASCII碼放入al中。若al爲0,則ah爲輸入的擴展碼。可是,若是鍵盤緩衝區已有數據,則會讀取鍵盤緩衝區數據,而且將其從緩衝區中刪除。內存

0號功能的工做流程爲:工作流

  1. 檢測鍵盤緩衝區是否有數據;
  2. 沒有則回到1;
  3. 讀取緩衝區第一個字單元中的鍵盤輸入;
  4. 將讀取的掃描碼送入ah,ASCII碼送入al;
  5. 將已讀取的鍵盤輸入從緩衝區中刪除

1號功能調用

mov ah,01h
int 16h

功能:用於查詢鍵盤緩衝區,對鍵盤掃描可是不等待(也就是不會中斷程序),並設置標誌寄存器中的ZF。若是有鍵盤輸入(即鍵盤緩衝區不空),則ZF=0,AL存放的是當前輸入的ASCII碼,AH存放的是輸入字符的擴展碼。若無鍵盤操做,則標誌位ZF=1。class

2號功能調用

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中判斷是否有輸入:

  • 若是沒有任何輸入,則直接執行offKey中的代碼內容;
  • 若是有輸入,會調用0號功能對鍵盤緩衝區進行檢索。由於咱們已知它有輸入(鍵盤緩衝區不爲空),因此不會中斷程序。
    • 若是鍵盤輸入爲空格,就跳轉到spaceProc,不然再加別的代碼。
    • 固然,咱們能夠利用這個作不少事情,不僅是判斷空格。

這樣,利用int 16h中斷中0號功能和1號功能的聯動,咱們實現了在只支持單線程的DOS中,實現了僞多線程的輸入判斷。

相關文章
相關標籤/搜索