如何解决为什么这个引导扇区只能在 QEMU 中工作?
我已经做了大量的研究,也看过类似的问题,但我似乎找不到任何有用的东西。我对此很陌生,但我对汇编代码中发生的事情以及原因有很好的了解。
基本上,这里的引导扇区在 QEMU 中运行良好,但我的 PC 无法引导到它。它似乎陷入了一个循环,屏幕上只有闪烁的下划线。
MSG_REAL_MODE
和 MSG_PROT_MODE
都不会打印到屏幕上(或者如果有,它们会立即被清除)。
这个文件有几个不同的文件。我知道很多,对不起! 如果您需要澄清任何事情,请告诉我:)
boot.asm(主引导文件)
[org 0x7c00]
mov bp,0x9000
mov sp,bp
mov bx,MSG_REAL_MODE
call print_string
call switch_to_pm
jmp $
%include "f_print_string.asm"
%include "f_print_string_pm.asm"
%include "gdt.asm"
%include "f_switch_to_pm.asm"
[bits 32]
BEGIN_PM:
mov ebx,MSG_PROT_MODE
call print_string_pm
jmp $
MSG_REAL_MODE: db "Started in 16-bit Real Mode",0
MSG_PROT_MODE: db "Successfully landed in 32-bit Protected Mode",0
times 510-($-$$) db 0
dw 0xaa55
f_print_string.asm(用于在 16 位实模式下打印字符串)
print_string:
pusha
string_loop:
mov al,[bx]
cmp al,0
jne print_char
popa
ret
print_char:
mov ah,0x0e
int 0x10
add bx,1
jmp string_loop
f_print_string_pm.asm(用于在 32 位保护模式下打印字符串)
[bits 32]
VIDEO_MEMORY equ 0xb8000
WHITE_ON_BLACK equ 0x0f
print_string_pm:
pusha
mov edx,VIDEO_MEMORY
print_string_pm_loop:
mov al,[ebx]
mov ah,WHITE_ON_BLACK
cmp al,0
je print_string_pm_done
mov [edx],ax
add ebx,1
add edx,2
jmp print_string_pm_loop
print_string_pm_done:
popa
ret
gdt.asm(用于设置 GDT 和 GDT 描述符,注释以便更好理解)
; GDT
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_code:
; base=0x0,limit=0xfffff
; 1st flags: (present)1 (privilege)00 (descriptor type)1 -> 1001b
; type flags: (code)1 (conforming)0 (readable)1 (accessed)0 -> 1010b
; 2nd flags: (granularity)1 (32-bit default)1 (64-bit seg)0 (AVL)0 -> 1100b
dw 0xffff ; Limit (bits 0-15)
dw 0x0 ; Base (bits 0-15)
db 0x0 ; Base (bits 16-23)
db 10011010b ; 1st flags (4 bits) and type flags (4 bits)
db 11001111b ; 2nd flags (4 bits) and limit (4 bits)
db 0x0 ; Base (bits 24-31)
gdt_data:
; Same as code segment except for the type flags:
; type flags: (code)0 (expand down)0 (writable)1 (accessed)0 -> 0010b
dw 0xffff ; Limit (bits 0-15)
dw 0x0 ; Base (bits 0-15)
db 0x0 ; Base (bits 16-23)
db 10010010b ; 1st flags (4 bits) and type flags (4 bits)
db 11001111b ; 2nd flags (4 bits) and limit (4 bits)
db 0x0 ; Base (bits 24-31)
gdt_end:
; GDT descriptor
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
f_switch_to_pm.asm(用于切换到 32 位保护模式)
[bits 16]
switch_to_pm:
cli
lgdt [gdt_descriptor]
mov eax,cr0
or eax,0x1
mov cr0,eax
jmp CODE_SEG:init_pm
[bits 32]
init_pm:
mov ax,DATA_SEG
mov ds,ax
mov ss,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ebp,0x90000
mov esp,ebp
call BEGIN_PM
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。