簡體   English   中英

如何從x86中的中斷處理程序獲取中斷號?

[英]How to get the interrupt number from the interrupt handler in x86?

在x86上以保護模式觸發中斷時,是否可以找出觸發的中斷號? 例如,假設我調用了int 0xFF。 在處理程序中我可以找到int 0xFF被調用?

如果你有唯一的中斷處理程序(或者,至少是唯一的入口點和序言代碼),那么,當然,你可以區分int 0xFF ,比如int 0x30 ISR地址存儲在IDT ,因此,這就是區分開始的地方。

沒有非常好的替代獨特的ISR。 這就是為什么......

在ISR中,您可以檢查調用者的堆棧,查看返回地址並檢查返回地址之前的代碼,以查看它是否是2字節的int n指令(編碼為字節:0xCD,n)或其他內容。 問題是,也有int 3into 1個字節的指令(分別編碼為的0xCC和0xCE)。 你如何區分0xCD + 0xCC( int 0xCC )或0xCD + 0xCE( int 0xCE )和0xCC( int 3 )或0xCE( into )? 在0xCC或0xCE之前可能有任何內容。 可變長度的指令不會讓我們輕松可靠地分析/反匯編代碼。

那些觸發中斷/異常的方法怎么樣,比如ud2 或觸發#GP,#PF的指令? 那些可以是任意指令。

此外,您應該記住,異常不會以完全相同的方式處理。 其中一些在進入ISR之前帶有CPU保存在堆棧上的額外信息,這是錯誤代碼。 其他人沒有這個錯誤代碼和ISR需要做之前將其刪除iret 確定異常向量時出錯將導致代碼崩潰或掛起。

現在,關於硬件中斷......您可以確定正在處理哪個硬件中斷。 PIC具有in-service registerISR ),其中位設置為1(AFAIR)表示IRQ ,但如果讓中斷較高優先級的搶占ISR處理較低優先級的中斷(通過啟用ISR內的中斷),則中斷識別很快變得比必要的復雜。

因此,只需使用獨特的ISR來處理所有IRQ,異常和系統調用。 或者使用一個常見的ISR但具有多個唯一的入口點,每個入口點在堆棧上保存唯一的編號(=向量編號)。 之后的公共代碼將提取該數字並執行該中斷向量所需的操作。

制作將值推送到堆棧的存根是處理這個問題的一種巧妙方法,並且用於James Molloy教程

%macro ISR_NOERRCODE 1
  global isr%1
  isr%1:
    cli                         ; Disable interrupts firstly.
    push byte 0                 ; Push a dummy error code.
    push byte %1                ; Push the interrupt number.
    jmp isr_common_stub         ; Go to our common handler code.
%endmacro

%macro ISR_ERRCODE 1
  global isr%1
  isr%1:
    cli                         ; Disable interrupts.
    push byte %1                ; Push the interrupt number
    jmp isr_common_stub
%endmacro

ISR_NOERRCODE 0
ISR_NOERRCODE 1
ISR_NOERRCODE 2
ISR_NOERRCODE 3
ISR_NOERRCODE 4
ISR_NOERRCODE 5
ISR_NOERRCODE 6
ISR_NOERRCODE 7
ISR_ERRCODE   8
ISR_NOERRCODE 9
ISR_ERRCODE   10
ISR_ERRCODE   11
ISR_ERRCODE   12
ISR_ERRCODE   13
ISR_ERRCODE   14
ISR_NOERRCODE 15
/* More entries */

這也處理錯誤代碼

我不是中斷處理程序的專家,但他們必須在某處有一個返回地址,以便原始代碼可以恢復執行。 如果您可以使用此地址,那么您可以檢查以前的地址,該地址可能包含中斷的編號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM