我尝试使用kolibri引导程序执行简单内核。 它被加载到1000:0000。 我不明白,这部分有什么问题:
...
; switch to PM
mov eax, cr0
or al, 1
mov cr0, eax
use32
PROTECTED_ENTRY:
mov ax, 00010000b ; DATA
mov ds, ax
mov ss, ax
mov esp, 0xFFFF
jmp $
mov ax, 00011000b ; VIDEO
mov es, ax
mov edi, 0
mov esi, string
int 1
jmp $
'因为在调试器中它看起来像这样
这里发生了什么?为什么ES和DS没有被改变?
P.S。我正在尝试使用kolibri加载器使用此内核: http://wasm.ru/article.php?article=ia32int
答案 0 :(得分:3)
在cr0
中设置受保护位时,处理器不会自动进入保护模式。在此之后更改cs
时,它会进入保护模式。最简单的方法是在写入cr0
后立即插入远跳。
mov cr0, eax
.db 066h
jmp CODE_SEGMENT:PROTECTED_ENTRY
use32
PROTECTED_ENTRY:
希望我做对了。 (我习惯于AT& T语法。).db
是一个操作数大小覆盖,允许32位地址。
答案 1 :(得分:2)
Tee调试器会将32位代码(您告诉汇编器生成带有use32
伪操作的32位代码)作为16位代码进行反汇编。因此,指令mov ax, 10h
被解释为mov eax, d88e0010h
,其中d88e
部分实际上是下一条指令{/ 1}}的操作码。
类似于mov ds,ax
,其被解释为mov esp, 0xffff
,另外两个零字节显示为虚假mov sp, 0xffff
指令。
处理器实际执行的内容取决于其当前状态 - 是处于保护模式,实模式,平面模式等。查看状态寄存器以查找。可能你可以告诉调试器解释不同的代码。