assembly - 更改为保护模式会导致三重故障
问题描述
我一直遇到一个问题,在长时间跳转到保护模式后,似乎在设置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
. 第 3 位应该是0
表示一个数据段。
当您mov
将值放入段寄存器时,它会检查它的有效性。DS
只要您不尝试写入该段,将(可读)代码段描述符移动到 中是有效的(尽管不是可取的) 。但是,将该描述符移入 是无效的SS
,因此这就是出错的指令。你可能会遇到一个#GP(0x10)
异常,它会级联成三重故障。
推荐阅读
- python - re.match 和 Path.match 之间的区别
- spring-boot - SpringBOOT:在 API 中保存对象
- javascript - 使用实践使用组件库(mui + react)
- javascript - 循环遍历数组并为每个元素运行 Jest 测试不起作用
- jupyter-notebook - 即使在安装后,Spyder ide 中也缺少 Jupyter 笔记本视图
- javascript - 使用 swiperjs React 时出错 - `请求的模块 'react' 应该是 CommonJS 类型`
- macos - 在 Automator 中批量调整选定图像的大小
- python - 必须是结构化数组,第一个字段是二进制类 RandomSurvivalForest
- java - Spring代理:BeanPostProcessor还是AOP?
- php - DynamodbClient 在连接时返回空对象