外中断02 - 零基础入门学习汇编语言70
生活随笔
收集整理的這篇文章主要介紹了
外中断02 - 零基础入门学习汇编语言70
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
第十五章:外中斷02
?讓編程改變世界
Change the world by program
?
小甲魚和大家談談心
? 一個帖子引發小甲魚的反省! 貓姐曾經說過,步子別邁太大,容易扯著蛋! 結果還真蛋疼了…… ? 因此,小甲魚要學會淡定面對,不能忘記當初的宗旨!做視頻也好、做網站也好,對得住大家才對得住自己的良心! 最后:希望大家繼續支持魚C、支持小甲魚,看到大家都能坦誠相待,很開心,很幸福! ?編寫int 9 中斷例程
?復習一下前邊的內容中,我們可以總結出鍵盤輸入的處理過程:
(1)鍵盤產生掃描碼; (2)掃描碼送入60h 端口; (3)一旦偵測到60h端口有動靜,引發9 號中斷; (4)CPU執行int 9 中斷例程處理鍵盤輸入。 以上的過程,前三步都由硬件系統自動完成。我們能夠改變的只有第四步,修改int 9 終端程序。 但是,在這門課程中,我們不準備完整地編寫一個鍵盤中斷的處理程序,因為要涉及到一些硬件細節,而這些內容脫離了我們的內容主線。 插入語:如果有興趣想更為深入的學習匯編語言,探究匯編語言的奧妙,可以關注小甲魚今后推出的《The Art of Assembly Language》。 ?但是,我們卻還要編寫新的鍵盤中斷處理程序,來進行一些特殊的工作,那么這些硬件細節如何處理呢?
如果單純要完成這點還是相對比較簡單的,因為BIOS 提供的int 9中斷例程已經對這些硬件細節進行了處理。 我們只要在自己編寫的中斷例程中調用BIOS 的int 9中斷例程就可以了。 ?任務演示:在屏幕中間依次顯示 “a”~“z” ,并可以讓人看清。在顯示的過程中,按下Esc鍵后,改變顯示的顏色。
?我們先來看一下如何依次顯示“a”~“z”:
[codesyntax lang="asm"] assume cs:codecode segmentstart: mov ax,0b800hmov es,axmov ah,'a's: mov es:[160*12+40*2],ahinc ahcmp ah,'z'jna smov ax,4c00hint 21hcode endsend start [/codesyntax] ? 我們發覺,因為一個字母剛顯示到屏幕上,CPU執行幾條指令后,就又變成了另一個字母,字母之間切換得太快,因此我們無法看清。 理想狀況是:我們應該在每顯示一個字母后,延時一段時間,讓人看清后,再顯示下一個字母。 ?那么如何延時呢?
不如……我們讓CPU 執行一段時間的空循環。有時候讓它做點無用功哈~ ? 請看源代碼并試圖分析作者的做法:相關代碼下載 ? 現在顯示“a”~“z”的任務我們基本完成了,并做到可以讓人看清,雖然做法有些無恥…… ? 那么接下來將進一步來實現:按下 Esc 鍵后,改變顯示的顏色!怎么辦呢? 鍵盤輸入到達60h 端口后,就會引發 9號中斷,CPU 則轉去執行int 9中斷例程。 ? 我們可以編寫int 9中斷例程,功能如下: (1)從60h端口讀出鍵盤的輸入; (2)調用BIOS 的int 9 中斷例程,處理其他硬件細節; (3)判斷是否為Esc的掃描碼,如果是,改 變顯示的顏色后返回;如果不是則直接返回。 ? ?接下來,我們對這些功能的實現一一進行分析!
?第一步:從端口60h讀出鍵盤的輸入
in al,60h ?第二步:調用BIOS的int 9中斷例程
注:有一點要注意的是,我們寫的中斷處理程序要成為新的int 9中斷例程,主程序必須要將中斷向量表中的int 9中斷例程的入口地址改為我們寫的中斷處理程序的入口地址。 那么在新的中斷處理程序中調用原來的int 9中斷例程時,中斷向量表中的int 9中斷例程的入口地址卻不是原來的int 9 中斷例程的地址。所以我們不能使用int 指令直接調用。 ? 這里有必要解釋一下:。。。。。。 對于我們現在的問題,假設我們將原來int 9中斷例程的偏移地址和段地址保存在ds:[0]和ds:[2]單元中。 那么我們在需要調用原來的int 9中斷例程時候,就可以在 ds:[0]、ds:[2] 單元中找到它的入口地址。 ?那么,有了入口地址后,我們如何進行調用呢?
當然不能使用指令int 9來調用。我們可以用別的指令來對int指令進行一些模擬,從而實現對中斷例程的調用。 ? 我們來看,int 指令在執行的時候,CPU 進行下面的工作: (1)取中斷類型碼n; (2)標志寄存器入棧; (3) IF=0,TF=0; (4) CS 、IP 入棧; (5)(IP) = (n*4),(CS) = (n*4+2)。 取中斷類型碼是為了定位中斷例程的入口地址,在我們的問題中,中斷例程的入口地址已經知道。 所以,我們用別的指令模擬int 指令時候,不需要做第(1)步。 ? 在假設要調用的中斷例程的入口地址在ds:0和ds:2單元中的前提下,我們將int 過程用下面幾步模擬: (1)標志寄存器入棧; (2)IF=0,TF=0; (3)CS、IP入棧; (4)(IP)=((ds)*16+0),(CS)=((ds)*16+2)。 可以注意到第(3)、(4)步和call dword ptr ds:[0]的功能一樣。 ? call dword ptr ds:[0] 的功能也是: (1)CS 、IP 入棧; (2)(IP)=((ds)*16+0),(CS)=((ds)*16+2)。 如果這點上有疑問的童鞋,不妨可以復習下10.6節的內容。 ?所以經過我們總結后,int 過程的模擬最終變為:
(1)標志寄存器入棧; (2)IF=0,TF=0; (3)call dword ptr ds:[0] 對于(1),可用pushf實現。 對于(2),我們又得動點歪腦筋,沒辦法,資源條件極其卑劣的8086 要么使人放棄,要么逼出天才!我們可用以下程序間接實現: ? 實現IF=0,TF=0步驟:pushf
pop ax
and ah,11111100b ; IF和OF為標志寄存器的
; 第9位和第8位
push ax
popf
? 這樣,模擬int指令的調用功能,調用入口地址在ds:0、ds:2中的中斷例程的程序如下:pushf ;標志寄存器入棧
pushf
pop ax
and ah,11111100b ; IF和OF為標志寄存器的第9
; 位和第8位
push ax
popf ;IF=0、TF=0
call dword ptr ds:[0]
?第三步:如果是Esc鍵的掃描碼,改變顯示的顏色后返回……
? 那么,下一個問題:如何改變顯示的顏色? [buy]?獲得所有教學視頻、課件、源代碼等資源打包?[/buy] [Downlink href='http://kuai.xunlei.com/d/LWPDSCJPSSUD']視頻下載[/Downlink]轉載于:https://www.cnblogs.com/LoveFishC/archive/2011/05/27/3846090.html
總結
以上是生活随笔為你收集整理的外中断02 - 零基础入门学习汇编语言70的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 试管移植后体温会升高吗?
- 下一篇: 光与夜之恋怎么重置选项