您的位置:首页 > 其它

保护模式下如何寻址

2010-10-06 11:20 295 查看
此时,段寄存器显然无法直接提供地址,但是它还是很有用的。



实模式下:段值是地址的一部分,如段值XXXXh标示xxxx0h开始的一段内存。

保护模式:段值仅是一个索引,用来指向一个数据结构(其实就是GDT)中的一个表项,此表项中详细定义了段的起始地址、界限、属性。



举例子:

“新政策下的地址仍然用:SEG:OFFSET这样的形式来表示”:这句话什么意思呢,

其实就是无论是实模式还是保护模式,在程序中都是这样来用的,如:(nasm不是masm)

mov [gs:edi],ax

但是样式虽然一样,不同模式的解析方式是不一样的,关于实模式的我就不说了,具体说下保护模式是如何理解上一句话的:

分析:





gs是段寄存器

edi指针在这里做偏移

ax是通用寄存器eax的低16位



在保护模式下:

如果使用上面那个句子,则肯定有类似下面的两条语句:

mov ax, SelectorVideo

mov gs, ax

这两句什么意思啊:

我们把这个Selector..叫做段选择子,顾名思义:段寄存器就是通过它来选择地址的。

这两句代码把gs地址指向SelectorVideo,不过它的内容是什么呢??

程序中式这样定义段选择子的:

SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT

解释:LABEL_DESC_VIDEO 是什么东东呢,原来它就是全局描述符表中的一个表项,LABEL_GDT是第一个表项,那么这个SelectorVideo equ它们的差,说明就是LABEL_DESC_VIDEO这个描述符相对于GDT基址的偏移。

(当然,它还不仅仅如此,它一共16位,高13位的确是地址,但是低3位又有其他意思:分别是0,1位表示RPL(特权级别),2位TI:如果是0表示是GDT的段描述符,如果是1表示是LDT中的)

这里,我们看到:

通过SelectorVideo 我们又联系上了GDT(或者LDT),这样我们就寻到了GDT中的表项:

LABEL_DESC_VIDEO.



这个东东是干什么的??



看定义先:

[section .gdt]

;GDT

LABEL_GDT: Descriptor 0, 0, 0

...

LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; base limit attr

; GDT结束



哈哈,我们终于寻到了段基地址,原来gs真实指向的地址就是0B8000h(显存的首地址),

所以寻址得到的物理地址就是:0B8000h加上edi(偏移地址)。

mov [gs:edi],ax

就是将ax的值写入显存中偏移edi的位置.



整个寻址过程如下:

逻辑地址SEG:OFFSEST-->

SET中的段选择子-->

段选择子中高13位的偏移地址-->

根据段段选择子2位TI的值判断是GDT还是LDT中对应的段描述符-->

根据这个段描述符结构(base,limit,attr)得到 段基地址-->

段基地址+OFFSET就得到线性地址(如果不分页就是物理地址)。



大功告成!!!



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: