分享
 
 
 

80386ASM程序设计基础(十一)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

主要介绍系统地址寄存器和控制寄存器以及在程序中实方式下与保护方式下的切换

80386处理器新增了一组控制寄存器CR0,CR1,CR2,CR3和一组系统地址寄存器GDTR,LDTR,IDTR,TR,它们全部都是32位的。CR0包含了指定处理器工作方式的控制位,CR1保留未使用,CR2和CR3由分页管理部件使用,CR0中的5~30位和CR3中的0~11位必须为0,分别介绍如下:

___________________________________________________________________________

|PG|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |ET|TS|EM|MP|PE| CR0

|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|_ |__|

| Reserved | CR1

|__________________________________________________________________________|

| 页故障线性地址 | CR2

|__________________________________________________________________________|

| 高20位页表的起始物理地址 |低12位为0 | CR3

|_____________________________________________________|____________________|

PE标记用于指定处理器的工作模式。PE=0,处理器处于实模式;PE=1,处理器处于保护模式

PG标记用于指定处理器是否启用分页管理机制。PG=0,禁用分页管理机制,此时由分段管理部件产生的线性地址就是物理地址。;PG=1,启用分页管理机制,此时由分段管理部件产生的线性地址须再经过分页管理机制才能得到最终的物理地址。

MP,EM,TS,ET用于控制浮点协处理器的操作。

CR2和CR3控制寄存器由分页管理机制使用。CR2用于发生页异常时报告出错信息。当发生页故障时,处理器会将当前的线性地址保存在CR2。CR3用于保存页表在内存中的起始物理地址,由于页表是对齐的,所以仅高20位有效,低12位必须为0。

全局描述符表GDT,局部描述符表LDT和中断描述符表IDT在保护模式下是特殊的段,也就是说处理器将这些线性表当段一个特殊的段来处理,它包含了对段机制所用的重要数据。为了能够更快速地进位这些段,386处理器采用特殊的寄存器保存这种段的基地址和界限,这种寄存器就是系统地址寄存。在80386下系统地址寄存器有:全局描述符表寄存器GDTR,局部描述符表寄存器LDTR,中断描述符表IDTR,任务状态段寄存器TR。全局描述符表寄存器GDTR,长度为48位,其中高32位是基址,低16位含界限。由于GDT本身不可以由GDT内的描述符来描述,所以处理使用GDTR寄存器为GDT这样的特殊段提供一个伪描述符,即是说:

| |

|________________| 全局描述符表寄存器GDTR

| | ________________________________

| GDT |______| | |

|________________|______| 32位基址 | 16界限 |

| | |___________________|___________|

| |

因为段选择子只用了13位来表描述表中的索引号,即是说最多可以有8192个描述符,而每个描述符是8个字节。而在80386处理器下将全局描述表作为一个特殊的系统段,那么段的界限实际上就是8192*8,所以段的界限用16位就可以了。通常情况下,如果GDT有N个描述符,那么GDT的段界限为N*8-1,这个伪描述符也就是全局描述符寄存器内容可以用结体定义成:

PreDesc STRUCT

BASE32 DD 0

LIMIT16 DW 0

PreDesc ENDS

局部描述表寄存器LDTR规定了当前任中使用的局部描述表LDT,LDTR类似于一个段寄存,它的长度为32位,一个16位的寄存器和对程序员来讲不可见的高速缓冲存储器。每一个任务的局部描述符表作为一个特殊的系统段,它由定义在全局描述符表GDT中的描述符来描述,前面已提到过一个任务只能有一张全局描述符表GDT和一张中断描述符表IDT,但可以有多张局部描述行表LDT,而每一张局部描述符表都由定义在GDT中的描述符来确定。通常将描述LDT的选择子装入到LDTR,LDTR根据选择子从全局描述符表中取出对应的描述符,并把LDT的基址及界限信息保存到对程序员来讲不可见的高速缓冲存储器,随后就可以对LDT进行访问。当前任务中的所有段都由GDT中的描述符来描述。

_________ ____________________________________________________

| |______| | | |

| LDTR |______| 32位基址 | 32位界限 |12位属性 |

|_______| |___________________|_____________________|_________|

中断描述符表和全局描述符表一样,长度为48位。32位段基址和16位界限。

如何从实式模式切换到保护模式下呢?通常来讲,要两个步骤:1.作好切换到保护模式下的准备;2.切换到保护模式。主要准备工作就是建立全局描述符表,并使GDTR指向GDT,因为切换到保护模式下,至少要将代码段的选择子装入到CS中,看程序片段:

;定义好描述符的结构

DESCRIPTOR STRUCT

LIMIT DW 0;段界限

BASEL DW 0;段基址的低16位

BASEM DB 0;段基址的16~23位

ATTRIBUTES DW 0;段属性

BASEH DB 0;段基址的高8位,24~31

DESCRIPTOR ENDS

;定义好伪描述符

PDESC STRUCT

LIMIT DW 0

BASE DD 0

PDESC ENDS

;通常要定义一个段间跳转的宏,这样的话就可以保证在进入保护模式时将代码段的选择子装入到CS寄存器

JUMP MACRO selector,offset

DB 0EAH

DW offsetv;段偏移

DW selector;段选择子

ENDM

;打开A20地址线

PUSH AX

IN AL,92H

OR AL,2

OUT 92H,AL

POP AX

;关闭A20地址线

PUSH AX

IN AL,92H

AND AL,0FDH

OUT 92H,AL

POP AX

;切换到保护模式下,将CR0寄存中的第0位置1

MOV EAX,CR0

OR CR0,1

MOV CR0,EAX

其它的部分就要根据具体的应用来写, 下面的例子是如何在保护模下访问820000H单元开始的内容,看程序:

.386P

data segment use16

GDT LABEL BYTE;定义全局描述符表

DUMMY DESCRIPTOR<>;空描述符,它有特定义的含义,空描述符可以保证GDT中的第1个描述符永远不会被访问

CODE DESCRIPTOR<0FFFFH,,,SAttr,>;代码段的描述符

CODE_SEL=CODE-GDT;代码段描述符的选择子

DATAS DESCRIPTOR<0FFFFH,0H,82H,DAttr,>;源数据段描述符,即820000H

DATAS_SEL=DATAS-GDT;源数据段选择子

GDTLEN=$-GDT

VGDTR DESCRIPTOR<GDTLEN-1,>

data ends

code segment use16

assume cs:code,ds:data

start:

mov ax,data

mov ds,ax

mov bx,16

mul bx;设置全局描述表GDT基址,因为现在还处在实模式下,所以段地址要左移4位

add ax,offset GDT

adc dx,0

mov word ptr VGDTR.BASE,ax;设置全局描述符表寄存器GDTR的内容

mov word ptr VGDTR.BASE+2,dx

;设置代码段描述符

mov ax,cs

mul bx

mov CODE.BASEL,ax

mov CODE.BASEM,dl

mov CODE.BASEH,dh

;以下部分你可以根据实际的应用来编写

.........

...........

;加载GDTR

LGDT QWORD PTR VGDTR

CLI;关中断

;打开A20地址线

;切换到保护模式

mov eax,cr0

or eax,1

mov cr0,eax

JUMP <CODE_SEL>,<OFFSET VIRTUAL>;清指令预取队列,真正进入保护模式

........

........

virutal:

;add your code here according to your needs

............

;回到实模式

;关闭A20地址线

STI;开中断

code ends

end start

上述的程序片段是随手写的,可根据需要自已加以调整,不过有点要说明。

a.通常来讲,从实模式下切换到保护模式下只要将CR0寄存器中的最低位设置为1就可以了。但是,此时CS的内容仍然是实模式下的内容,所以加了一条段间跳转指令JUMP <CODE_SEL>,<OFFSET VIRTUAL>,执行完这条指令就可以将代码段选择子CODE_SEL装入到段寄存器CS中,同时也可以刷新指令预取队列。

b.LGDT QWORD PTR VGDTR,该指令的功能是将VGDTR的内容装入到全局描述符表寄存器GDTR中。

c.上面的代码片段中并没有建立中断描述符表IDT,这样的话就要求整个程序必须运行在关中断情况下进行。

d.为了访问1M以上的存储单元,应该打开A20地址线,在WINDOWS下只需加载HIMEM.SYS就可以了。能不能进入保护模式只与是否加载HIMEM.SYS有关,与处理器工作在实方式下还是在保护方式下无关。也就是说,只要加载HIMEM.SYS,就算处理器当前处在实模式下,A20地址线关闭,处理器也一样可以进入保护模式。

下集预告:

80386ASM程序设计基础(十二)---任务切换

80386ASM程序设计基础(十三)---80386中断和异常

80386ASM程序设计基础(十四)---分页管理机制

80386ASM程序设计基础(十五)---V86模式

敬请关注,谢谢。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有