上一篇文章记录了如何进入保护模式,但是并没有展示保护模式的便利,例子也仅仅是打印了一个红色的字母P,这在实模式中也可以容易地完成,没有必要使用保护模式。所以这篇文章记录保护模式的便利以及实模式无法完成的任务。
实模式的寻址能力只有1MB,而保护模式下的寻址空间可以达到4GB,可以完成更多的任务,所以今天记录书上的例子第一个功能就是体验保护模式超过1MB内存的访问能力。
另外,上一篇文章记录的代码例子比较简单,进入保护模式之后就开始死循环,除了重启系统外没有其他办法。但实际上,在DOS下完全可以在程序结束时跳回实模式。所以记录例子的第二个功能就是从保护模式跳回到实模式。
整理一下,本篇文章记录保护模式进阶的实例代码,完成2个功能:
- 试验读写大地址内存。新建一个段,该段以5MB为基址。先读出开始处8字节的内容,然后写入一个字符串,再从中读出8字节。
- 实模式 --> 保护模式 --> 实模式。
在这里首先将该篇文章代码例子(pmtest2.asm)记录下来,然后再依次记录代码说明。
; ==========================================
; pmtest2.asm
; 编译方法:nasm pmtest2.asm -o pmtest2.com
; ==========================================
%include "pm.inc" ; 常量, 宏, 以及一些说明,使用的和上一篇文章是一个文件
org 0100h
jmp LABEL_BEGIN
[SECTION .gdt]
; GDT
; 段基址, 段界限 , 属性
LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW ; Normal 描述符
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32; 非一致代码段, 32
LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C ; 非一致代码段, 16
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW ; Data
LABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA+DA_32; Stack, 32 位
LABEL_DESC_TEST: Descriptor 0500000h, 0ffffh, DA_DRW
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
; GDT 结束
GdtLen equ $ - LABEL_GDT ; GDT长度
GdtPtr dw GdtLen - 1 ; GDT界限
dd 0 ; GDT基地址
; GDT 选择子
SelectorNormal equ LABEL_DESC_NORMAL - LABEL_GDT
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorCode16 equ LABEL_DESC_CODE16 - LABEL_GDT
SelectorData equ LABEL_DESC_DATA - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorTest equ LABEL_DESC_TEST - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
; END of [SECTION .gdt]
[SECTION .data1] ; 数据段
ALIGN 32
[BITS 32]
LABEL_DATA:
SPValueInRealMode dw 0
; 字符串
PMMessage: db "In Protect Mode now. ^-^", 0 ; 在保护模式中显示

最低0.47元/天 解锁文章
1203

被折叠的 条评论
为什么被折叠?



