您的位置:首页 > 其它

一个操作系统的实现:保护模式

2011-09-06 19:34 281 查看
今天学习了保护模式,依据书上的内容以及大灰狼老师的视频,终于完成自己写的保护模式。

[BITS 16] ;表示以下为段位16位

org 07c00h ;这是由于系统会将代码加载到7C00处

jmp start

gdt_table_start:

gdt_null:

dd 0h

dd 0h ;Intel 规定描述符表的第一个描述符必须为空描述符

gdt_data_addr equ $-gdt_table_start

gdt_data:

dw 07FFh ;数据段的界值,一个数据段、代码段规定为8M大小

dw 0h ;段基址的0~18位

db 0h ;段基址的19~23位

db 10010010b ;第一个1,表示P,是描述符对地址的转换是否有效,有效为1

;第二个1,表示DT,表示是系统段还是存储段,为1表示系统段

;第三个1,与0010一起表示type类型,即是可读可写的数据段还是可读可执行的代码段

;段属性的第六字节

db 11000000b ;第一个1,表示是数据段大小4G,为0则表示64K;代码段是32位,为0则表示16位

;第二个1表示段界限粒度为字节,0则表示为4K

;段属性的第七字节

db 0h ;基地址

gdt_code_addr equ $-gdt_table_start

gdt_code:

dw 07FFh ;代码段的界值,一个数据段、代码段规定为8M大小

dw 1h ;段基址的0~18位

db 80h ;段基址的19~23位

db 10011010b ;第一个1,表示P,是描述符对地址的转换是否有效,有效为1

;第二个1,表示DT,表示是系统段还是存储段,为1表示系统段

;第三个1,与1010一起表示type类型,即是可读可写的数据段还是可读可执行的代码段

;段属性的第六字节

db 11000000b ;第一个1,表示是数据段大小4G,为0则表示64K

;第二个1表示代码段是32位,为0则表示16位

;段属性的第七字节

db 0h ;基地址

gdt_video_addr equ $-gdt_table_start

gdt_video:

dw 01FFh ;代码段的界值,可以为任意值

dw 8000h ;段基址的0~18位

db 0Bh ;段基址的19~23位

db 10010010b ;第一个1,表示P,是描述符对地址的转换是否有效,有效为1

;第二个1,表示DT,表示是系统段还是存储段,为1表示系统段

;第三个1,与1010一起表示type类型,即是可读可写的数据段还是可读可执行的代码段

;段属性的第六字节

db 11000000b ;第一个1,表示是数据段大小4G,为0则表示64K

;第二个1表示代码段是32位,为0则表示16位

;段属性的第七字节

db 0h ;基地址

gdt_table_end:

gdtr_addr:

dw gdt_table_end-gdt_table_start-1 ;段描述符表长度,GDTR寄存器为48位

dd gdt_table_start ;段描述符表基地址

start:

;初始化数据段描述符

xor eax , eax

mov eax , data_32

mov word [gdt_data+2] ,ax

shr eax , 16

mov byte [gdt_data+4] , al

mov byte [gdt_data+7] ,ah

;初始化代码段描述符

xor eax , eax

mov eax , code_32

mov word [gdt_code+2] ,ax

shr eax , 16

mov byte [gdt_code+4] , al

mov byte [gdt_code+7] ,ah

;关闭中断向量表,相当于删除以前的16位中断向量表,为装入32位中断向量表做准备

cli

;加载GDT描述表的大小和基地址放入gdtr寄存器

lgdt [gdtr_addr]

;打开A20地址线,以便能够访问超过1M的地址内存

in al , 92h

or al ,00000010b

out 92h , al

;打开保护模式允许

mov eax , cr0

or eax ,1

mov cr0 , eax

;跳转到保护模式下的32位地址处

jmp gdt_code_addr:0

[BITS 32]

data_32:

dd "my os!"

code_32:

mov ax , gdt_data_addr

mov ds , ax

mov ax , gdt_video_addr

mov gs ,ax

mov edi ,(80*20+30)*2 ;在屏幕第20行第30列处显示数据my os!

mov ah , 0ch ;黑底红字

mov bx ,0

mov cx ,6

s:

mov al , [ds:bx]

mov [gs:edi] , al

mov [gs:edi+1] , ah

inc bx

add edi ,2

loop s

jmp $

times 510-($-$$) db 0

dw 0aa55h
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐