【发布时间】:2020-03-31 17:39:11
【问题描述】:
我没有真正意义上的问题,但我会尝试澄清一个内容问题。假设我们有一个微内核(PC Intel x86;32 位保护模式),每个 CPU 异常都有工作 中断描述符表 (IDT) 和 中断服务例程 (ISR)。 ISR 被成功调用,比如Division by Zero 异常。
global ir0
extern isr_handler
isr0:
cli
push 0x00 ; Dummy error code
push %1 ; Interrupt number
jmp isr_exc_handler
isr_exc_handler:
; Save the current processor state
pusha
mov ax, ds
push eax
mov ax, 0x10 ; Load kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; Push current stack pointer
mov eax, esp
push eax
call isr_handler ; Additional C/C++ handler function
pop eax ; Remove pushed stack pointer
pop ebx ; Restore original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa
add esp, 0x08 ; Clean up pushed error code and ISR number
sti
iret
问题是中断被一次又一次地抛出。结果,ISR 被一次又一次地调用。通过反复试验,我发现引发异常的行,
int x = 5 / 0,在循环中执行,因此 指令指针 (EIP) 不会递增。
当我手动增加推送到堆栈的 IP 值时,会发生预期的行为。 CPU 然后执行恶意代码行之后的下一条指令。当然是在 ISR 被调用一次之后。
对于我的实际问题:ISR 是否有必要增加 IP?或者这是“CPU/硬件”的责任?继续前进的正确行为是什么?
【问题讨论】:
-
由于这是一个例外,之前的 EIP 指向错误指令,如果您想继续,您必须自己更改它。硬件对此无能为力。通常代码将被终止,因此没有理由对其进行更改,并且有一个指向错误发生的实际位置的指针会更有用。
标签: assembly x86 intel interrupt osdev