Assembly 将CR0更改为启动保护模式时出现三重故障

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

我目前正在开发一个操作系统。我正在使用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"
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.