存贮器


系统存贮器

分为2部分,低地址部分和高地址部分,其中高地址部分叫做上位存贮器(641k-1024k),地址地部分叫做基本存贮器或者基本内存(0-640k)

基本内存比较重要 :1我们的应用程序就放在该内存,dos命令,TSR驻留部分是受保护空间,系统不重启,他的内容就始终存在,这部分主要由dos的常驻程序占据,用户的驻留程序也在此,另外该内存中还有中断向量表,和bios数据区

高端存贮器中A0000到BFFFF用作显示缓冲区,C0000-DFFFF部分为Rom的扩展部分,它用作存储视频显示器适配器和磁盘的Bios和一些网络控制板,I/O接口板,EMS分页帧,F0000-FFFFF该部分有系统引导程序还有系统基本输入输出系统(Bios)

扩展存储器

首先要说明的是系统存储器在0-1024k 之间 扩展存储器在其之上 也就是FFFFH或1M的那部分存储器

 

 

高端地址一般很少用到,Dos5.0以上的版本提供了管理640以上的内存的xms内存管理程序HIMEM.SYS,这样只要在CONFIG.SYS加入下面两行内容:

Divce = c:/Dos/HIMEM.SYS

Dos = HIGH

config.sys他是一个告诉Dos系统配置的的配置文件

 

内存条(EMS)使用的原理

在高端地址中,也就是在A0000H以上的找个连续64kb的地址空间,作为分页帧,每一页占用16kb,一共分为4页,而EMS也分为许多帧,那么就形成了一一对应的关系,然后通过高端地址不停的刷新4个映射从而将EMS遍历完

 

现在的计算机采用20位寻址,相对于16位多了4位,因此采用分段来处理,也就是说在原来16位寻址的基础上增加了4位偏移量地址,从表现来说段地址都是低4位全0。然后它的真实地址是:段地址向左移动4位然后和偏移地址相加。

 


 

让我们回忆一下:

一个程序,系统怎样给他分配地址。一个程序代码区,一个数据存储区,一个堆栈

这就对应了段寄存器:CS,DS,SS,ES;那系统又是怎么分段的?它是将存储器地址分为很多块,称为段,每一段内包含有64k,很显然段地址就形成了,而这64k也就称为其偏移地址那么可以计算出原来的16位寻址+64k的寻址能力4位寻址一共是20位寻址.

cs该段含有要执行的代码指令集合;但是真正要执行的时候就需要CS的段地址+从*IP寄存器取得偏移量

ss堆栈存储器+SP栈指针寄存器 == 栈数据,BP是在SS中传送数据时保存 数据和栈偏移地址

ES主要存放于目的字符串

ES是一个附加的数据段,如用DS作为数据段段地址,SI作为源地址偏移,将一个字符串从源传送到目的区,这个目的区可设在附加段中DI寄存目的区的偏移地址,ES装附加段地址,DI寄存目的区地址的偏移 ,如果使用附加段,用户程序必须对ES初始化,即设置值,否则ES=DS。

 


 存储器操作类型                   约定的段寄存器                  另外可用的段寄存器              偏移地址


取指令                                CS                                                                            IP

堆栈操作                             SS                                                                            SP

取数据或者变量                    DS                                    CS.ES.SS                         有效地址

串操作中取源串                    DS                                    CS.ES.SS                         SI

串操作中写目的串                 ES                                                                            DI

BP被当做基地址                   SS                                    CS.ES.SS                          有效地址


在包含了<dos.h>的情况下 ,我们可以对段地址和偏移地址以及存储的数据进行操作:

#include<dos.h>

#include<stdio.h>

mian()

{

     char far* p;

     unsigned seg,offset;

     //整合段地址和偏移地址

    p = MK_FP(oxb000,0x20);

    //又从该整合的真实地址中取出段地址

    seg = FP_SEG(p);

    off = FP_OFF(p);

    printf("far p %p,segment %04x,offset %0x",p,seg,off);

}

result: far p b0000,0020,segment b000,offset 0x20);

 

他们将写入或者获取一个字节或者一个字到所指出的地址中

char pokeb(unsigned segment,unsigned offset, char value);

 

int poke(unsigned segment,unsigned offset,int value);

 

char peekb(unsigned segment,unsigned offset);

 

int peek(unsigned segment,unsigned offset);

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值