繁体   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