免费注册 查看新帖 |

Chinaunix

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

[内存管理] 请教386汇编中页映射表的初始化问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-01-16 09:39 |只看该作者 |倒序浏览
我看了个分页的例子,实在看不明白,
现在有几个问题请教:
1、我看例子中,在GDT中定义页目录和页表的物理地址,
那么在装载GDT时,应该也就把它们初始化了,是不是这样?
2、但是,我看例子中的说明提示,又有对页目录和页表的初始化,
请问:如何对它们初始化?
3、如何把页目录与页表,以及页表与某个物理地址对应起来?
因为我看它是说要映射到视频内存,该怎么做?  
4、能否把这个过程说明下

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
2 [报告]
发表于 2014-01-16 11:00 |只看该作者
[quote]netdoger 发表于 2014-01-16 09:39
GDT表中装的是段描述符,如内核和用户态的代码段,数据段等,并不是存放页目录和页表的,两者没啥直接关系。
内核的页目录和页表通常是启动是初始化好,用户进程的都是通过缺页异常动态映射的。

论坛徽章:
0
3 [报告]
发表于 2014-01-16 11:46 |只看该作者
你看例子,GDT中有定义页目录表和页表:
INCLUDE         386SCD.INC
;============================================================================
PDT_AD          =       200000h ;页目录表所在物理页的地址
PT0_AD          =       202000h ;页表0所在物理页的地址
PT1_AD          =       201000h ;页表1所在物理页的地址
PhVB_AD         =       0b8000h ;物理视频缓冲区地址
LoVB_AD         =       0f0000h ;程序使用的逻辑视频缓冲区地址
MPVB_AD         =       301000h ;线性地址0B8000H所映射的物理地址
PhSC_AD         =       303000h ;部分演示代码所在内存的物理地址
LoSC_AD         =       402000h ;部分演示代码的逻辑地址
;============================================================================
GDTSeg          SEGMENT PARA USE16                ;全局描述符表数据段(16位)
;----------------------------------------------------------------------------
                ;全局描述符表GDT
GDT             LABEL   BYTE
                ;空描述符
DUMMY           Desc    <>
                ;规范段描述符及选择子
Normal          Desc    <0ffffh,,,ATDW,,>
Normal_Sel      =       Normal-GDT
                ;页目录表所在段描述符(在保护方式下初始化时用)及选择子
PDT             Desc    <0fffh,PDT_AD AND 0ffffh,PDT_AD SHR 16,ATDW,,>
PDT_Sel         =       PDT-GDT
                ;页表0所在段描述符(在保护方式下初始化时用)及选择子
PT0             Desc    <0fffh,PT0_AD AND 0ffffh,PT0_AD SHR 16,ATDW,,>
PT0_Sel         =       PT0-GDT
                ;页表1所在段描述符(在保护方式下初始化时用)及选择子
PT1             Desc    <0fffh,PT1_AD AND 0ffffh,PT1_AD SHR 16,ATDW,,>
PT1_Sel         =       PT1-GDT
                ;逻辑视频缓冲区段描述符及选择子
LoVideo         Desc    <3999,LoVB_AD AND 0ffffh,LoVB_AD SHR 16,ATDW,,>
LoVideo_Sel     =       LoVideo-GDT
                ;逻辑上的部分演示代码段的描述符及选择子
LoCode          Desc    <SCodeLen-1,LoSC_AD AND 0ffffh,LoSC_AD SHR 16,ATCE,,>
LoCode_Sel      =       LoCode-GDT
                ;预定内存区域(用于部分演示代码)的段描述符及选择子
TPSCode         Desc    <SCodeLen-1,PhSC_AD AND 0ffffh,PhSC_AD SHR 16,ATDW,,>
TPSCode_Sel     =       TPSCode-GDT
;----------------------------------------------------------------------------
                ;以下是需额外初始化的描述符
EFFGDT          LABEL   BYTE
                ;临时代码段描述符及选择子
TempCode        Desc    <0ffffh,TempCodeSeg,,ATCE,,>
TempCode_Sel    =       TempCode-GDT
                ;演示代码段描述符及选择子
DemoCode        Desc    <DemoCodeLen-1,DemoCodeSeg,,ATCE,,>
DemoCode_Sel    =       DemoCode-GDT
                ;演示任务数据段描述符及选择子
DemoData        Desc    <DemoDataLen-1,DemoDataSeg,,ATDW,,>
DemoData_Sel    =       DemoData-GDT
                ;初始化时要移动的代码段描述符及选择子(移动时作为数据对待)
SCode           Desc    <SCodeLen-1,SCodeSeg,,ATDR,,>
SCode_Sel       =       SCode-GDT
;----------------------------------------------------------------------------
GDTLen          =       $-GDT                     ;全局描述符表长度
GDNum           =       ($-EFFGDT)/(SIZE Desc)    ;需特殊处理的描述符数
;----------------------------------------------------------------------------
GDTSeg          ENDS                              ;全局描述符表段定义结束
;============================================================================
;这部分代码在初始化时被复制到预定的内存区域,其功能是在屏幕上显示提示信息
;----------------------------------------------------------------------------
SCodeSeg        SEGMENT PARA USE16
                ASSUME  CS:SCodeSeg,DSemoDataSeg
;----------------------------------------------------------------------------
SBegin          PROC    FAR
                mov     ax,LoVideo_Sel
                mov     es,ax
                mov     di,0
                mov     ah,17h
                mov     cx,MessLen
S1:             lodsb
                stosw
                loop    S1
                JUMP16  DemoCode_Sel,Demo3
SBegin          ENDP
;----------------------------------------------------------------------------
MLen            =       $-SBegin
SCodeLen        =       $
SCodeSeg        ENDS
;============================================================================
DemoDataSeg     SEGMENT PARA USE16                ;演示任务数据段
Mess            DB      'Page is OK!'
MessLen         =       $-Mess
DemoDataLen     =       $
DemoDataSeg     ENDS
;============================================================================
DemoCodeSeg     SEGMENT PARA USE16                ;演示任务代码段
                ASSUME  CSemoCodeSeg
;----------------------------------------------------------------------------
DemoBegin       PROC    FAR
                mov     ax,PDT_Sel
                mov     es,ax
                xor     di,di
                mov     cx,1024
                xor     eax,eax                   ;先把全部表项置成无效
                rep     stosd                     ;再置表项0和表项1
                mov     DWORD PTR es:[0],PT0_AD OR (USU+RWW+PL)
                mov     DWORD PTR es:[4],PT1_AD OR (USU+RWW+PL)
                mov     ax,PT0_Sel                ;初始化页表0
                mov     es,ax
                xor     di,di
                mov     cx,1024
                xor     eax,eax
                or      eax,USU+RWW+PL
Demo1:          stosd
                add     eax,1000h                 ;先全部置成对应等地址的
                loop    Demo1                     ;物理页,再特别设置两广表项
                mov     di,(PhVB_AD SHR 12)*4
                mov     DWORD PTR es:[di],MPVB_AD+USS+RWW+PL
                mov     di,(LoVB_AD SHR 12)*4
                mov     DWORD PTR es:[di],PhVB_AD+USU+RWR+PL
                mov     ax,PT1_Sel                ;初始化页表1
                mov     es,ax
                xor     di,di
                mov     cx,1024
                mov     eax,400000h
Demo2:          stosd                             ;先把全部表项设置为无效
                add     eax,1000h
                loop    Demo2                     ;再特别设置1项
                mov     di,((LoSC_AD SHR 12)AND 3ffh)*4
                mov     DWORD PTR es:[di],PhSC_AD+USU+RWR+PL
                mov     eax,PDT_AD
                mov     cr3,eax
                mov     eax,cr0
                or      eax,80000000h
                mov     cr0,eax
                jmp     SHORT PageE
PageE:          mov     ax,DemoData_Sel
                mov     ds,ax
                mov     si,OFFSET Mess
                JUMP16  LoCode_Sel,SBegin
Demo3:          mov     eax,cr0
                and     eax,7fffffffh             ;关闭分页机制
                mov     cr0,eax
                jmp     SHORT PageD
PageD:          mov     ax,Normal_Sel
                JUMP16  TempCode_Sel,ToDOS
DemoBegin       ENDP
;----------------------------------------------------------------------------
DemoCodeLen     =       $
DemoCodeSeg     ENDS
;============================================================================
TempCodeSeg     SEGMENT PARA USE16                ;临时任务的代码段
                ASSUME  CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual         PROC    FAR
                cld                               ;为演示在启用分页机制后执
                mov     ax,SCode_Sel              ;行位于较高线性地址空间中
                mov     ds,ax                     ;的代码作准备
                mov     ax,TPSCode_Sel
                mov     es,ax
                mov     si,OFFSET SBegin
                mov     di,si
                mov     cx,MLen                   ;把分页演示代码复制到预定
                rep     movsb                     ;内存
                JUMP16  DemoCode_Sel,DemoBegin
ToDOS:          mov     ds,ax
                mov     es,ax
                mov     eax,cr0                   ;准备返回实模式
                and     al,11111110b
                mov     cr0,eax
                JUMP16  <SEG Real>,<OFFSET Real>
Virtual         ENDP
;----------------------------------------------------------------------------
TempCodeSeg     ENDS
;============================================================================
RCodeSeg        SEGMENT PARA USE16                ;实方式的初始化代码和数据
                ASSUME  CS:RCodeSeg,DS:RCodeSeg
;----------------------------------------------------------------------------
VGDTR           PDesc   <GDTLen-1,>
;----------------------------------------------------------------------------
Start           PROC
                push    cs
                pop     ds
                cld
                call    InitGDT                   ;初始化全局描述符表GDT
                EnableA20
                lgdt    QWORD PTR VGDTR           ;装载GDTR
                cli                               ;关中断
                mov     eax,cr0
                or      al,1
                mov     cr0,eax
                JUMP16  <TempCode_Sel>,<OFFSET Virtual>
Real:           DisableA20
                sti
                mov     ax,4c00h
                int     21h
Start           ENDP
;----------------------------------------------------------------------------
InitGDT         PROC
                push    ds
                mov     ax,GDTSeg
                mov     ds,ax
                mov     cx,GDNum
                mov     si,OFFSET EFFGDT
InitG:          mov     ax,[si].BaseL
                movzx   eax,ax
                shl     eax,4
                shld    edx,eax,16
                mov     WORD PTR [si].BaseL,ax
                mov     BYTE PTR [si].BaseM,dl
                mov     BYTE PTR [si].BaseH,dh
                add     si,SIZE Desc
                loop    InitG
                pop     ds
                mov     bx,16
                mov     ax,GDTSeg
                mul     bx
                mov     WORD PTR VGDTR.Base,ax
                mov     WORD PTR VGDTR.Base+2,dx
                ret
InitGDT         ENDP
;----------------------------------------------------------------------------
RCodeSeg        ENDS
                END     Start

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
4 [报告]
发表于 2014-01-17 09:12 |只看该作者
netdoger 发表于 2014-01-16 11:46
你看例子,GDT中有定义页目录表和页表:
INCLUDE         386SCD.INC
;================================ ...

请问你这是哪里的代码?好像没见过呢~

论坛徽章:
0
5 [报告]
发表于 2014-01-17 09:31 |只看该作者
《80X86汇编语言程序设计教程》书上的,是杨季文的

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
6 [报告]
发表于 2014-01-17 11:06 |只看该作者
netdoger 发表于 2014-01-17 09:31
《80X86汇编语言程序设计教程》书上的,是杨季文的

这个应该是特定场景下的特定用途。Linux中不是这样的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP