📄 80386asm程序设计基础(十一).htm
字号:
|__________________________________________________________________________|<BR>
|
页故障线性地址
| CR2<BR>
|__________________________________________________________________________|<BR>
|
高20位页表的起始物理地址
|低12位为0
| CR3<BR>
|_____________________________________________________|____________________|</P>
<P> PE标记用于指定处理器的工作模式。PE=0,处理器处于实模式;PE=1,处理器处于保护模式<BR>
PG标记用于指定处理器是否启用分页管理机制。PG=0,禁用分页管理机制,此时由分段管理部件产生的线性地址就是物理地址。;PG=1,启用分页管理机制,此时由分段管理部件产生的线性地址须再经过分页管理机制才能得到最终的物理地址。<BR>
MP,EM,TS,ET用于控制浮点协处理器的操作。<BR>
CR2和CR3控制寄存器由分页管理机制使用。CR2用于发生页异常时报告出错信息。当发生页故障时,处理器会将当前的线性地址保存在CR2。CR3用于保存页表在内存中的起始物理地址,由于页表是对齐的,所以仅高20位有效,低12位必须为0。<BR>
全局描述符表GDT,局部描述符表LDT和中断描述符表IDT在保护模式下是特殊的段,也就是说处理器将这些线性表当段一个特殊的段来处理,它包含了对段机制所用的重要数据。为了能够更快速地进位这些段,386处理器采用特殊的寄存器保存这种段的基地址和界限,这种寄存器就是系统地址寄存。在80386下系统地址寄存器有:全局描述符表寄存器GDTR,局部描述符表寄存器LDTR,中断描述符表IDTR,任务状态段寄存器TR。全局描述符表寄存器GDTR,长度为48位,其中高32位是基址,低16位含界限。由于GDT本身不可以由GDT内的描述符来描述,所以处理使用GDTR寄存器为GDT这样的特殊段提供一个伪描述符,即是说:<BR>
<BR>
|
|<BR>
|________________|
全局描述符表寄存器GDTR<BR>
|
|
________________________________<BR>
|
GDT
|______|
|
|<BR> |________________|______|
32位基址
| 16界限 |<BR>
|
|
|___________________|___________|<BR>
|
|<BR>因为段选择子只用了13位来表描述表中的索引号,即是说最多可以有8192个描述符,而每个描述符是8个字节。而在80386处理器下将全局描述表作为一个特殊的系统段,那么段的界限实际上就是8192*8,所以段的界限用16位就可以了。通常情况下,如果GDT有N个描述符,那么GDT的段界限为N*8-1,这个伪描述符也就是全局描述符寄存器内容可以用结体定义成:<BR>
PreDesc STRUCT<BR> BASE32 DD 0<BR> LIMIT16 DW
0<BR> PreDesc
ENDS<BR>局部描述表寄存器LDTR规定了当前任中使用的局部描述表LDT,LDTR类似于一个段寄存,它的长度为32位,一个16位的寄存器和对程序员来讲不可见的高速缓冲存储器。每一个任务的局部描述符表作为一个特殊的系统段,它由定义在全局描述符表GDT中的描述符来描述,前面已提到过一个任务只能有一张全局描述符表GDT和一张中断描述符表IDT,但可以有多张局部描述行表LDT,而每一张局部描述符表都由定义在GDT中的描述符来确定。通常将描述LDT的选择子装入到LDTR,LDTR根据选择子从全局描述符表中取出对应的描述符,并把LDT的基址及界限信息保存到对程序员来讲不可见的高速缓冲存储器,随后就可以对LDT进行访问。当前任务中的所有段都由GDT中的描述符来描述。<BR>
_________
____________________________________________________<BR>
|
|______|
|
| |<BR>
| LDTR |______|
32位基址 |
32位界限
|12位属性 |<BR> |_______|
|___________________|_____________________|_________|</P>
<P>中断描述符表和全局描述符表一样,长度为48位。32位段基址和16位界限。<BR>如何从实式模式切换到保护模式下呢?通常来讲,要两个步骤:1.作好切换到保护模式下的准备;2.切换到保护模式。主要准备工作就是建立全局描述符表,并使GDTR指向GDT,因为切换到保护模式下,至少要将代码段的选择子装入到CS中,看程序片段:</P>
<P>;定义好描述符的结构<BR>DESCRIPTOR STRUCT<BR> LIMIT DW
0;段界限<BR> BASEL DW 0;段基址的低16位<BR> BASEM DB
0;段基址的16~23位<BR> ATTRIBUTES DW 0;段属性<BR> BASEH DB
0;段基址的高8位,24~31<BR>DESCRIPTOR ENDS<BR>;定义好伪描述符<BR>PDESC
STRUCT<BR> LIMIT DW 0<BR> BASE DD 0<BR>PDESC
ENDS<BR>;通常要定义一个段间跳转的宏,这样的话就可以保证在进入保护模式时将代码段的选择子装入到CS寄存器<BR>JUMP
MACRO selector,offset<BR> DB 0EAH<BR> DW
offsetv;段偏移<BR> DW selector;段选择子<BR>
ENDM<BR>;打开A20地址线<BR>PUSH AX<BR>IN AL,92H<BR>OR AL,2<BR>OUT
92H,AL<BR>POP AX<BR>;关闭A20地址线<BR>PUSH AX<BR>IN AL,92H<BR>AND
AL,0FDH<BR>OUT 92H,AL<BR>POP AX<BR>;切换到保护模式下,将CR0寄存中的第0位置1<BR>MOV
EAX,CR0<BR>OR CR0,1<BR>MOV CR0,EAX<BR>其它的部分就要根据具体的应用来写,
下面的例子是如何在保护模下访问820000H单元开始的内容,看程序:<BR>.386P<BR>data segment
use16<BR>GDT LABEL BYTE;定义全局描述符表<BR>DUMMY
DESCRIPTOR<>;空描述符,它有特定义的含义,空描述符可以保证GDT中的第1个描述符永远不会被访问<BR>CODE
DESCRIPTOR<0FFFFH,,,SAttr,>;代码段的描述符<BR>CODE_SEL=CODE-GDT;代码段描述符的选择子<BR>DATAS
DESCRIPTOR<0FFFFH,0H,82H,DAttr,>;源数据段描述符,即820000H<BR>DATAS_SEL=DATAS-GDT;源数据段选择子<BR>GDTLEN=$-GDT<BR>VGDTR
DESCRIPTOR<GDTLEN-1,><BR>data ends</P>
<P>code segment use16<BR> assume
cs:code,ds:data<BR>start:<BR> mov
ax,data<BR> mov ds,ax<BR> mov
bx,16<BR> mul
bx;设置全局描述表GDT基址,因为现在还处在实模式下,所以段地址要左移4位<BR> add ax,offset
GDT<BR> adc dx,0<BR> mov word ptr
VGDTR.BASE,ax;设置全局描述符表寄存器GDTR的内容<BR> mov word ptr
VGDTR.BASE+2,dx<BR> ;设置代码段描述符<BR> mov
ax,cs<BR> mul bx<BR> mov
CODE.BASEL,ax<BR> mov CODE.BASEM,dl<BR> mov
CODE.BASEH,dh <BR>
;以下部分你可以根据实际的应用来编写<BR> .........<BR>
...........<BR> ;加载GDTR<BR> LGDT QWORD PTR
VGDTR<BR> CLI;关中断<BR>
;打开A20地址线<BR> ;切换到保护模式<BR> mov
eax,cr0<BR> or eax,1<BR> mov
cr0,eax<BR> JUMP <CODE_SEL>,<OFFSET
VIRTUAL>;清指令预取队列,真正进入保护模式<BR>
........<BR> ........<BR>
virutal:<BR> ;add your code here according
to your needs<BR> ............<BR>
;回到实模式<BR> ;关闭A20地址线<BR> STI;开中断<BR>code
ends<BR>end
start<BR>上述的程序片段是随手写的,可根据需要自已加以调整,不过有点要说明。<BR>a.通常来讲,从实模式下切换到保护模式下只要将CR0寄存器中的最低位设置为1就可以了。但是,此时CS的内容仍然是实模式下的内容,所以加了一条段间跳转指令JUMP
<CODE_SEL>,<OFFSET
VIRTUAL>,执行完这条指令就可以将代码段选择子CODE_SEL装入到段寄存器CS中,同时也可以刷新指令预取队列。
<BR>b.LGDT QWORD PTR
VGDTR,该指令的功能是将VGDTR的内容装入到全局描述符表寄存器GDTR中。<BR>c.上面的代码片段中并没有建立中断描述符表IDT,这样的话就要求整个程序必须运行在关中断情况下进行。<BR>d.为了访问1M以上的存储单元,应该打开A20地址线,在WINDOWS下只需加载HIMEM.SYS就可以了。能不能进入保护模式只与是否加载HIMEM.SYS有关,与处理器工作在实方式下还是在保护方式下无关。也就是说,只要加载HIMEM.SYS,就算处理器当前处在实模式下,A20地址线关闭,处理器也一样可以进入保护模式。<BR>下集预告:<BR>80386ASM程序设计基础(十二)---任务切换<BR>80386ASM程序设计基础(十三)---80386中断和异常<BR>80386ASM程序设计基础(十四)---分页管理机制<BR>80386ASM程序设计基础(十五)---V86模式<BR>敬请关注,谢谢。
<BR> </P>
<P><BR> </P><BR><!--内容结束//--></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR><!--文章评论开始//-->
<TABLE cellSpacing=0 cellPadding=0 width=770 align=center bgColor=#006699
border=0>
<TBODY>
<TR bgColor=#006699>
<TD id=white align=middle bgColor=#006699><FONT
color=#ffffff>对该文的评论</FONT></TD>
<TD align=middle><!--文章人气开始//-->
<SCRIPT src="80386ASM程序设计基础(十一).files/readnum.htm"></SCRIPT>
<!--文章人气开始//--></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TD bgColor=#cccccc colSpan=3><SPAN style="COLOR: #cccccc"><IMG height=16
hspace=1 src="80386ASM程序设计基础(十一).files/ico_pencil.gif" width=16>
</SPAN> xixiao001 <I>(2004-2-17 18:11:23)</I>
</TD></TR>
<TR>
<TD width=532 bgColor=#ffffff colSpan=3><BR>想请教一下: 什么是一致代码段?
为什么对非一致代码段,要求CPL=DPL,RPL<=DPL,这个CPL是怎么获得的呢?而RPL在断间跳转时具体是
什么意义呢?疑惑ing+痛苦ing。。。。 <BR></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TD bgColor=#cccccc colSpan=3><SPAN style="COLOR: #cccccc"><IMG height=16
hspace=1 src="80386ASM程序设计基础(十一).files/ico_pencil.gif" width=16>
</SPAN> xixiao001 <I>(2004-2-17 18:10:49)</I>
</TD></TR>
<TR>
<TD width=532 bgColor=#ffffff
colSpan=3><BR>当第(1)条指令执行后,CPU进入保护模式,在执行(2)以前,CPU会以保护的寻址方式将一些数据(可能不是指令)写入指令缓冲队列,然后从缓冲队列中取(2)到CPU译码器,因为机器码不变,(2)可以顺利的重置CS和IP并清缓冲指令队列,这样当(1)执行后预取的那条错误指令将不会有影响
<BR></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TD bgColor=#cccccc colSpan=3><SPAN style="COLOR: #cccccc"><IMG height=16
hspace=1 src="80386ASM程序设计基础(十一).files/ico_pencil.gif" width=16>
</SPAN> climberwxh <I>(2004-2-17 11:36:52)</I>
</TD></TR>
<TR>
<TD width=532 bgColor=#ffffff colSpan=3><BR>请教一个问题好吗 文的代码有如下部分 (1) mov
cr0,eax (2) JUMP <CODE_SEL>,<OFFSET VIRTUAL> 我的问题是, 当 (1)
执行完后,cpu 应该处于保护模式了,那它应该把 cs中的值 解释为 描述符选择子 eip 则是 由此找到的基址的偏移, 这样一来,(1)
句执行完后, cpu 是无条件的执行(2),还是 恰好 可以 根据 cs:eip 并按照 保护模式的 寻址方法 找到 (2)句呢 ,严重困惑中
先谢谢了 <BR></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TD bgColor=#cccccc colSpan=3><SPAN style="COLOR: #cccccc"><IMG height=16
hspace=1 src="80386ASM程序设计基础(十一).files/ico_pencil.gif" width=16>
</SPAN> kingcaiyao <I>(2003-12-29 10:58:59)</I>
</TD></TR>
<TR>
<TD width=532 bgColor=#ffffff colSpan=3><BR>to bigwhiteshark:
如果说我是的抄的,那么所有中国程序员现在的技术都是抄的,我们现在学到的计算机理论基本上都外国人的,没有任何理论是我们自已发明的,我们都是跟着别人后面跑。你当然可以到书店买汇编语言看,但问题是你看了之后能将你的理解写下来吗?你是否真正理解了呢?我的所有文章都是我了解其工作原理,然后将它写成代码,如果这样就算是抄,那你就不要读书了。因为老师教给你的都是思维方法和解决方法,然后由你实践,按照你的潜意识,这都属于抄袭。如果你能够看完80386ASM宏汇编这本书,然后将其中的精华提炼出来,并写成文章发表出来,你再说我抄袭不迟。我劝你不要轻易给别人扣帽子,你有时间好好地读读书,不要整天在论坛上哗众取宠。基本上每天都看到你说你的学历不高,而得不到公平的机会。真是这样吗?是金子就一定会发光,不要埋怨任何人。你意识不到你的危机是因为你还年轻,年轻的资本不应该仅仅在于精力充沛,还在于知识的逐渐进步。你现在去南方流浪,同样是因为你年轻,我想30岁的时候,你就不是现在这样的心态。你只能去适应这个客观世界,更为重要的是要改造你的主观世界,改变你的病态心理。你不行,并不代表别人不行,病态的心理对你的成长有害。你在夜郎国里时间太久了,要出去了解社会,要进修。无端的自悲,莫名的愤怒都是你病态心理的集中体现,你已经不止一次在BCB论坛上将你的这种病态心理体现出来。对于许多人而言,对你的表演感到冷漠,无奈,可笑。我不想跟你引起任何争论,只不过是对你污蔑,攻击进行适当的反击。
<BR></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#666666
border=0>
<TBODY>
<TR>
<TD bgColor=#cccccc colSpan=3><SPAN style="COLOR: #cccccc"><IMG height=16
hspace=1 src="80386ASM程序设计基础(十一).files/ico_pencil.gif" width=16>
</SPAN> bigwhiteshark <I>(2003-6-25 9:33:49)</I>
</TD></TR>
<TR>
<TD width=532 bgColor=#ffffff colSpan=3><BR>你是抄的.... 收藏目的是不用带那本书跑来跑去了
<BR></TD></TR></TBODY></TABLE><!--文章评论结束//--><BR>
<DIV align=center>
<TABLE cellSpacing=1 cellPadding=2 width=770 align=center bgColor=#cccccc
border=0>
<TBODY>
<TR>
<TH id=white bgColor=#006699><FONT
color=#ffffff>我要评论</FONT></TH></TR></TBODY></TABLE></DIV>
<DIV align=center>
<TABLE width=770 border=0>
<TBODY>
<TR>
<TD>你没有登陆,无法发表评论。 请先<A
href="http://www.csdn.net/member/login.asp?from=/Develop/read_article.asp?id=17481">登陆</A>
<A
href="http://www.csdn.net/expert/zc.asp">我要注册</A><BR></TD></TR></TBODY></TABLE></DIV><BR>
<HR width=770 noShade SIZE=1>
<TABLE cellSpacing=0 cellPadding=0 width=500 border=0>
<TBODY>
<TR align=middle>
<TD vAlign=bottom height=10><A
href="http://www.csdn.net/intro/intro.asp?id=2">网站简介</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=5">广告服务</A> - <A
href="http://www.csdn.net/map/map.shtm">网站地图</A> - <A
href="http://www.csdn.net/help/help.asp">帮助信息</A> - <A
href="http://www.csdn.net/intro/intro.asp?id=2">联系方式</A> - <A
href="http://www.csdn.net/english">English</A> </TD>
<TD align=middle rowSpan=3><A
href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010"><IMG
height=48 src="80386ASM程序设计基础(十一).files/biaoshi.gif" width=40
border=0></A></TD></TR>
<TR align=middle>
<TD vAlign=top>百联美达美公司 版权所有 京ICP证020026号</TD></TR>
<TR align=middle>
<TD vAlign=top><FONT face=Verdana>Copyright © CSDN.net, Inc. All rights
reserved</FONT></TD></TR>
<TR>
<TD height=15></TD>
<TD></TD></TR></TBODY></TABLE></DIV>
<DIV></DIV><!--结束//--></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -