《自己动手写操作系统》于渊跟我们开了个玩笑

lyramilk 2010-03-19 04:00:24
看过的朋友不知道还记不记得下面这两个宏
Descriptor
Gate
如果不记得,那么我可以提示一下

; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; 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那里

; 门 目标选择子, 偏移, DCount, 属性
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate + DA_DPL3

不知道大家有没有试过“DA_386CGate | DA_DPL3”,如果没试过,你可以试试。按理说都是位属性,那么为什么“加号”可以,而“或号”就不行了呢?
关键在于

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

扩展后,其实“加号”的会被扩展为


dw (0 & 0FFFFh)
dw SelectorCodeDest
dw (0 & 1Fh) | ((DA_386CGate + DA_DPL3 << 8) & 0FF00h)
dw ((0 >> 16) & 0FFFFh)


而“或号”的会被扩展为

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

; 宏 ------------------------------------------------------------------------------------------------------
;
; 描述符
; 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 字节

...全文
765 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wybmagic 2011-08-18
  • 打赏
  • 举报
回复
书还是不错的,角度很好,就是文笔有点问题。好多挺简单的东西写得复杂了。
火雲邪神 2010-03-23
  • 打赏
  • 举报
回复
good point
lchhzjx32226 2010-03-23
  • 打赏
  • 举报
回复
呵呵.
也不错了,
有时候就是把简单的问题复杂化了.哥累了.
guogongshao 2010-03-23
  • 打赏
  • 举报
回复
手册很有用,没有手册没法干活!!
lyramilk 2010-03-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sd4189253 的回复:]

顺便问一下,各位同仁认为于渊的书写的怎么样?
有点过于简单!
[/Quote]

刚刚好吧,我觉得我们学编程从两种书中收获的知识最大。
1是某种技术的入门书籍
2是手册
liangchencf 2010-03-22
  • 打赏
  • 举报
回复
顶lz,也顶3楼说心里话的人
sd4189253 2010-03-22
  • 打赏
  • 举报
回复
顺便问一下,各位同仁认为于渊的书写的怎么样?
有点过于简单!
sd4189253 2010-03-22
  • 打赏
  • 举报
回复
顶一下,有心之人!
bjrabbit007 2010-03-21
  • 打赏
  • 举报
回复
呵呵,楼主有心人啊。
huer0625 2010-03-21
  • 打赏
  • 举报
回复
说一句实话,我觉得根本就没有必要设计这个宏。这样我莫名其妙。其实初学者,直接写就可以了。不要搞得那么花哨。呵呵,一家之言,仅供参考。
xiilin 2010-03-20
  • 打赏
  • 举报
回复
哈哈,有趣的问题,没注意过,多谢lz提醒。
lyramilk 2010-03-19
  • 打赏
  • 举报
回复
为什么我非要用或号而不用加号?因为对于位属性来说,用加号是个不好的习惯。
假设我们得到了一个属性,我们想设置它为DPL3,那么我们用"或是"没有任何问题的(属性|DPL3),而如果原属性中已经包含了DPL3,我们再用加号结果就会错误了。

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧