Assembly 将CR0更改为启动保护模式时出现三重故障
我目前正在开发一个操作系统。我正在使用VMWare来模拟它。我在每一行上使用Assembly 将CR0更改为启动保护模式时出现三重故障,assembly,x86,nasm,32-bit,osdev,Assembly,X86,Nasm,32 Bit,Osdev,我目前正在开发一个操作系统。我正在使用VMWare来模拟它。我在每一行上使用int 0x16进行调试,发现当我将受保护模式开关CR0切换到1时,它只会出现三重故障。下面是内核加载程序的第2阶段: bits 16 org 0x500 jmp main %include "stdio.inc" %include "Gdt.inc" %include "A20.inc" %include "Fat12.inc" %include "common.inc" Lo
int 0x16
进行调试,发现当我将受保护模式开关CR0
切换到1时,它只会出现三重故障。下面是内核加载程序的第2阶段:
bits 16
org 0x500
jmp main
%include "stdio.inc"
%include "Gdt.inc"
%include "A20.inc"
%include "Fat12.inc"
%include "common.inc"
LoadingMsg db "Please Wait . . .", 0x0D, 0x0A, 0x00
msgFailure db 0x0D, 0x0A, "Can't find Krnl. Press any key to retry", 0x0D, 0x0A, 0x0A, 0x00
main:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ax, 0x9000
mov ss, ax
mov sp, 0xFFFF
sti
call InstallGDT
call EnableA20_KKbrd_Out
mov si, LoadingMsg
call Puts16 ; nuts61
jmp EnterKernel
mov ah, 0
int 0x16
int 0x19
cli
hlt
EnterKernel:
cli
mov eax, cr0
or eax, 1
mov cr0, eax ; <= here is the damn triple fault
jmp CODE_DESC:KernelC
bits 32
KernelC:
mov ax, DATA_DESC
mov ds, ax
mov ss, ax
mov es, ax
mov esp, 90000h
CopyImage:
mov eax, dword [ImageSize]
movzx ebx, word [bpbBytesPerSector]
mul ebx
mov ebx, 4
div ebx
cld
mov esi, IMAGE_RMODE_BASE
mov edi, IMAGE_PMODE_BASE
mov ecx, eax
rep movsd
jmp CODE_DESC:IMAGE_PMODE_BASE
cli
hlt
我如何解决这个问题?有什么建议吗?您可能想看一下作为参考。您确实知道,当您使用单操作数div(如
div ebx
时,红利在edx:eax中。我看不到您将edx归零。您可以在设置eax后立即使用cwd
指令或xor edx、edx
。用SHR指令右移2位也可以除以4。无论如何,如果没有一个最小的完整的可验证示例,很难判断错误。这是高级编程,先学会调试。特别是因为我不知道在中断被禁用的情况下,mov
会发生什么故障。在您采取其他措施之前,仅启用保护不应该是一个问题。下一个jmp
是一个更好的故障候选,可能是由于地址错误。您还提到我是通过在每一行上使用int 0x16进行调试的。如果您在切换到保护模式后放置了一个int 0x16
,并试图调用realmode BIOS中断,那么这本身就可能是问题的根源。您可能想查看一下作为参考。您确实知道,当您使用单操作数div(如div ebx
)时,红利在edx:eax中。我看不到你把edx调零了。您可以在设置eax后立即使用cwd
指令或xor edx、edx
。用SHR指令右移2位也可以除以4。无论如何,如果没有一个最小的完整的可验证示例,很难判断错误。这是高级编程,先学会调试。特别是因为我不知道在中断被禁用的情况下,mov
会发生什么故障。在您采取其他措施之前,仅启用保护不应该是一个问题。下一个jmp
是一个更好的故障候选,可能是由于地址错误。您还提到我是通过在每一行上使用int 0x16进行调试的。如果您在切换到保护模式后放置了一个int 0x16
,并试图调用realmode BIOS中断,那么这本身可能就是问题的根源。
2016-01-14T17:30:00.613+01:00| vcpu-0| I120: Triple fault.
2016-01-14T17:30:00.613+01:00| vcpu-0| I120: MsgHint: msg.monitorEvent.tripleFault
2016-01-14T17:30:00.613+01:00| vcpu-0| I120+ A fault has occurred causing a virtual CPU to enter the shutdown state. If this fault had occurred outside of a virtual machine, it would have caused the physical machine to restart. The shutdown state can be reached by incorrectly configuring the virtual machine, a bug in the guest operating system, or a problem in VMware Player.