【问题标题】:Changing to protected mode causes triple fault更改为保护模式会导致三重故障
【发布时间】:2021-08-09 20:13:34
【问题描述】:

我一直遇到一个问题,在长时间跳转到保护模式后,似乎在设置ss 寄存器时,会导致三重故障。我的代码:

switch-to-32bit.asm

[org 0x7c00]
[bits 16]
switch_to_32bit:
    cli
    lgdt [gdt_descriptor]
    mov eax, cr0
    or eax, 0x1 ; protected mode
    mov cr0, eax
    jmp CODE_SEG:init_32bit ; far jump

[bits 32]
init_32bit:
    mov ax, DATA_SEG ; 0x1000
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000 ; setup stack
    mov esp, ebp

    call BEGIN_32BIT

gdt.asm

gdt_start:
    dq 0x0

gdt_code:
    dw 0xffff ; segment length
    dw 0x0 ; segment base
    db 0x0 ; segment base
    db 10011010b ; flags 
    db 11001111b ; flags
    db 0x0 ; segment base

gdt_data:
    dw 0xffff ; segment length
    dw 0x0 ; segment base
    db 0x0 ; segment base
    db 10011010b ; flags 
    db 11001111b ; flags
    db 0x0 ; segment base

gdt_end:

gdt_descriptor:
    dw gdt_end - gdt_start - 1
    dd gdt_start

CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start

使用bochs 运行此程序时,控制台中会出现许多调试行,如下所示:

有谁知道为什么设置ss 寄存器会导致这个问题?或者如果问题更深(我看到SS.mode = 16 bit)?谢谢。

【问题讨论】:

  • 所示代码将SS 加载为零。这显然是行不通的。如果您改为使用DATA_SEG 加载它(根据注释掉的代码),您会崩溃吗?
  • 哎呀我应该删除它,这只是我试图调试问题而不是故意的。
  • 同时更新 bochs 屏幕截图,因为它仍然显示将空选择器加载到 SS

标签: assembly x86 protected-mode


【解决方案1】:

您的数据段描述符上有一个不正确的标志:10011010b 应该是 10010010b。第 3 位应该是0 表示一个数据段。

当您将mov 值放入段寄存器时,它会检查它的有效性。只要您不尝试写入该段,将(可读)代码段描述符移动到DS 是有效的(尽管不是可取的)。然而,将该描述符移入SS 是无效的,因此这就是出错的指令。您可能会遇到#GP(0x10) 异常,它会级联成三重故障。

【讨论】:

  • 非常感谢,真不敢相信我错过了这个!
猜你喜欢
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 1970-01-01
  • 2021-09-23
  • 2011-06-26
  • 2021-12-25
相关资源
最近更新 更多