首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

(第三章 三)数据段/代码段描述符

2012-10-25 
(第三章 3)数据段/代码段描述符一、宏定义和属性常量(代码段/数据段描述符见P32;门描述符见P51)下面是对代

(第三章 3)数据段/代码段描述符

一、宏定义和属性常量

(代码段/数据段描述符见P32;门描述符见P51)

下面是对代码段/数据段描述符的宏定义,目的是为了方便编写描述符。

?

; 描述符; usage: Descriptor Base, Limit, Attr;        Base:  dd  -->段基址4字节;        Limit: dd (low 20 bits available)  -->段界限20位,放心大胆地用4字节(32位)表示界限,只不过经转换只用到其中20位;        Attr:  dw (lower 4 bits of higher byte are always 0)  -->%3 & 0F0FFh,因为高字节的第4位为段界限2的位置%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 字节
?

下面定义一些常量,便于在编写描述符时设置属性:

?

; 描述符类型DA_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; 存在的可执行可读一致代码段属性值; 系统段描述符类型DA_LDTEQU  82h; 局部描述符表段类型值DA_TaskGateEQU  85h; 任务门类型值DA_386TSSEQU  89h; 可用 386 任务状态段类型值DA_386CGateEQU  8Ch; 386 调用门类型值DA_386IGateEQU  8Eh; 386 中断门类型值DA_386TGateEQU  8Fh; 386 陷阱门类型值

注意到代码段和数据段描述符中和属性相关的字段(从Byte0算起,Byte5和Byte6),如下:

Byte5:

?? ? 0~3位: ?TYPE

?? ? 4位: ? ? ? ?S

?? ? 5~6位: ?DPL

?? ? 7位: ? ? ? ?P

Byte6:

?? ? 0~3位: ?段界限2

?? ? 4位: ? ? ? ?AVL

?? ? 5位: ? ? ? ?固定为0

?? ? 6位: ? ? ? ?D/B

?? ? 7位: ? ? ? ?G

?

?

二、宏和属性常量的使用(重点在属性的设置上):

?

[SECTION .gdt]; GDT;                              段基址,      段界限     , 属性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 结束GdtLenequ$ - LABEL_GDT; GDT长度GdtPtrdwGdtLen - 1; GDT界限dd0; GDT基地址,在后面代码中再指定(略); GDT 选择子SelectorCode32equLABEL_DESC_CODE32- LABEL_GDTSelectorVideoequLABEL_DESC_VIDEO- LABEL_GDT; END of [SECTION .gdt]...

?

1、设置属性:

?

理解“32位代码段”中对属性的设置(DA_C+DA_32):

1)DA_32——32位段

?

DA_32EQU4000h; 32 位段

?? ? 4000h=0100,0000,0000,0000b,也就是将“D/B位”设置为1,由P36对“D/B位”的说明可知,当这个段是可执行代码段时,称为D位。D=1,则在默认情况下指令使用32位地址及8位操作数(因此,在这个段中用“选择子”代替“段基值”);D=0,则默认情况下用16位地址及16位或8位操作数。

2)DA_C——在内存中存在的可执行代码段/数据段

?

DA_CEQU98h; 存在的只执行代码段属性值

?? ? 98h=0000,0000,1001,1000b,也就是将

?? ? TYPE设置为1000,表示可执行。见P36

?? ? S设置为1,表示是数据段/代码段描述符(如果S=0,表示是系统段/门描述符)。见P36

?? ? P设置为1,表示在内存中存在。见P35

?

理解“显存段”中对属性的设置(DA_DRW):

1)DA_DRW——在内存中存在的可读写代码段/数据段

?

DA_DRWEQU92h; 存在的可读写数据段属性值

?? ? 92h=0000,0000,1001,0010,也就是将

?

?? ? TYPE设置为0010,表示可读写。见P36

?? ? S设置为1,表示是数据段/代码段描述符(如果S=0,表示是系统段/门描述符)。见P36

?? ? P设置为1,表示在内存中存在。见P35

?


2、设置段基址:

?

LABEL_DESC_CODE32: Descriptor       0, SegCode32Len - 1, DA_C + DA_32; 其中段基址在后面代码中再指定(略)LABEL_DESC_VIDEO:  Descriptor 0B8000h,           0ffffh, DA_DRW     ;

1)在[SECTION .s16]中设置了第一行这个32位对应的段基址(该段做从实模式转入保护模式前的准备工作):

?? ?? ... ...

 [SECTION .s16][BITS16]LABEL_BEGIN:        ... ...; 初始化 32 位代码段描述符xoreax, eaxmovax, csshleax, 4addeax, LABEL_SEG_CODE32movword [LABEL_DESC_CODE32 + 2], axshreax, 16movbyte [LABEL_DESC_CODE32 + 4], almovbyte [LABEL_DESC_CODE32 + 7], ah        ... ...; 真正进入保护模式jmpdword SelectorCode32:0[SECTION .s32]; 32 位代码段. 由实模式跳入.[BITS32]LABEL_SEG_CODE32:... ...
2)显存段的段基址固定为0B8000h,故在编写描述符时就写好了3)gdt开始那个段规定为全0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

?

预习:下面是门描述符

?

; 门

; usage: Gate Selector, Offset, DCount, Attr

; ? ? ? ?Selector: ?dw

; ? ? ? ?Offset: ? ?dd

; ? ? ? ?DCount: ? ?db

; ? ? ? ?Attr: ? ? ?db

%macro Gate 4

dw(%2 & 0FFFFh); 偏移1

dw%1; 选择子

dw(%3 & 1Fh) | ((%4 << 8) & 0FF00h); 属性

dw((%2 >> 16) & 0FFFFh); 偏移2

%endmacro ; 共 8 字节

?

热点排行