内存管理与保护模式_第1页
内存管理与保护模式_第2页
内存管理与保护模式_第3页
内存管理与保护模式_第4页
内存管理与保护模式_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、内存管理与保护模式本实验讨论x86采用的内存管理模式:从分段实模式到分段保护模式,再到分页虚拟内存管理,并介绍进入保护模式、启动分页机制、以及获取内存大小的基本方法。1 x86的内存管理内存的分段(segmentation)管理符合程序的逻辑结构,利于程序的保护和动态控制。分页(paging)则最适合虚拟内存的管理需要。目前主流操作系统的内存管理采用的是分页方法(如类Unix),也有采用段页式的(如Wiondows)。Intel 8086支持不带保护功能的分段内存管理,80286开始引入带保护功能的分段内存管理,80386又引入了支持虚拟内存的分页内存管理,但其分页是建立在分段基础上的。IA-

2、32和x64处理器,都支持段页式内存管理。1.1 实模式Intel的16位处理器8086,采用的是分段内存管理,CPU中有CS、DS、SS和ES四个16位段寄存器,作为基地址,分别用于生成代码、数据、堆栈和其他段的物理地址:20位物理地址 = 16位段寄存器值*16(或左移4位) + 16位偏移量寻址空间只有(220=)1MB,最大段长为(216=)64KB。因为这样的CPU只能生成和访问真实的物理内存地址,所以被称为实地址模式(real-address mode),简称为实模式(real mode)。不过这种分段方法并不是现代的分段技术,没有提供任何内存保护功能,不能阻止内存的越界访问。而且

3、8086 CPU也没有提供任何特权分级,谁都可以任意改变CS、DS和SS寄存器中的值,从而可以执行/访问内存任何地址的指令/数据,完全没有安全可言。因此在8086 CPU上,是不可能构建现代操作系统的。1.2 保护模式1982年推出的16位的80286处理器,在x86体系中首次引入了(分段式的)内存保护机制,称之为保护模式(protected mode)。不过80286的保护模式只支持24位的地址空间(最多只能访问16MB内存)和16位的界限大小(最大段长为216=64KB或216+8=224=16MB),且只能从实模式进入保护模式,而不能从保护模式返回实模式。1985年推出的32位的8038

4、6处理器,其保护模式支持32位的地址空间,寻址空间达到(232=)4GB。但是为了与分段式的8086兼容,80386并没有使用简单的线性地址空间,而是采用了基于分段的分页内存管理方法(其中的分页管理是80386新增加的)。这里的分段是必须的,分页则是可选的。1分段分段将处理器可寻址的内存空间(称为线性地址空间)划分为较小的受保护的地址空间(称为段),段可用于容纳程序的代码、数据和堆栈,或系统的数据结构(如TSS或LDT)。可以为每个运行的程序指派各自的段集。分段机制还允许将段分类,从而可限制在某个特定段类上能够执行的操作。为了定位特定段中的字节,必须提供一个逻辑地址(也称为远指针),它包含一个

5、段选择符和一个偏移量。段选择符是段唯一的标识符,它提供段描述符在描述符表中的偏移量。段描述符指定段的大小、访问权限和特权级、段类型、段在线性地址空间中的起始地址(基址)。段的基址+偏移量=处理器线性地址空间中的线性地址。2分页如果不使用分页,则IA-32处理器的线性地址空间直接映射到处理器的物理地址空间,不支持虚拟内存管理。对IA-32处理器,只有分页机制才支持虚拟内存,使处理器的线性地址空间可以大于内存的物理地址空间。但是IA-32处理器的分页是建立在分段的基础之上的,即IA-32处理器采用的是段页式内存管理方法。在使用分页管理时,每个段被分成若干等长的页(对IA-32处理器,典型的页帧大小

6、是4KB),这些页可以存放在内存中,也可以存放在磁盘上(即支持虚拟内存)。当程序或任务试图访问线性地址空间中的地址位置时,处理器利用页目录和页表,将线性地址转换为物理地址。为了节省内存空间,IA-32处理器采用的是两级分页方式。如果采用单级分页,对4KB(=212)页帧大小和4GB地址空间,需要1M(=220)个表项,每个表项4B则整个页表就需要4MB空间。由于一般的进程并不需要使用整个4GB的空间,所以大多数表项都空着的,非常浪费。如果采用二级分页,一级为页目录(Page Directory,PD),有(210=)1024个页目录项(Page Directory Entry,PDE)。每个页

7、目录项指向一个二级页表(Page Table,PT),它也有(210=)1024个页表项(Page Table Entry,PTE),总共也是(1024*1024=220=)1M个页。但对空页目录项,不必创建其对应的页表,可以节省空间。31222112110页目录项序号dir页表项序号table页帧内偏移量offset4KB分页时的线性地址格式311211109876543210页表起始物理地址的高20位IgnoredPSIgnAPCDPWTU/SR/WP4KB分页时的PDE(页目录项)格式其中:l P = Present存在(=0:不在内存中,其余各位忽略、=1:在内存中,其余各位有意义)l

8、 R/W = Read / Write读/写(=0:只读、=1:可写)l U/S = User / Supervisor用户/超级管理员(=0:系统权限、=1:用户权限)l PWT = Page-level Write-Through页级直接写l PCD = Page-level Cache Disable页级禁用缓存l A = Accessed访问过(0:未访问过、1:已访问过)l Ign = Ignored被忽略l PS = Page Size页大小(0:4KB、1:4MB)l Ignored被忽略311211109876543210页帧起始物理地址的高20位IgnoredGPATDAPC

9、DPWTU/SR/WP4KB分页时的PTE(页表项)格式其中:l D = Dirty脏(即对应页被软件改写过)(0:未脏、1:已脏)l PAT = 用于确定内存类型l G = Global全局(0:局部、1:全局)如果采用4MB页帧大小,则只需要单级分页(只需要页目录)即可。3122210页目录dir偏移量offset4MB分页时的线性地址格式2 IA-32的寻址方式IA-32的分段保护模式下的逻辑地址由一个16位的段选择符和一个32位的偏移量构成。2.1 段选择符80386的8个通用寄存器和指令指针寄存器及标志寄存器都扩展成了32位(如EAX、ESP、EIP、EFLAGS,对应寄存器名前增加

10、了一个字母E,代表Extended扩展),但是仍然保留原来的段寄存器为16位不变,只是另外增加了两个新的16位辅助段寄存器FS和GS(字母F和G没有特殊的含义,只是跟随在已有段寄存器字母CS、DS、ES之后的两个英文字母而已),一共有6个段寄存器:代码段的CS、数据段的DS、堆栈段的SS和3个辅助段寄存器ES、FS和GS。80386的主要寄存器但是在32位的保护模式下,这些16位的段寄存器的内容,不再是实模式下(最大64KB段长的)段基址,而是一种包含地址描述符结构数组(段表)的索引(index,下标)和特权级(privilege level)等设置的一种数据结构段选择符(segment se

11、lector)。这里的索引(偏移值)指向全局或局部段描述符表(段表)中的一个(描述符)表项,因索引/偏移值为16位,而每个段描述符占8B,所以该偏移值的低3位必须为0(另外用作TI和RPL),只有段寄存器的高13位才有效,因此段描述符表中最多可有(216/8=213=)8192(=8K)个表项。其实在IA-32处理器中,除了6个可见的16位段寄存器外,还有隐藏不可见的与每个段寄存器对应的(64位)影子结构,用于实现分段管理中的保护功能。2.2 段描述符段选择符指向段描述符表(segment descriptor table)中的一个段描述符表项,段描述符用于分段内存管理中的地址生成和保护。在段

12、描述符(表项)中,包含32位段基址、20位段界限和12个控制位,共计64位(8B)。为了与80286(48位6B的)段描述符中的24位基址和16位界限兼容,所以80386段描述符中的32位基址和20位界限在8字节的结构中并不是连续的(高8位基址和高4位界限被放在了新增加的2个高位字节中)。B31B24GD/B0AVL3210L19L16PDPLSTypeB23B16B15B0L15L015 0描述符其中:l L = limit界限(20位段的界限)l B = base基址(32位段的基地址)l Type(类型)占4个二进制位,从低到高依次为(对代码段或数据段描述符):n A = access访

13、问(=0:未被访问、=1:已被访问)n RW = read/write读/写数据段(=0:只读不可写数据段/只执行不可读代码段、=1:可读写数据段/可执行和读代码段)n ED/C = extend direction/conforming伸展方向/一致(=0:向上高地址伸展数据段/非一致代码段、1:向下低地址伸展堆栈段/一致 代码段)n E = code代码(0:数据段包括堆栈、1:代码段)l S = descriptor type描述符类型(=0:系统描述符、=1:代码段或数据段描述符)l DPL = descriptor privilege level描述符特权级(03:本段的特权级为03

14、)l P = present存在(0:段不存在,描述符无意义、1:段存在,描述符含有效基址和界限)l AVL = available for System系统可用(始终设为0) l D/B = default operation size默认操作大小(0:16位段、1:32位段)l G = Granularity 粒度/段长的单位(=0:字节、=1:4KB=212B)下面是全局描述符的结构定义:struct gdt_entry unsigned short limit_low; unsigned short base_low; unsigned char base_middle; unsign

15、ed char access; unsigned char granularity; unsigned char base_high; _attribute_(packed);因为段描述符中的控制位G可以指定段长的单位,G=0时单位为字节,G=1时的单位为4KB=212B。所以段描述符中20位段界限,最大(段长)可以是(220=)1MB或(220+12 = 232 =)4GB。(使用x86处理器的)Linux采用的是分页内存管理,不支持内存的分段管理,就是利用粒度为4KB的段界限,将32位处理器所支持的整个4GB内存分为了一个段,绕开了x86默认的分段管理机制。如果描述符中的S控制位=0,则为

16、系统描述符,包括如下两类:l 系统段描述符n LDT(Local Descriptor-Table,局部描述符表)段描述符n TSS(Task-State Segment,任务状态段)描述符l 门描述符n 调用门(call-gate)描述符n 中断门(interrupt-gate)描述符n 陷阱门(trap-gate)描述符n 任务门(task-gate)描述符系统描述符类型Type字段描述数值11109800000保留1000116位TSS(可用)20010LDT3001116位TSS(忙)4010016位调用门50101任务门6011016位中断门7011116位陷阱门81000保留910

17、0132位TSS(可用)101010保留11101132位TSS(忙)12110032位调用门131101保留14111032位中断门15111132位陷阱门2.3 描述符表l GDT(Global Descriptor Table,全局描述符表)是线性空间里的一种数据结构(本身不是一个段),每个系统都必须定义唯一一个GDT,可被系统中的所有程序和任务使用。GDT的基线性地址(8B对齐)和界限必须(使用LGDT指令)装入GDTR寄存器。GDT的界限值为字节数。l LDT(Local Descriptor Table,局部描述符表)本身是一个段,可定义若干个,可被多个任务共享。LDT位于LDT类

18、型的系统段,GDT中必须包含一个LDT的段描述符。LDT使用其段选择符访问。为了在访问LDT时消除地址转换,LDT的段选择符、基线性地址、界限、访问权限被存储在LDTR寄存器中。IDTR = Interrupt Descriptor Table Register,中断描述符表寄存器3 保护模式IA-32架构的CPU支持4种操作模式:l 保护模式(protected mode)这是处理器的天然态(native state)。l 虚拟8086模式(virtual-8086 mode)不是一种实际的处理器模式,只是指在保护模式下可以直接执行实模式8086软件的能力。l 实地址模式(Real-addr

19、ess mode)实现8086处理器的编程环境。在加电或重启时,处理器被置于实地址模式。l SMM(System Management Mode,系统管理模式)为操作系统或执行程序提供一种实现平台特定功能(如电源管理和系统安全)的透明机制。3.1 进入保护模式1进入保护模式的主要步骤l 准备GDTl 准备GDTR指针(48位GDT参数:16位界限与32位基址)l 用LGDT指令将GDT参数加载到寄存器GDTRl 关闭中断l 打开A20地址线l 置CR0寄存器的PE位l 跳转进入保护模式2常量与宏l NASM宏的定义与使用n 宏的定义格式:%macro 宏名 参数个数 ; (含诸参数的)指令序列

20、,在其中用%i来表示参数i%endmacron 宏的使用方法:宏名 参数1, 参数2, l (段)描述符格式:B31B24GD/B0AVL3210L19L16PDPLSTypeB23B16B15B0L15L015 0描述符格式D/B=1:32位段DPL=03:描述符特权级l 描述符类型常量与用于生成描述符(和门)宏的包含文件代码(pm.inc);-; 在下列类型值命名中:; DA_ : Descriptor Attribute 描述符属性; D : 数据段; C : 代码段; S : 系统段; R : 只读; RW : 读写; A : 已访问; 其它 : 可按照字面意思理解;-; 描述符类型D

21、A_32EQU4000h; 32 位段DA_DPL0EQU 00h; DPL = 0DA_DPL1EQU 20h; DPL = 1DA_DPL2EQU 40h; DPL = 2DA_DPL3EQU 60h; DPL = 3; 存储段描述符类型DA_DREQU90h; 存在的只读数据段类型值DA_DRWEQU92h; 存在的可读写数据段属性值DA_DRWAEQU93h; 存在的已访问可读写数据段类型值DA_CEQU98h; 存在的只执行代码段属性值DA_CREQU9Ah; 存在的可执行可读代码段属性值DA_CCOEQU9Ch; 存在的只执行一致代码段属性值DA_CCOREQU9Eh; 存在的可执

22、行可读一致代码段属性值; 系统段描述符类型DA_LDT EQU 82h; 局部描述符表段类型值DA_TaskGate EQU 85h; 任务门类型值DA_386TSS EQU 89h; 可用 386 任务状态段类型值DA_386CGate EQU 8Ch; 386 调用门类型值DA_386IGate EQU 8Eh; 386 中断门类型值DA_386TGate EQU 8Fh; 386 陷阱门类型值; RPL(Requested Privilege Level): 请求特权级,用于特权检查。; TI(Table Indicator): 引用描述符表指示位;TI=0 指示从全局描述符表GDT中读

23、取描述符;;TI=1 指示从局部描述符表LDT中读取描述符。;-; 选择符类型值说明; 其中:; SA_ : Selector AttributeSA_RPL0EQU0; SA_RPL1EQU1; RPLSA_RPL2EQU2; SA_RPL3EQU3; SA_TIGEQU0; TISA_TILEQU4; ;-; 宏 -; 描述符; usage: Descriptor Base, Limit, Attr; Base: dd; Limit: dd (low 20 bits available); Attr: dw (lower 4 bits of higher byte are always 0

24、)%macro Descriptor 3dw%2 & 0FFFFh; 段界限1dw%1 & 0FFFFh; 段基址1db(%1 >> 16) & 0FFh; 段基址2dw(%2 >> 8) & 0F00h) | (%3 & 0F0FFh); 属性1 + 段界限2 + 属性2db(%1 >> 24) & 0FFh; 段基址3%endmacro ; 共 8 字节; 门; usage: Gate Selector, Offset, DCount, Attr; Selector: dw; Offset: dd; DCo

25、unt: db; Attr: db%macro Gate 4dw(%2 & 0FFFFh); 偏移1dw%1; 选择子dw(%3 & 1Fh) | (%4 << 8) & 0FF00h); 属性dw(%2 >> 16) & 0FFFFh); 偏移2%endmacro ; 共 8 字节; 3汇编源代码l 测试程序(pmtest1.asm)%include"pm.inc" 常量, 宏, 以及一些说明org07c00hjmpLABEL_BEGINSECTION .gdt; GDT(定义全局描述符表。注意,为防止误操作,首个G

26、DT表项必须为空); 段基址, 段界限, 属性LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW; 显存首地址; GDT 结束; 定义48位的GDT参数结构GdtPtr(16位界限 + 32位基地址)GdtLenequ$ - LABEL_GDT; GDT长度GdtPtrdwGdtLen - 1; GDT界限dd0; GDT基地址;

27、 GDT 选择符(定义代码段和显存段在GDT中的偏移量)SelectorCode32equLABEL_DESC_CODE32 - LABEL_GDT ; = 64SelectorVideoequLABEL_DESC_VIDEO- LABEL_GDT ; = 128; END of SECTION .gdtSECTION .s16BITS16LABEL_BEGIN:movax, cs; 设置DS/ES/SS = CSmovds, axmoves, axmovss, axmovsp, 100h; 设置 SP = 100h; 初始化 32 位代码段描述符中的基址部分xoreax, eax; EAX

28、= 0movax, csshleax, 4; EAX = 代码段基址addeax, LABEL_SEG_CODE32; EAX + 偏移地址 = 32位代码段起始地址movword LABEL_DESC_CODE32 + 2, ax; B015 = AXshreax, 16; EAX >> 16(AX = EAX的高16位)movbyte LABEL_DESC_CODE32 + 4, al; B1623 = ALmovbyte LABEL_DESC_CODE32 + 7, ah; B2431 = AH; 为加载 GDTR 作准备xoreax, eaxmovax, dsshleax,

29、 4addeax, LABEL_GDT; eax <- GDT基地址movdword GdtPtr + 2, eax; GdtPtr + 2 <- GDT基地址; 加载 GDTRlgdtGdtPtr; 关中断cli; 打开地址线A20inal, 92horal, 00000010b ; or al, 2(关闭:and al,0FDh)out92h, al; 准备切换到保护模式(置CR0的PE位为1)moveax, cr0oreax, 1; PE = 1movcr0, eax; 真正进入保护模式jmpdword SelectorCode32:0; 执行这一句会把SelectorCod

30、e32 装入cs,; 并跳转到Code32Selector:0处; END of SECTION .s16SECTION .s32; 32 位代码段. 由实模式跳入.BITS32LABEL_SEG_CODE32:movax, SelectorVideomovgs, ax; 视频段选择符(目的)movedi, (80 * 11 + 79) * 2; 屏幕第 11 行, 第 79 列。movah, 0Ch; 0000: 黑底 1100: 红字moval, 'P'movgs:edi, ax; 到此停止jmp$; 死循环SegCode32Lenequ$ - LABEL_SEG_CODE

31、32; END of SECTION .s324代码解释l 机器指令LGDT将48位GDT参数(参见下图)加载到寄存器GDTR中,我们代码中的GDT参数,用结构变量GdtPtr表示。471615032位GDT基址16位GDT界限下面是相关代码:; 加载 GDTRlgdtGdtPtrl 打开A20地址线由于历史原因,虽然8086处理器只有20位地址线(即只能寻址1MB地址空间),但是如果试图访问超过1MB的地址时,系统并不会发生异常,而只是回卷(wrap)寻址(忽略序号为20的第21位及以上的地址数据)。在推出80286后,不再回卷,可访问超过1MB以上的地址空间。但为了保证对老软件的兼容,IB

32、M想出了一个办法使用Intel 8042键盘控制器(后来改用92h号端口的第二个二进制位)来控制20号(及以上)地址(Address)位,称为A20线门(A20 line gate)或门A20(Gate-A20))。当A20打开时,不回卷,可访问超过1MB以上的地址空间;当A20关闭时,则回卷,只能寻址1MB地址空间。在系统启动时,主板上的系统BIOS会打开A20进行内存检测,但在将控制转交给操作系统(磁盘引导扇区)之前,会关闭A20。为了使用大于1MB的内存空间,在进入保护模式之前,我们先必须打开A20。下面是相关代码:; 打开地址线A20inal, 92horal, 00000010bou

33、t92h, all 置CR0寄存器的PE位CR0是80386引入的4个32位的控制寄存器(Control Register)CR0CR3之一,包含若干控制处理器操作模式和状态的系统控制标志。其中的最低位PE(Protection Enable,保护允许/激活保护)用于允许/禁止保护状态。相关代码:; 准备切换到保护模式(置CR0的PE位为1)moveax, cr0oreax, 1movcr0, eax控制寄存器l 跳转进入保护模式虽然置CR0的PE=1后,系统已经允许在保护模式,但是此时的CS仍然是16位实模式下的值,必须通过一个特殊的跳转指令,从我们程序前面的16位代码(SECTION .s

34、16)跳转到后面的32位代码(SECTION .s32)。至此,才算真正完成从实模式到保护模式的转换。相关代码:; 真正进入保护模式jmpdword SelectorCode32:0; 执行这一句会把 SelectorCode32 装入 cs,; 并跳转到 Code32Selector:0 处注意,其中jmp指令的红色的数据类型说明符dword(32位的双字)是NASM特有的。4编译运行编译:nasm pmtest1.asm -o pmtest1.bin写入:用FloppyWriter或WinHex将pmtest1.bin写入软盘映像的引导扇区,并在该扇区的结束处(1FEh)添加启动扇区的结束

35、标55h和0aah测试:用Bochs虚拟机测试结果:运行结果如下图所示:3.2 启动分页机制进入保护模式,只是启动了分段机制,可以实现保护功能。但是如果要实现虚拟内存管理,还需要启动可选的分页机制。1启动分页机制的主要步骤l 准备PD和PTl 让CR3指向PDl 置CR0寄存器的PG位l 短跳转启动分页机制2汇编源代码需要在原pm.inc中增加如下常量定义:; 为段描述符中属性字对应控制位G(15b)的十六进制值,用于构造描述符DA_LIMIT_4KEQU8000h; 段界限粒度为 4K 字节;-; 分页机制使用的常量说明; 为页目录项PDE和页表项PTE中字对应属性位的值,用于表项的初始化;

36、-PG_PEQU1; 页存在属性位PG_RWREQU0; R/W 属性位值, 读/执行PG_RWWEQU2; R/W 属性位值, 读/写/执行PG_USSEQU0; U/S 属性位值, 系统级PG_USUEQU4; U/S 属性位值, 用户级;-下面是进入保护模式并启动分页机制的测试程序的源代码(pmtest2.asm):其中l 红色部分为启动分页机制的代码l 绿色部分为返回实模式的代码l 其余部分为进入保护模式的代码%include"pm.inc" 常量, 宏, 以及一些说明PageDirBaseequ200000h; 页目录开始地址: 2MPageTblBaseequ2

37、01000h; 页表开始地址: 2M+4Korg0100hjmpLABEL_BEGINSECTION .gdt; GDT; 段基址, 段界限, 属性LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符LABEL_DESC_NORMAL: Descriptor 0, 0ffffh, DA_DRW; Normal 描述符LABEL_DESC_PAGE_DIR: Descriptor PageDirBase, 4095, DA_DRW ; Page DirectoryLABEL_DESC_PAGE_TBL: Descriptor PageTblBase, 1023, DA_DRW

38、|DA_LIMIT_4K ; Page TablesLABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32; 非一致代码段, 32LABEL_DESC_CODE16: Descriptor 0, 0ffffh, DA_C; 非一致代码段, 16LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW; DataLABEL_DESC_STACK: Descriptor 0, TopOfStack, DA_DRWA + DA_32 ; Stack, 32 位LABEL_DESC_VIDEO: D

39、escriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址; GDT 结束GdtLenequ$ - LABEL_GDT; GDT长度GdtPtrdwGdtLen - 1; GDT界限dd0; GDT基地址; GDT 选择符SelectorNormalequLABEL_DESC_NORMAL- LABEL_GDTSelectorPageDirequLABEL_DESC_PAGE_DIR- LABEL_GDTSelectorPageTblequLABEL_DESC_PAGE_TBL- LABEL_GDTSelectorCode32equLABEL_DESC_CODE32-

40、LABEL_GDTSelectorCode16equLABEL_DESC_CODE16- LABEL_GDTSelectorDataequLABEL_DESC_DATA- LABEL_GDTSelectorStackequLABEL_DESC_STACK- LABEL_GDTSelectorVideoequLABEL_DESC_VIDEO- LABEL_GDT; END of SECTION .gdtSECTION .data1 ; 数据段ALIGN32BITS32LABEL_DATA:SPValueInRealModedw0; 字符串PMMessage:db"In Protect

41、Mode now. -", 0; 进入保护模式后显示此字符串OffsetPMMessageequPMMessage - $DataLenequ$ - LABEL_DATA; END of SECTION .data1; 全局堆栈段SECTION .gsALIGN32BITS32LABEL_STACK:times 512 db 0TopOfStackequ$ - LABEL_STACK - 1; END of SECTION .gsSECTION .s16BITS16LABEL_BEGIN:movax, csmovds, axmoves, axmovss, axmovsp, 0100h

42、movLABEL_GO_BACK_TO_REAL+3, axmovSPValueInRealMode, sp; 初始化 16 位代码段描述符movax, csmovzxeax, axshleax, 4addeax, LABEL_SEG_CODE16movword LABEL_DESC_CODE16 + 2, axshreax, 16movbyte LABEL_DESC_CODE16 + 4, almovbyte LABEL_DESC_CODE16 + 7, ah; 初始化 32 位代码段描述符xoreax, eaxmovax, csshleax, 4addeax, LABEL_SEG_CODE

43、32movword LABEL_DESC_CODE32 + 2, axshreax, 16movbyte LABEL_DESC_CODE32 + 4, almovbyte LABEL_DESC_CODE32 + 7, ah; 初始化数据段描述符xoreax, eaxmovax, dsshleax, 4addeax, LABEL_DATAmovword LABEL_DESC_DATA + 2, axshreax, 16movbyte LABEL_DESC_DATA + 4, almovbyte LABEL_DESC_DATA + 7, ah; 初始化堆栈段描述符xoreax, eaxmovax,

44、 dsshleax, 4addeax, LABEL_STACKmovword LABEL_DESC_STACK + 2, axshreax, 16movbyte LABEL_DESC_STACK + 4, almovbyte LABEL_DESC_STACK + 7, ah; 为加载 GDTR 作准备xoreax, eaxmovax, dsshleax, 4addeax, LABEL_GDT; eax <- gdt 基地址movdword GdtPtr + 2, eax; GdtPtr + 2 <- gdt 基地址; 加载 GDTRlgdtGdtPtr; 关中断cli; 打开地址线

45、A20inal, 92horal, 00000010bout92h, al; 准备切换到保护模式moveax, cr0oreax, 1movcr0, eax; 真正进入保护模式jmpdword SelectorCode32:0; 执行这一句会把SelectorCode32装入cs, ; 并跳转到Code32Selector:0处;LABEL_REAL_ENTRY:; 从保护模式跳回到实模式就到了这里movax, csmovds, axmoves, axmovss, axmovsp, SPValueInRealModeinal, 92h; andal, 11111101b; 关闭 A20 地址线

46、out92h, al; sti; 开中断movax, 4c00h; int21h; 回到 DOS; END of SECTION .s16SECTION .s32; 32 位代码段. 由实模式跳入.BITS32LABEL_SEG_CODE32:callSetupPagingmovax, SelectorDatamovds, ax; 数据段选择符movax, SelectorVideomovgs, ax; 视频段选择符movax, SelectorStackmovss, ax; 堆栈段选择符movesp, TopOfStack; 下面显示一个字符串movah, 0Ch; 0000: 黑底 110

47、0: 红字xoresi, esixoredi, edimovesi, OffsetPMMessage; 源数据偏移movedi, (80 * 10 + 0) * 2; 目的数据偏移。屏幕第 10 行, 第 0 列。cld.1:lodsbtestal, aljz.2movgs:edi, axaddedi, 2jmp.1.2:; 显示完毕; 到此停止jmpSelectorCode16:0; 启动分页机制 -SetupPaging:; 为简化处理, 所有线性地址对应相等的物理地址.; 首先初始化页目录movax, SelectorPageDir; 此段首地址为 PageDirBasemoves, axmovecx, 1024; 共 1K 个表项xoredi, edixoreax, eaxmoveax, PageTblBase | PG_P | PG_USU | PG_RWW.1:st

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论