更改为保护模式导致三重故障
Changing to protected mode causes triple fault
我一直有一个问题,在长时间跳转到保护模式后,似乎在设置 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
)?谢谢。
您的数据段描述符上有一个不正确的标志:10011010b
应该是 10010010b
。 Bit 3 应该是 0
表示一个数据段。
当您 mov
将一个值写入段寄存器时,它会检查它的有效性。将(可读的)代码段描述符移动到 DS
中是有效的(尽管不可取),只要您不尝试写入该段即可。但是,将该描述符移动到 SS
中是无效的,所以这是出错的指令。您可能遇到 #GP(0x10)
异常,它会级联成三重故障。
我一直有一个问题,在长时间跳转到保护模式后,似乎在设置 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
)?谢谢。
您的数据段描述符上有一个不正确的标志:10011010b
应该是 10010010b
。 Bit 3 应该是 0
表示一个数据段。
当您 mov
将一个值写入段寄存器时,它会检查它的有效性。将(可读的)代码段描述符移动到 DS
中是有效的(尽管不可取),只要您不尝试写入该段即可。但是,将该描述符移动到 SS
中是无效的,所以这是出错的指令。您可能遇到 #GP(0x10)
异常,它会级联成三重故障。