看过的朋友不知道还记不记得下面这两个宏
Descriptor
Gate
如果不记得,那么我可以提示一下
- Assembly code
; 宏 ------------------------------------------------------------------------------------------------------;; 描述符; usage: Descriptor Base, Limit, Attr; Base: dd; Limit: dd (low 20 bits available); Attr: dw (lower 4 bits of higher byte are always 0)%macro Descriptor 3 dw %2 & 0FFFFh ; 段界限 1 (2 字节) dw %1 & 0FFFFh ; 段基址 1 (2 字节) db (%1 >> 16) & 0FFh ; 段基址 2 (1 字节) dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节) db (%1 >> 24) & 0FFh ; 段基址 3 (1 字节)%endmacro ; 共 8 字节;; 门; usage: Gate Selector, Offset, DCount, Attr; Selector: dw; Offset: dd; DCount: db; Attr: db%macro Gate 4 dw (%2 & 0FFFFh) ; 偏移 1 (2 字节) dw %1 ; 选择子 (2 字节) dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 (2 字节) dw ((%2 >> 16) & 0FFFFh) ; 偏移 2 (2 字节)%endmacro ; 共 8 字节; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(copy自OS\Tinix\chapter3\e\pm.inc)
然后再看GDT那里
- Assembly code
; 门 目标选择子, 偏移, DCount, 属性LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate + DA_DPL3
不知道大家有没有试过“DA_386CGate | DA_DPL3”,如果没试过,你可以试试。按理说都是位属性,那么为什么“加号”可以,而“或号”就不行了呢?
关键在于
- Assembly code
dw (%3 & 1Fh) | ((%4 << 8) & 0FF00h) ; 属性 (2 字节)
扩展后,其实“加号”的会被扩展为
- Assembly code
dw (0 & 0FFFFh) dw SelectorCodeDest dw (0 & 1Fh) | ((DA_386CGate + DA_DPL3 << 8) & 0FF00h) dw ((0 >> 16) & 0FFFFh)
而“或号”的会被扩展为
- Assembly code
dw (0 & 0FFFFh) dw SelectorCodeDest dw (0 & 1Fh) | ((DA_386CGate | DA_DPL3 << 8) & 0FF00h) dw ((0 >> 16) & 0FFFFh)
正确的时候生成的这个双字是
00 ec 00 00
与“加号”时是相同的
而“或号”生成的这个双字是
00 60 00 00
虽然示例代码并没有什么错误,但我还是将这两个宏修改了,因为它们不完美#109
下面是修改后的宏,这次再用我喜欢的“|”符号就没有问题啦#39
- Assembly code
; 宏 ------------------------------------------------------------------------------------------------------;; 描述符; usage: Descriptor Base, Limit, Attr; Base: dd; Limit: dd (low 20 bits available); Attr: dw (lower 4 bits of higher byte are always 0)%macro Descriptor 3 dw (%2) & 0FFFFh ; 段界限 1 (2 字节) dw (%1) & 0FFFFh ; 段基址 1 (2 字节) db ((%1) >> 16) & 0FFh ; 段基址 2 (1 字节) dw (((%2) >> 8) & 0F00h) | ((%3) & 0F0FFh) ; 属性 1 + 段界限 2 + 属性 2 (2 字节) db ((%1) >> 24) & 0FFh ; 段基址 3 (1 字节)%endmacro ; 共 8 字节;; 门; usage: Gate Selector, Offset, DCount, Attr; Selector: dw; Offset: dd; DCount: db; Attr: db%macro Gate 4 dw ((%2) & 0FFFFh) ; 偏移 1 (2 字节) dw (%1) ; 选择子 (2 字节) dw ((%3) & 1Fh) | (((%4) << 8) & 0FF00h) ; 属性 (2 字节) dw (((%2) >> 16) & 0FFFFh) ; 偏移 2 (2 字节)%endmacro ; 共 8 字节