标签: 80286

为什么在尝试处理286而不是现代CPU或Bochs上的异常时出现三重错误?

我正在尝试通过AMD 286系统上的异常处理来初始化保护模式。我已经在Bochs上调试了以下代码,并且在这里可以正常工作。在奔腾4机器上运行时也是如此。但是在286上,当到达int3指令时,它只是三重故障。可以观察到的行为是:如果我注释掉了int3,则会无限期地在屏幕上显示“ OK”,而按原样使用代码,则系统将重新启动。

该代码将由FASM编译,并将二进制文件放入HDD或FDD的引导扇区中。我实际上是从1.4M软盘运行它。

 org 0x7c00
 use16

 CODE_SELECTOR     = code_descr - gdt
 DATA_SELECTOR     = data_descr - gdt

    ; print "OK" on the screen to see that we've actually started
    push     0xb800
    pop      es
    xor      di,di
    mov      ax, 0x0700+'O'
    stosw
    mov      ax, 0x0700+'K'
    stosw
    ; clear the rest of the screen
    mov      cx, 80*25*2-2
    mov      ax, 0x0720
    rep stosw

    lgdt     [cs:gdtr]
    cli
    smsw     ax
    or       al, 1
    lmsw     ax
    jmp      CODE_SELECTOR:enterPM
enterPM:
    lidt     [idtr]
    mov      cx, DATA_SELECTOR …
Run Code Online (Sandbox Code Playgroud)

x86 assembly protected-mode interrupt-handling 80286

6
推荐指数
1
解决办法
87
查看次数

装配说明:AAA

我正在看伪代码:BCD指令的隐藏能力.以下是该网站内容的片段:

那么,让我们来看看AAA的作用.这是伪代码等价物(来自英特尔):

   IF ((AL AND 0FH) > 9) OR (AF = 1)
    THEN
            AL = (AL + 6) AND 0FH;
            AH = (AH + 1);
            AF = 1;
            CF = 1;
    ELSE
            AF = 0;
            CF = 0;
    FI;enter code here
Run Code Online (Sandbox Code Playgroud)

对于像这样的典型英特尔文档兼容用途,这是正确的:

    mov     al,6
    add     al,9    ;al=15=0Fh
    aaa             ;al=21=15h  =>  it's in decimal!
Run Code Online (Sandbox Code Playgroud)

上面的算法似乎没有在代码中给出结果,所以我假设这里省略了一些步骤.评论说明如下:"al = 21 = 15h =>它是十进制的!".

我对代码的解释如下:

  • 在add指令之后,存储在AL寄存器中的值将为15(0Fh).
  • 由于它大于10,因此将向该值添加6,并且使用0Fh进行AND运算,这将导致1s值存储在AL寄存器中("AL =(AL + 6)AND 0FH;").AL寄存器的值现在应为05h.
  • 算法在AH寄存器中加一个,我假设是寄存器,因为我们对AL寄存器进行了ANDed和归零4位("AH =(AH + 1);").

但是,在运行"AH =(AH + 1);"行之前,没有提到存储在AH寄存器中的值.如果它被初始化为零,它只适用于20以下的数字.现在我们假设它被初始化为零,我希望结果存储为AH = 1和AL = 5,但评论说"; …

x86 assembly bcd x86-16 80286

5
推荐指数
1
解决办法
1263
查看次数

标签 统计

80286 ×2

assembly ×2

x86 ×2

bcd ×1

interrupt-handling ×1

protected-mode ×1

x86-16 ×1