汇编语言随笔(13)- 外中断(可屏蔽中断)、实验15
端口的作用
??????在PC系統的接口卡和主板上,裝有各種接口芯片。這些外設接口芯片內部有若干寄存器,CPU將這些寄存器當作端口來訪問。
??????外設的輸入不直接送入內存和CPU,而是送入相關的接口芯片的端口中;CPU向外設的輸出也不是直接送入外設,而是先送入端口中,再由相關的芯片送到外設。CPU還可以向外設輸出控制命令,這些命令也是先送到相關芯片的端口中,再由相關芯片根據命令對外設實施控制。
外中斷
??????之前所提到的中斷類型都是屬于內中斷,也就是在CPU的內部有需要處理的事情時,產生中斷信息,引發中斷過程。
??????在此,我們主要介紹外中斷,也就是說當CPU的外部有需要處理的事情時,比如:外設的輸入到達,相關芯片將向CPU發出相應的中斷信息。CPU在執行完當前指令后,可以檢測到發送過來的中斷信息,引發中斷過程來處理外設的輸入。
??????外中斷源一共有兩類:
(1)可屏蔽中斷
??????這類中斷是CPU可以不響應的外中斷。CPU是否響應可屏蔽中斷,在于標志寄存器IF位的設置。當CPU檢測到可屏蔽中斷信息時,如果IF=1,則CPU在執行完當前指令后響應中斷,引發中斷過程;如果IF=0,則不響應可屏蔽中斷。
??????故:中斷過程中的置TF=0是為了在中斷處理程序中防止CPU陷入單步執行(內中斷)循環;而IF=0是為了在中斷處理程序中禁止其他的可屏蔽中斷(默認中斷不能嵌套)。
??????8086CPU提供的設置IF的指令如下:sti,設置IF=1;cli,設置IF=0。
(2)不可屏蔽中斷
??????這類中斷是CPU必須響應的外中斷。當CPU檢測到不可屏蔽中斷信息時,則在執行完當前指令后,立即響應引發中斷過程。 對于8086CPU,不可屏蔽中斷的中斷類型碼固定為 2,所以在中斷過程中不需要取中斷類型碼。
??????幾乎所有由外設引發的外中斷都屬于可屏蔽中斷。可屏蔽中斷也是我們的重點所在。
鍵盤的中斷處理過程
(1)鍵盤輸入
??????鍵盤上的每一個鍵相當于一個開關,鍵盤中有一個芯片對鍵盤上的每一個鍵的開關狀態進行掃描。
??????按下一個鍵時,開關接通,該芯片產生一個掃描碼,稱其為通碼。通碼說明了按下的鍵在鍵盤上的位置。通碼被送入主板上的相關接口芯片的寄存器中,該寄存器的端口地址為60h。
??????松開按下的鍵時,也產生一個掃描碼,稱其為斷碼。斷碼說明了松開的鍵的位置,也被送入到60h端口中。
??????掃描碼的長度為一個字節,通碼的第 7 位為0,斷碼的第 7 位為1。 斷碼 = 通碼 + 80h。比如 g 鍵的通碼為 22h,斷碼為 a2h。
(2)引發 9 號中斷
??????當鍵盤輸入到達 60h 端口時,相關芯片會對CPU發出中斷類型碼為 9 的可屏蔽中斷。如果此時 IF=1,則響應中斷,引發中斷過程,執行相應的中斷處理程序。
(3)執行 int 9 中斷例程
?????? 讀出60h端口中的掃描碼。
?????? 如果為字符鍵的掃描碼,將它和它對應的字符碼(ASCII碼)送入內存中的BIOS鍵盤緩沖區;如果是控制鍵(Ctrl、Caps)的掃描碼,將它轉變為狀態字節寫入內存中存儲狀態字節的單元。
?????? 對鍵盤系統進行相關的控制,如,對相關芯片發出應答信息。
??????補充:BIOS鍵盤緩沖區是系統啟動后,BIOS用于存放 int 9 中斷例程所接收的鍵盤輸入的內存區。該內存區可以存儲15個鍵盤輸入,int 9 中斷例程除了接收掃描碼外,還需要產生和掃描碼對應的字符碼,故:在緩沖區中,一個鍵盤輸入用一個字單元存放,高位字節存放掃描碼,低位字節存放字符碼。
??????內存單元 0040:17 存儲鍵盤狀態字節,用來記錄控制鍵和切換鍵的狀態。比如說:按下 Ctrl 鍵,對應的位置1,松開置0。按下 Insert 鍵,對應的位置1表示處于刪除態,否則置0。
編寫 int 9 中斷例程
?????? 編程:在屏幕中間依次顯示‘a’-’z’,并可以讓人看清。在顯示的過程中,按下Esc鍵后,改變顯示的顏色。(Esc鍵的通碼是1)
?????? 思路:在鍵盤輸入到達60h端口后,就會引發9號中斷,CPU轉而去執行 int 9 中斷例程。我們編寫 int 9 中斷例程的功能如下:
??????(1)從60h讀取鍵盤輸入,這是為了對特定輸入稍后進行處理。
??????(2)調用BIOS的 int 9 中斷例程,處理其他細節。
調用原 int 9 的中斷過程需要有4步:
??????a,取中斷類型碼9;
??????b,pushf;
??????c,置 IF、TF為0;
??????d,設置新的CS:IP。
其中a步驟可以忽略,并且c步驟也是可以忽略的,因為在CPU進入到我們編寫的新 int 9 中斷例程后,IF、TF已經置為0了,而執行指令 in al,60h 后不會改變IF、TF的值,所以c被省略。
??????補充:c步驟代碼如下
????????????pushf
????????????pop bx
????????????and bh,11111100b ??????IF、TF在標志寄存器的第9位和第8位。
????????????push bx
????????????popf
??????(3)判斷是否為Esc的掃描碼,若是,改變顯示的顏色,否則直接返回。
實驗15
??????安裝一個新的 int 9 中斷例程,功能:在DOS下,按下“A”鍵后,除非不再松開,如果松開,就顯示滿屏幕的“A”,其他的鍵照常處理。(斷碼=通碼+80h。“A”的通碼為1Eh)
assume cs:codestack segment db 128 dup(0)stack endscode segmentstart: mov ax,stackmov ss,axmov sp,128mov ax,cs ;將ds:si處的新int 9例程安裝到內存0:204h處。mov ds,axmov si,offset int9mov ax,0mov es,axmov di,204hmov cx,offset int9end-offset int9cldrep movsbpush es:[9*4] ;將原來的int 9入口地址存儲在內存0:200h-0:203h處。pop es:[200h]push es:[9*4+2]pop es:[202h]climov word ptr es:[9*4],204h ;將新的int 9例程的入口地址放在中斷向量表中。mov word ptr es:[9*4+2],0stimov ax,4c00hint 21hint9: push axpush espush dipush cxin al,60hpushfcall dword ptr cs:[200h]cmp al,1eh+80h ;判斷是否為“A”的斷碼jne int9retmov ax,0b800hmov es,axmov di,0mov cx,2000s: mov byte ptr es:[di],'A'add di,2loop sint9ret: pop cxpop dipop espop axiretint9end: nopcode endsend start總結
以上是生活随笔為你收集整理的汇编语言随笔(13)- 外中断(可屏蔽中断)、实验15的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汇编语言随笔(11)- int 指令(返
- 下一篇: 汇编语言随笔(14)-直接定址表、检测点