2

我尝试使用 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 没有被改变?

PS我试图让这个内核与kolibri loader一起工作: http ://wasm.ru/article.php?article=ia32int

4

2 回答 2

3

当您在 中设置保护位时,处理器不会自动进入保护模式cr0cs之后更改时进入保护模式。最简单的方法是在写入后立即插入一个远跳转cr0

mov cr0, eax
.db 066h
jmp CODE_SEGMENT:PROTECTED_ENTRY

use32
PROTECTED_ENTRY:

希望我做对了。(我习惯于 AT&T 语法。)这.db是一个允许 32 位地址的操作数大小覆盖。

于 2012-01-16T19:03:27.830 回答
2

Tee 调试器确实将 32 位代码(您告诉汇编器使用use32伪操作生成 32 位代码)反汇编为 16 位代码。因此该指令mov ax, 10h被解释为mov eax, d88e0010h,其中该d88e部分实际上是下一条指令的操作码,mov ds,ax

与 for 类似mov esp, 0xffff,它被解释为mov sp, 0xffff并且两个额外的零字节显示为虚假add byte ptr...指令。

处理器实际执行的内容取决于其当前状态——它是处于保护模式、实模式还是平坦模式等。查看状态寄存器以找出答案。可能您可以告诉调试器以不同的方式解释代码。

于 2012-01-16T18:17:17.043 回答