免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3054 | 回复: 9
打印 上一主题 下一主题

[CPU及多核] 问个简单的关于选择子赋值给段寄存器的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-04-04 09:44 |只看该作者 |倒序浏览
  1. [SECTION .gdt]
  2. ; GDT
  3. ;                              段基址,       段界限     , 属性
  4. LABEL_GDT:           Descriptor       0,                0, 0           ; 空描述符
  5. LABEL_DESC_CODE32: Descriptor       0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
  6. LABEL_DESC_VIDEO:  Descriptor 0B8000h,           0ffffh, DA_DRW             ; 显存首地址
  7. ; GDT 结束

  8. GdtLen                equ        $ - LABEL_GDT        ; GDT长度
  9. GdtPtr                dw        GdtLen - 1        ; GDT界限
  10.                 dd        0                ; GDT基地址

  11. ; GDT 选择子
  12. SelectorCode32                equ        LABEL_DESC_CODE32        - LABEL_GDT
  13. SelectorVideo                equ        LABEL_DESC_VIDEO        - LABEL_GDT
  14. ; END of [SECTION .gdt]

  15. ...

  16. LABEL_SEG_CODE32:
  17.     mov    ax, SelectorVideo
  18.     mov    gs, ax            ; 视频段选择子(目的)

  19.     mov    edi, (80 * 11 + 79) * 2    ; 屏幕第 11 行, 第 79 列。
  20.     mov    ah, 0Ch            ; 0000: 黑底    1100: 红字
  21.     mov    al, 'P'
  22.     mov    [gs:edi], ax

  23.     ; 到此停止
  24.     jmp    $

  25. SegCode32Len    equ    $ - LABEL_SEG_CODE32
  26. ; END of [SECTION .s32]
复制代码
这是看《ORANGES'_自己动手写操作系统》的源码,关于选择子赋值有个小问题
  1. LABEL_SEG_CODE32:
  2.         mov        ax, SelectorVideo
  3.         mov        gs, ax                        ; 视频段选择子(目的)
复制代码

SelectorVideo这个值是GPT的偏移地址对应到相应的Descriptor宏的结果的地址
  1. Descriptor 0B8000h,           0ffffh, DA_DRW
复制代码
mov ax, SelectorVideo ;这句ax不应该得到的是下面这个字么,怎么会是显存段地址0B800h呢?
  1. dw        %2 & 0FFFFh                                ; 段界限1
复制代码

下面是Descriptor宏代码:
  1. ; 宏 ------------------------------------------------------------------------------------------------------
  2. ;
  3. ; 描述符
  4. ; usage: Descriptor Base, Limit, Attr
  5. ;        Base:  dd
  6. ;        Limit: dd (low 20 bits available)
  7. ;        Attr:  dw (lower 4 bits of higher byte are always 0)
  8. %macro Descriptor 3
  9.         dw        %2 & 0FFFFh                                ; 段界限1
  10.         dw        %1 & 0FFFFh                                ; 段基址1
  11.         db        (%1 >> 16) & 0FFh                        ; 段基址2
  12.         dw        ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh)        ; 属性1 + 段界限2 + 属性2
  13.         db        (%1 >> 24) & 0FFh                        ; 段基址3
  14. %endmacro ; 共 8 字节
复制代码

感谢~

论坛徽章:
0
2 [报告]
发表于 2014-04-04 10:02 |只看该作者
可不可以这样理解,选择子是一个特殊的数据结构,对CPU来说会自动加载段描述符,将段地址赋给ax?

论坛徽章:
0
3 [报告]
发表于 2014-04-04 10:19 |只看该作者
本帖最后由 kkddkkdd11 于 2014-04-04 10:20 编辑

这个好多年前看过点,刚刚查了一下

SelectorVideo是选择子
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
这个选择子,只是个偏移,这样赋值之后是,0级,全局

装入gdtr由cpu干这个事,cpu根据偏移量,完成装入段描述符,不知道解释的是否明白:)

论坛徽章:
0
4 [报告]
发表于 2014-04-04 10:46 |只看该作者
回复 3# kkddkkdd11
感谢回复~
装入的代码我没贴出来:
  1. GdtLen               equ       $ - LABEL_GDT        ; GDT长度
  2. GdtPtr                dw        GdtLen - 1        ; GDT界限
  3.                          dd         0                ; GDT基地址
复制代码
  1.         ; 为加载 GDTR 作准备
  2.         xor        eax, eax
  3.         mov        ax, ds
  4.         shl        eax, 4
  5.         add        eax, LABEL_GDT                ; eax <- gdt 基地址
  6.         mov        dword [GdtPtr + 2], eax        ; [GdtPtr + 2] <- gdt 基地址

  7.         ; 加载 GDTR
  8.         lgdt        [GdtPtr]
复制代码

加载完了之后,GDT的基地址是0,然后由于选择子的TI,RPL都是0所以SelectorVideo的值刚好是对应描述符相对于GDT的基址偏移。
但是就是不明白为什么
mov ax, SelectorVideo
mov gs, ax;
之后 gs中就是显存的基地址

还有个地方就是:
  1.         ; 真正进入保护模式
  2.         jmp        dword SelectorCode32:0        ; 执行这一句会把 SelectorCode32 装入 cs,
  3.                                         ; 并跳转到 Code32Selector:0  
复制代码
执行jmp dword SelectorCode32:0; 这句会跳转到LABEL_SEG_CODE32:这个代码段,但是cs是怎么得到这个代码段的段基地址的?求教~
   

论坛徽章:
0
5 [报告]
发表于 2014-04-04 11:09 |只看该作者
回复 3# kkddkkdd11
找到一篇比较好的文章,可以参考下:
http://blog.csdn.net/littlehedgehog/article/details/2089504
   

论坛徽章:
0
6 [报告]
发表于 2014-04-04 11:37 |只看该作者
回复 3# kkddkkdd11
这个应该就是保护模式下的寻址方式吧,具体操作细节应该是CPU自动完成的。感谢~

   

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
7 [报告]
发表于 2014-04-04 14:50 |只看该作者
对于这类问题建议使用一个cpu模拟器调试一下,跑一条执行看看cpu寄存器状态,一目了然

论坛徽章:
0
8 [报告]
发表于 2014-04-04 15:21 |只看该作者
amarant 发表于 2014-04-04 14:50
对于这类问题建议使用一个cpu模拟器调试一下,跑一条执行看看cpu寄存器状态,一目了然


有道理,bochs好像可以做这类调试:)

论坛徽章:
0
9 [报告]
发表于 2014-04-04 15:26 |只看该作者
回复 7# amarant
好的,有时间我得试下,感谢大家~

论坛徽章:
0
10 [报告]
发表于 2014-05-16 17:25 |只看该作者
intel 32位的机器上,像CS,SS这样的段寄存器分为两个部分,可见部分和不可见部分。可见部分就是常说的段寄存器,防止选择子,不可见部分是也称为描述符缓存。
比如当把kernel_cs赋值给cs的时候,这个时候会把GDT中相应的描述符缓存到cs的不可见区域,以此来提升效率。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP