x86 程序集:如何重写中断?

x86 assembly: How can i rewrite an interrupt?

我正在尝试将 0h 中断(除以零)重写为我制作的自定义标签,它应该打印我制作的自定义消息,而不是模拟器抛出的正常异常。

我还没有设法找到一个很好的资源来以一种好的和易于理解的方式解释所有这些东西,所以我的代码显然在我第一次制作它时不起作用。我发现了这个 post:Is it possible to make a custom Interrupt in Assembly? 但我还是很困惑。

org 100h


jmp main


main:
    xor ax, ax
    mov es, ax    
    CLI
    mov bx, offset divideByZero
    mov es:[0h], bx 
    add bx, 2
    mov ax, cx
    mov es:[bx], ax 
    STI


    mov ax, 10
    mov bx, 0
    div bx

    mov ah, 0
    int 16h
    ret

divideByZero:
    push bp 
    mov bp, sp 

    PRINTN "Error: Divide By Zero Can Break The Universe" 

    pop bp
    iret

有人可以向我解释一下如何像我尝试的那样创建自己的中断吗?它是如何工作的?

您设置中断向量的代码中存在一些错误。 add bx,2完全没有必要,mov ax,cx应该是mov ax,csmov es:[bx],ax应该是mov es:[2],ax

我还要提到的是,虽然最初的 8086(和 EMU8086)在发生被零除(或溢出)时将指令的地址压入除法之后,但在后来的芯片上 return地址将与刚刚出错的 div 指令相同。因此,在这些后来的芯片上,当您执行 iret 时,您将返回到 div bx 并触发另一个除以零。然后处理程序要么需要中止进程(简单),要么在执行 iret(困难)之前对保存的寄存器 and/or return 地址进行适当的更改。