64位模式下mov es, ax致虚拟机崩溃,像素输出失效求助
64位模式下
mov es, ax指令引发虚拟机崩溃问题 为简化开发直接切换到64位模式,但在尝试输出像素时,mov es, ax指令导致虚拟机崩溃,这是像素输出代码的关键环节。发现代码初始阶段存在分页设置的痕迹,目前完全困惑。
我的目标是打造无BIOS、多平台且基本兼容所有设备的系统,若代码已预设分页设置将大幅简化开发,后续只需实现全显示器兼容、键鼠检测功能即可(已为此开发一门语言,因篇幅较长未附上)。
相关代码如下:
%define FREE_SPACE 0x9000 ORG 0x7C00 [bits 16] mov ax,115h ; init 800x600 32bit mov bx,ax mov ax,4f02h int 16 Main: jmp 0x0000:.FlushCS .FlushCS: xor ax, ax mov ss, ax mov sp, Main mov ds, ax mov es, ax mov fs, ax mov gs, ax cld call CheckCPU jc nlm mov edi, FREE_SPACE jmp SwitchToLongMode nlm: BITS 16 %define PAGE_PRESENT (1 << 0) %define PAGE_WRITE (1 << 1) %define CODE_SEG 0x0008 %define DATA_SEG 0x0010 ALIGN 4 IDT: .Length dw 0 .Base dd 0 SwitchToLongMode: push di mov ecx, 0x1000 xor eax, eax cld rep stosd pop di lea eax, [es:di + 0x1000] or eax, PAGE_PRESENT | PAGE_WRITE mov [es:di], eax lea eax, [es:di + 0x2000] or eax, PAGE_PRESENT | PAGE_WRITE mov [es:di + 0x1000], eax lea eax, [es:di + 0x3000] or eax, PAGE_PRESENT | PAGE_WRITE mov [es:di + 0x2000], eax push di lea di, [di + 0x3000] mov eax, PAGE_PRESENT | PAGE_WRITE .LoopPageTable: mov [es:di], eax add eax, 0x1000 add di, 8 cmp eax, 0x200000 jb .LoopPageTable pop di mov al, 0xFF out 0x21, al nop nop lidt [IDT] mov eax, 10100000b mov cr4, eax mov edx, edi mov cr3, edx mov ecx, 0xC0000080 rdmsr or eax, 0x00000100 wrmsr mov ebx, cr0 or ebx,0x80000001 mov cr0, ebx lgdt [GDT.Pointer] jmp CODE_SEG:LongMode GDT: .Null: dq 0x0000000000000000 .Code: dq 0x00209A0000000000 dq 0x0000920000000000 ALIGN 4 dw 0 .Pointer: dw $ - GDT - 1 dd GDT [BITS 64] LongMode: mov ax, DATA_SEG mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ; ------------------------------- mainl0: mov ax,10 mov bx,10 mov ecx,00000000111111111111111110001000b ;color l0: ;edx : y edx : x mov eax, 800 mov edx, 1 imul edx add eax, edx add eax, edx mov edx, 3 imul edx add eax, edx mov di,ax ; di = eax % FFFFh (offset) mov ax,0A000h ; es = A000h mov es,ax ;crash <---- mov eax,ecx stosd jmp l0 hlt lol: jmp lol [bits 16] CheckCPU: pushfd pop eax mov ecx, eax xor eax, 0x200000 push eax popfd pushfd pop eax xor eax, ecx shr eax, 21 and eax, 1 push ecx popfd test eax, eax jz nlm mov eax, 0x80000000 cpuid cmp eax, 0x80000001 jb nlm mov eax, 0x80000001 cpuid test edx, 1 << 29 jz nlm ret times 510 - ($-$$) db 0 dw 0xAA55
内容的提问来源于stack exchange,提问作者Xulum12
相关产品推荐
相关产品推荐

