演示中斷處理的例項(例項六)(轉)
斷處理的例項(例項六):
下面給出一個用於演示中斷處理的例項。該例項的邏輯功能是,在螢幕的左上角以倒數計時方式顯示秒為單位的時間,在時間用完後結束。該例項演示內容包括:外部中斷處理程式和陷阱處理程式。
1.源程式組織和清單
本例項由如下幾部分組成:
(1)全域性描述符表GDT。GDT中除了含有常見的幾個描述符外,還含有描述時鐘中斷處理程式所使用的程式碼段和資料段描述符,以及描述顯示程式所使用的程式碼段和資料段描述符。
(2)中斷描述符表IDT。為了在保護模式下響應中斷和處理異常,必須有IDT。IDT含有256個門描述符。8號安排的是一個通向時鐘中斷處理程式的中斷門,0FEH號安排的是通向顯示處理程式的陷阱門,其它均安排成通向其它中斷或異常處理程式的陷阱門。
(3)時鐘中斷處理程式的程式碼段和資料段。
(4)實現直接寫顯示緩衝區進行顯示的程式程式碼段和資料段。
(5)處理其它中斷或異常的處理程式的程式碼段。
(6)演示程式的程式碼段、資料段和堆疊段。
(7)真實模式下執行的啟動和結束程式程式碼段和資料段。
源程式清單如下:
;名稱:ASM6.ASM;功能:演示中斷處理的實現;編譯:TASM ASM6.ASM;連線:TLINK ASM6.OBJ;----------------------------------------------------------------------------INCLUDE 386SCD.INC;----------------------------------------------------------------------------;部分常量定義;----------------------------------------------------------------------------EOICOM = 20h ;外部中斷處理結束命令ICREGP = 20h ;中斷控制暫存器埠地址IMREGP = 21h ;中斷遮蔽暫存器埠地址;----------------------------------------------------------------------------GDTSeg SEGMENT PARA USE16 ;全域性描述符表資料段(16位);---------------------------------------------------------------------------- ;全域性描述符表GDTGDT LABEL BYTE ;空描述符DUMMY Desc <> ;規範段描述符Normal Desc <0ffffh,,,ATDW,,> ;影片緩衝區段描述符(DPL=3)VideoBuf Desc <0ffffh,8000h,0bh,ATDW,,>;----------------------------------------------------------------------------EFFGDT LABEL BYTE ;臨時程式碼段描述符TempCode Desc <0ffffh,TempCodeSeg,,ATCE,,> ;演示程式碼段描述符DemoCode Desc <DemoCodeLen-1,DemoCodeSeg,,ATCE,,> ;演示資料段描述符DemoData Desc <DemoDataLen-1,DemoDataSeg,,ATDW,,> ;演示堆疊段描述符DemoStack Desc <DemoStackLen-1,DemoStackSeg,,ATDWA,,> ;0feh號中斷處理程式(顯示程式)程式碼段描述符EchoCode Desc <EchoCodeLen-1,EchoCodeSeg,,ATCE,,> ;0feh號中斷處理程式(顯示程式)資料段描述符EchoData Desc <EchoDataLen-1,EchoDataSeg,,ATDW,,> ;8號中斷處理程式程式碼段描述符TICode Desc <TICodeLen-1,TICodeSeg,,ATCE,,> ;8號中斷處理程式資料段描述符TIData Desc <TIDataLen-1,TIDataSeg,,ATDW,,> ;其它中斷或異常處理程式程式碼段描述符Other Desc <OtherCodeLen-1,OtherCodeSeg,,ATCE,,>;----------------------------------------------------------------------------GDTLen = $-GDT ;全域性描述符表長度GDNum = ($-EFFGDT)/(SIZE Desc) ;需特殊處理的描述符數;----------------------------------------------------------------------------Normal_Sel = Normal-GDT ;規範段描述符選擇子Video_Sel = VideoBuf-GDT ;影片緩衝區段描述符選擇子;----------------------------------------------------------------------------TempCode_Sel = TempCode-GDT ;臨時程式碼段的選擇子DemoCode_Sel = DemoCode-GDT ;演示程式碼段的選擇子DemoData_Sel = DemoData-GDT ;演示資料段的選擇子DemoStack_Sel = DemoStack-GDT ;演示堆疊段的選擇子EchoCode_Sel = EchoCode-GDT ;0feh號中斷程式程式碼段選擇子EchoData_Sel = EchoData-GDT ;0feh號中斷程式資料段選擇子TICode_Sel = TICode-GDT ;8號中斷程式程式碼段選擇子TIData_Sel = TIData-GDT ;8號中斷程式資料段選擇子Other_Sel = Other-GDT ;其它中斷或異常程式碼段選擇子;----------------------------------------------------------------------------GDTSeg ENDS ;全域性描述符表段定義結束;----------------------------------------------------------------------------IDTSeg SEGMENT PARA USE16 ;中斷描述符表資料段(16位);----------------------------------------------------------------------------IDT LABEL BYTE ;中斷描述符表 ;0--7的8個陷阱門描述符 REPT 8 Gate <OtherBegin,Other_Sel,,AT386TGate,> ENDM ;對應8號(時鐘)中斷處理程式的門描述符 Gate <TIBegin,TICode_Sel,,AT386IGate,> ;從9--0fdh的245個陷阱門描述符 REPT 245 Gate <OtherBegin,Other_Sel,,AT386TGate,> ENDM ;對應0feh號中斷處理程式的陷阱門描述符 Gate <EchoBegin,EchoCode_Sel,,AT386TGate,> ;對應0ffh號中斷處理程式的陷阱門描述符 Gate <OtherBegin,Other_Sel,,AT386TGate,>;----------------------------------------------------------------------------IDTLen = $-IDT;----------------------------------------------------------------------------IDTSeg ENDS ;中斷描述符表段定義結束;----------------------------------------------------------------------------;其它中斷或異常處理程式的程式碼段;----------------------------------------------------------------------------OtherCodeSeg SEGMENT PARA USE16 ASSUME CS:OtherCodeSeg;----------------------------------------------------------------------------OtherBegin PROC FAR mov ax,Video_Sel mov es,ax mov ah,17h ;在螢幕左上角顯示蘭底白字 mov al,'!' ;符號"!" mov WORD PTR es:[0],ax jmp $ ;無限迴圈OtherBegin ENDP;----------------------------------------------------------------------------OtherCodeLen = $OtherCodeSeg ENDS;----------------------------------------------------------------------------;8號中斷處理程式的資料段;----------------------------------------------------------------------------TIDataSeg SEGMENT PARA USE16Count DB 0 ;中斷髮生的計數器TIDataLen = $TIDataSeg ENDS;----------------------------------------------------------------------------;8號中斷處理程式的程式碼段;----------------------------------------------------------------------------TICodeSeg SEGMENT PARA USE16 ASSUME CS:TICodeSeg,DS:TIDataSeg;----------------------------------------------------------------------------TIBegin PROC FAR push eax ;保護現場 push ds push fs push gs mov ax,TIData_Sel ;置中斷處理程式資料段 mov ds,ax mov ax,EchoData_Sel ;置顯示過程資料段 mov fs,ax mov ax,DemoData_Sel ;置演示程式資料段 mov gs,ax cmp Count,0 jnz TI2 ;計數非0表示未到1秒 mov Count,18 ;每秒約18次 int 0feh ;呼叫0FEH號中斷處理程式顯示 cmp BYTE PTR fs:Mess,'0' jnz TI1 mov BYTE PTR gs:Flag,1 ;顯示符號'0'時置標記TI1: dec BYTE PTR fs:Mess ;調整顯示符號TI2: dec Count ;調整計數 pop gs ;恢復現場 pop fs pop ds mov al,EOICOM ;通知中斷控制器中斷處理結束 out ICREGP,al pop eax iretd ;中斷返回TIBegin ENDP;----------------------------------------------------------------------------TICodeLen = $TICodeSeg ENDS;----------------------------------------------------------------------------;0FEH號中斷處理程式資料段;----------------------------------------------------------------------------EchoDataSeg SEGMENT PARA USE16Mess DB '8',4ehEchoDataLen = $EchoDataSeg ENDS;----------------------------------------------------------------------------;0FEH號中斷處理程式(顯示程式)的程式碼段;----------------------------------------------------------------------------EchoCodeSeg SEGMENT PARA USE16 ASSUME CS:EchoCodeSeg,DS:EchoDataSeg;----------------------------------------------------------------------------EchoBegin PROC FAR push ax ;保護現場 push ds push es mov ax,EchoData_Sel ;置顯示過程資料段 mov ds,ax mov ax,Video_Sel ;置影片緩衝區資料段 mov es,ax mov ax,WORD PTR Mess mov WORD PTR es:[0],ax pop es pop ds pop ax iretdEchoBegin ENDP;----------------------------------------------------------------------------EchoCodeLen = $EchoCodeSeg ENDS;----------------------------------------------------------------------------;演示任務的堆疊段;----------------------------------------------------------------------------DemoStackSeg SEGMENT PARA USE16DemoStackLen = 1024 DB DemoStackLen DUP(0)DemoStackSeg ENDS;----------------------------------------------------------------------------;演示任務的資料段;----------------------------------------------------------------------------DemoDataSeg SEGMENT PARA USE16Flag DB 0DemoDataLen = $DemoDataSeg ENDS;----------------------------------------------------------------------------;演示任務的程式碼段;----------------------------------------------------------------------------DemoCodeSeg SEGMENT PARA USE16 ASSUME CS:DemoCodeSeg,DS:DemoDataSeg;----------------------------------------------------------------------------DemoBegin PROC FAR mov ax,DemoStack_Sel ;置堆疊 mov ss,ax mov sp,DemoStackLen ;置資料段 mov ax,DemoData_Sel mov ds,ax mov es,ax mov fs,ax mov gs,ax mov al,11111110b ;置中斷遮蔽字 out IMREGP,al ;只開發時鐘中斷 sti ;開中斷DemoConti: cmp BYTE PTR Flag,0 ;判標誌 jz DemoConti ;直到不為0 cli ;關中斷 ;轉回臨時程式碼段,準備回實方式 JUMP16 TempCode_Sel,<OFFSET ToDos>DemoBegin ENDP;----------------------------------------------------------------------------DemoCodeLen = $DemoCodeSeg ENDS;----------------------------------------------------------------------------TempCodeSeg SEGMENT PARA USE16 ;臨時任務的程式碼段 ASSUME CS:TempCodeSeg;----------------------------------------------------------------------------Virtual PROC FAR JUMP16 DemoCode_Sel,DemoBegin ;轉演示任務ToDos: mov ax,Normal_Sel ;恢復實方式段描述符快取記憶體 mov ds,ax mov es,ax mov fs,ax mov gs,ax mov ss,ax mov eax,cr0 ;準備返回真實模式 and al,11111110b mov cr0,eax JUMP16 <SEG Real>,<OFFSET Real>Virtual ENDP;----------------------------------------------------------------------------TempCodeSeg ENDS;============================================================================RDataSeg SEGMENT PARA USE16 ;實方式資料段VGDTR PDesc <GDTLen-1,> ;GDT偽描述符VIDTR PDesc <IDTLen-1,> ;IDT偽描述符NORVIDTR PDesc <3ffh,> ;用於儲存原IDTR值SPVar DW ? ;用於儲存實方式下的SPSSVar DW ? ;用於儲存實方式下的SSIMaskRegV DB ? ;用於儲存原中斷遮蔽暫存器值RDataSeg ENDS;----------------------------------------------------------------------------RCodeSeg SEGMENT PARA USE16 ;實方式程式碼段 ASSUME CS:RCodeSeg,DS:RDataSeg;----------------------------------------------------------------------------Start PROC mov ax,RDataSeg mov ds,ax cld call InitGDT ;初始化全域性描述符表GDT call InitIDT ;初始化中斷描述符表IDT mov SSVar,ss ;儲存堆疊指標 mov SPVar,sp sidt QWORD PTR NORVIDTR ;儲存IDTR in al,IMREGP mov BYTE PTR IMaskRegV,al lgdt QWORD PTR VGDTR ;裝載GDTR cli ;關中斷 lidt QWORD PTR VIDTR ;裝載IDTR mov eax,cr0 or al,1 mov cr0,eax JUMP16 <TempCode_Sel>,<OFFSET Virtual>Real: mov ax,RDataSeg mov ds,ax lss sp,DWORD PTR SPVar ;又回到實方式 lidt QWORD PTR NORVIDTR mov al,IMaskRegV out IMREGP,al sti mov ax,4c00h int 21hStart ENDP;----------------------------------------------------------------------------InitGDT PROC push ds mov ax,GDTSeg mov ds,ax mov cx,GDNum mov si,OFFSET EFFGDTInitG: mov ax,[si].BaseL movzx eax,ax shl eax,4 shld edx,eax,16 mov WORD PTR [si].BaseL,ax mov BYTE PTR [si].BaseM,dl mov BYTE PTR [si].BaseH,dh add si,SIZE Desc loop InitG pop ds mov bx,16 mov ax,GDTSeg mul bx mov WORD PTR VGDTR.Base,ax mov WORD PTR VGDTR.Base+2,dx retInitGDT ENDP;----------------------------------------------------------------------------InitIDT PROC mov bx,16 mov ax,IDTSeg mul bx mov WORD PTR VIDTR.Base,ax mov WORD PTR VIDTR.Base+2,dx retInitIDT ENDP;----------------------------------------------------------------------------RCodeSeg ENDS END Start
2.關於例項六的說明
(1)時鐘中斷仍使用8H號中斷向量
為了即簡單又清楚地演示在保護模式下響應外部中斷並進行處理,例項使用了時鐘中斷源,但沒有透過重新設定中斷控制器的方法改變對應的中斷向量。所以,時鐘中斷使用的8H號中斷向量號就與雙重故障異常使用的中斷向量號發生衝突。但例項僅是演示程式,所以只要保證不發生雙重故障異常,就可避免衝突,從而不會影響演示。
設定中斷遮蔽暫存器,僅開放時鐘中斷。所以,在開中斷狀態下,也只可能發生時鐘中斷,而不會發生其它外部中斷。
(2)時鐘中斷處理程式的設計
由於透過中斷門轉時鐘中斷處理程式,所以在控制轉移時不發生任務切換。但外部中斷隨時可能發生,因此中斷處理程式必須採取保護現場等措施。作為演示程式,該中斷處理程式檢查和調整在其資料段中的計數器,滿18次後,就認為已滿一秒,再調整用於顯示的倒計數資訊。如果倒計數資訊為0,那麼就設定演示程式資料段中的時間為0標誌。該中斷處理程式透過約定的資料區與顯示程式及演示程式交換資訊。
(3)利用一個軟中斷(陷阱處理)程式實現顯示
為了演示陷阱及其處理,把顯示過程安排成陷阱處理程式。上述時鐘中斷處理程式透過軟中斷呼叫指令INT呼叫該顯示程式,以顯示倒計數。在控制轉移時,也沒有任務切換。該陷阱處理程式相當於一個“軟中斷”處理程式,類似真實模式下的BIOS中斷INT 10H。
(4)對其它中斷或異常的響應
為了簡單,除了8H號和0FEH號外,IDT中其它的門均通向一個處理程式。該處理程式用於處理其它中斷或異常。處理過程也極其簡單,在螢幕左上角顯示藍底白字的符號“!”,然後進入無限迴圈。實際上,按演示程式現在的安排,不可能發生這種情況。
(5)沒有特權級變換
為了簡單,例項涉及的中斷處理程式和異常處理程式都保持特權級0。所以,控制轉移時不發生特權級變換。因此,沒有使用其它堆疊。
(6)對IDT的初始化
由於IDT中門描述符沒有32位段基地址,並且入口點偏移較小,所以就直接填寫門描述符結構變數,沒有額外再初始化。過程InitIDT只是設定IDT偽描述符。
(7)裝載和儲存IDTR暫存器
再使IDT發揮作用之前,還要裝載中斷描述符表暫存器IDTR;但為了回到真實模式後,恢復原來的IDTR之內容,所以先儲存IDTR的內容。例項使用如下指令儲存IDTR:
sidt QWORD PTR NORVIDTR
該指令的功能是把IDTR的內容儲存到儲存器中的偽描述符NORVIDTR中。該偽描述符的結構如前文所述的結構型別PDESC所示,低字是以位元組為單位的界限,高雙字是基地址。在後面的文章中將對SIDT指令作詳細說明。
本例項使用如下指令裝載IDTR暫存器:
lidt QWORD PTR VIDTR lidt QWORD PTR NORVIDTR
LIDT指令類似於LGDT指令,在後面的文章中將對LIDT指令作詳細說明。
[@more@]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10172717/viewspace-928727/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- GaussDB(分散式)例項故障處理分散式
- NLP自然語言處理中的hanlp分詞例項自然語言處理HanLP分詞
- MySQL碎片整理小節--例項演示MySql
- VUE例項:使用 CSS Filter 處理圖片VueCSSFilter
- php例項化物件的例項方法PHP物件
- 如何將獨立例項轉換成叢集例項EU
- 如何區分例項化網格中的每個例項
- Nacos - 服務端處理例項列表請求服務端
- 在思科ASA上部署Failover例項演示-上AI
- iOS架構入門 - MVC模式例項演示iOS架構MVC模式
- 例項演示如何使用CCE XGPU虛擬化GPU
- 測試驅動開發(TDD)例項演示
- 分享一下 Laravel 的中時間的簡單處理方式例項Laravel
- JS中Caesars Cipher的例項JS
- 三個例項演示 Java Thread Dump 日誌分析Javathread
- Activiti的流程例項【ProcessInstance】與執行例項【Execution】
- 對pandas進行資料預處理的例項講解
- longing載入中例項
- Linux中head命令例項Linux
- JavaScript:從Callback到Async的發展過程——例項演示JavaScript
- OkHttpClient例項HTTPclient
- unittest例項
- jQuery 例項jQuery
- 腦機介面例項二:腦電訊號CSP處理腦機介面
- 解密Spring中的Bean例項化:推斷構造方法(上)解密SpringBean構造方法
- CSS 例項之翻轉圖片CSS
- python例項方法中self的作用Python
- Linux 中 ss 命令的使用例項Linux
- Linux 中的 JQ 命令使用例項Linux
- Linux中ip命令的使用例項Linux
- Linux中的basename命令使用例項Linux
- 例項詳解構建數倉中的行列轉換
- Linux中printf命令使用例項Linux
- 遞迴中Return例項分析遞迴
- C++中dynamic_cast與static_cast淺析與例項演示C++AST
- guava之ImmutableMap使用例項及好處Guava
- 例項化list
- msfvenom使用例項
- 雙層 for 例項