一个操作系统的实现:保护模式
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
[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
相关文章推荐
- 《Orange’s 一个操作系统的实现》3.保护模式5----特权级概述(转)
- 《一个操作系统的实现》阅读笔记 之 保护模式
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3-b)
- 《Orange's 一个操作系统的实现》读书手记3(1)--- [ 保护模式(Protect Mode)]
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-理论)
- 一个操作系统的实现:关于保护模式和实模式的跳转和段描述符高速缓冲寄存器
- 《一个操作系统的实现》(三):1.认识保护模式
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-理论)
- 《Orange's 一个操作系统的实现》学习笔记--实践认识保护模式
- 一个操作系统的实现-5_保护模式4
- 《一个操作系统的实现》(三):4.中断和异常&5.保护模式下的I/O
- 《Orange’s 一个操作系统的实现》3.保护模式4----LDT(Local Descriptor Table)
- 《Orange’s 一个操作系统的实现》3.保护模式5----特权级概述(转)
- 《Orange’s 一个操作系统的实现》3.保护模式6-特权级转移(门描述符概述)
- 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-有特权级转换-进入ring3)
- 学习笔记:一个操作系统的实现--保护模式之基础知识
- 《Orange’s 一个操作系统的实现》3.保护模式1----pm.inc分析
- 《Orange’s 一个操作系统的实现》3.保护模式8-页式存储(启动分页机制)
- 一个操作系统的实现:第三章 保护模式 调试问题