%macro Descriptor 3 ; 有三个参数:【段界限】、【段基址】、【段属性】
dw %2 & 0FFFFh ; 段界限 1 (2 字节)
dw %1 & 0FFFFh ; 段基址 1 (2 字节)
db (%1 >> 16) & 0FFh ; 段基址 1 (1 字节)
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节)
db (%1 >> 24) & 0FFh ; 段基址 2 (1 字节)
%endmacro ; 共 8 字节
看似很简单的结构体 理解起来可不是那么简单!
【Descriptor结构体】有8个字节。
1、【第1、2字节】组合(word) 表示该段的[段界限①], dw %2 & 0FFFFh ;引用第二个参数去掉高16位
2、【第3、4、5字节】组合表示该段的[段基址①],dw %1 & 0FFFFh ;先得到第一个参数(段基址)低WORD。
3、接着把第5个字节赋值,db (%1 >> 16) & 0FFh 去掉第3第4个字节的内容.再把剩下的字节赋值
4、【第6个字节】是与【第7个字节】组合的内容可就更复杂了:
【第6个字节】的内容:
【7(p) 6(DPL) 5(DPL) 4(S) 3(Type) 2(Type) 1(Type) 0(Type)】
0-3位表示:[段属性]、说明存储段描述符所描述的存储段的具体属性。
4位表示:说明描述符的类型, 对于存储段描述符而言,S=1表示是系统段描述符。
5-6位表示:DPL 该段的特权级别也就是Ring 0-3;
7位表示:P: 存在(Present)位。
; P=1 表示描述符对地址转换是有效的,即描述的段在内存当中.
; P=0 表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常
【第7个字节】的内容:
【7(G) 6(D) 5(0 ) 4(AVL) 3(段界限) 2(段界限) 1(段界限) 0(段界限)】
0-3位表示:[段界限②]
4位表示:软件可利用位。80386对该位的使用未做规定,Intel公司也保证今后开发生产的处理器只要与80386兼容,就不会对该位的使用做任何定义或规定。
5位表示:0 ;Intel资料也没表示
6位表示:是一个很特殊的位,在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同,通常置1
7位表示: 段界限粒度(Granularity)位。
G=0 表示界限粒度为字节;
G=1 表示界限粒度为4K 字节。
注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位。
那么这段宏dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)表示:
取[段界限]参数除去低16位取 高4位,得到【段界限②】
取[段属性]参数的低8位 12-15位(AVL属性等)
属性 1 + 段界限 2 + 属性 2
【第8个字节】的内容:
[段基址②] 、db (%1 >> 24) & 0FFh 取基地址参数的最高8位
那么一个Descriptor 结构体就这样成形了.