我试图切换到保护模式后,玩了一点真正的模式,但奇怪的事情发生了。在真实的模式下,我创建了一个简单的欢迎屏幕,要求用户输入他们的名字。之后,应该会切换到保护模式,但实际上是这样的:
的数据
正如您所看到的,我按下Enter键,字符的背景开始改变,然后QEMU(我正在使用的模拟器)重新启动并重新显示欢迎屏幕。
代码如下:
section startUp vstart=0x7f00
; clearing the screen
mov ah,0x00
mov al,0x03
int 0x10
; disabling the cursor
mov ah,0x01
mov ch,0x3f
int 0x10
; using Bios to print character
mov ah,0x0e
mov al,'C'
mov cx,0x01
int 0x10
; printing a string
mov ax,msg
mov bx,0x00
mov cl,0x0f
mov dx,0x00
call printMsg
; print warning
mov ax,warning
mov bx,0x00
mov cl,0x04
mov dx,0x3a
call printMsg
; print message
mov ax,msg2
mov bx,0x00
mov cl,0x0f
mov dx,0x0140
call printMsg
; input
mov si,keypress
mov bx,0x00
call input
; switching to protected mode
cli ; disabling interrupts
lgdt [GDT_Descriptor]
mov eax,cr0
or eax,0x01
mov cr0,eax ; here we are in 32 bit protected mode
jmp protectedMode
; printing a string function
printMsg:
pusha
; ax ==> offset , bx ==> segment , dl ==> Line a0*lineNumber - 1, cl ==> color
mov es,bx
mov bx,0xB000
mov ds,bx
mov si,ax
mov di,0x8000
add di,dx
mov byte[es:0x7e00],0x00
jmp loopThrough
loopThrough:
mov al,byte[es:si]
mov byte[ds:di], al
add di,0x01
mov byte[ds:di],cl
sub di,0x01
add si,0x01
mov bl,byte[es:si]
cmp bl,0x00
je quit
add di,0x02
jmp loopThrough
quit :
popa
ret
; input function kjjj
input:
pusha
; si ==> offset , bx ==> segment
mov di,si
mov es,bx
jmp loopinterupt
loopinterupt :
mov ah,0x00
int 0x16
cmp al,0x20
je quitInput
mov byte[es:si],al
add si,0x01
mov byte[es:si],0x00
mov ax,di
mov dx,0x172
mov cl,0x0f
call printMsg
jmp loopinterupt
quitInput :
popa
ret
; Data
; Setting Up the GDT
GDT :
times 8 db 0x00
; base : 0x100000 ; Limit : 0x00700
dw 0x0700 ; limit 1
dw 0x0000 ; base 1
db 0x10 ; base 2
db 0x9a ; access Byte
db 0xc0 ; limit + flags
db 0x00d ; base 3
; base : 0x800000 ; limit : 0x00700
dw 0x0700 ; limit 1
dw 0x0000 ; base 1
db 0x80 ; base 2
db 0x96 ; access Byte
db 0xc0 ; limit + flags
db 0x00 ; base 3
GDT_Descriptor :
dw GDT_Descriptor - GDT - 1
dd GDT
msg db 'Welcome to the OS fdffdfgd',0x00
msg2 db 'Please write your name : ',0x00
keypress db 'K',0x00
warning db ""
[bits 32]
protectedMode:
jmp $
times 1024-($-$$) db 0
字符串
因此,正如您所看到的,在执行jmp protectedMode
之前,代码执行得很好。
1条答案
按热度按时间dy1byipe1#
在Protected Mode guide on OSDev之后,可以看到涉及到3个步骤。
1.禁用中断
您在代码中使用
cli
指令正确地做到了这一点。1.使能A20门
由于horrible history,硬件在访问内存时清除每个地址的位20。您很可能不希望这样,因为这意味着您的地址空间有一半无法访问。关于如何禁用此行为的完整指南在OSDev上,但只是为了在QEMU上进行快速测试,这应该可以工作:
字符串
1.创建并加载GDT
如果要切换到32位保护模式,您最可能希望以以下两个段描述符开头:代码和数据。由于您可能希望访问完整的4GB地址空间,因此应该为它们指定0基址和4GB限制。因此,它们之间唯一不同的位是代码/数据位:
型
这些段将允许您使用32位寄存器(如
eax
)来寻址高达4GB标记的任何内存位置。最后,确保您实际上正在使用这些段(通过将它们加载到段寄存器中),否则可能会导致纯粹的混乱。
全模式切换代码:
型