第8章 内存管理机制与TC编译模式_第1页
第8章 内存管理机制与TC编译模式_第2页
第8章 内存管理机制与TC编译模式_第3页
第8章 内存管理机制与TC编译模式_第4页
第8章 内存管理机制与TC编译模式_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2022/10/111第八章 内存管理机制与TC编译模式寄存器和伪变量内存的寻址模式TC的编译模式2022/10/112第一节 寄存器和伪变量寄存器是CPU中的部件,用来存储数据、地址和指令C语言中,程序员在编程时可以直接使用寄存器CPU中,寄存器的个数以及每个寄存器的位数会有所不同,取决于CPU的型号2022/10/113第一节 寄存器和伪变量8086、8088、80286的CPU只有14个寄存器,都是16位寄存器,如右图其中:AX、BX、CX、DX是多用途寄存器,又称通用寄存器AX、BX、CX、DX,每个都可以分为两个8位寄存器来使用2022/10/114第一节 寄存器和伪变量CS: 代码

2、段寄存器,用来“指明” 代码段在内存中的起始位置DS: 数据段寄存器,用来“指明”数据段的起始位置数据段可以细分成三部分:初始化为非零的数据区BSS(Block Started by Symbol)堆(Heap)初始化非零数据区一般存放非零静态数据;BSS主要存放未初始化的静态数据;堆,是用来进行动态内存分配的。2022/10/115第一节 寄存器和伪变量ES: 附加段寄存器,用来“指明”附加段的起始位置SS: 堆栈段寄存器,用来“指明”堆栈段的起始位置堆栈(Stack)与堆(Heap)不是同一个东西,堆栈用来存放局部变量和函数参数等数据2022/10/11680386之后的CPU对前十个寄存

3、器做了扩充(32位),同时又增加了两个寄存器FS和GS,如图所示:TC只支持14个寄存器且认为它们都是16位的2022/10/117程序中,有时候需要操作这些寄存器,为了能在TC中使用它们,TC定义了一些伪变量以对应相应的寄存器:_AX: 对应寄存器AX_AH: 对应寄存器AH_AL: 对应寄存器AL_BX: 对应寄存器BX_BH: 对应寄存器BH_BL: 对应寄存器BL_CX: 对应寄存器CX例如:若要将字符 A置于AL中,则可用 :_AL = A;若要将整数100置于AX中,则可用:_AX = 100;2022/10/118第二节 内存的寻址模式实模式寻址保护模式寻址默认的段寄存器近程指针

4、与远程指针与地址操作有关的几个函数(宏)2022/10/119一、内存的实模式8086、8088、80286的CPU都是16位的。对应的数据总线、地址总线、控制总线也“应”是16位。但16位的地址总线只能寻址65536个内存单元(64K),显然太小了。当时认为寻址能力达到1M就够用了,故将地址总线设定成了20位。20位的地址不便于用16位的CPU直接处理,因此当时采用了一种将内存分段的方法来解决这个问题。2022/10/1110从内存的任意一个“地址能被16整除”的单元开始,将该单元之后的共64K内存划为一个“段”之所以要求段的起点必须是16的倍数,是为了把段的首地址存入段寄存器中:因为寄存器

5、是16位的,而内存地址是20位,寄存器只能存储20位地址中的16位数据,所以规定:段寄存器只存前16位,后面4位必须是0(不必存)。00000H00010H00020H00030H00040H00050H.每16Bytes为1小段64K Bytes16进制地址2022/10/1111在一个段内,任意单元的地址都可以用一个相对于段起点的地址来表示,称作偏移地址例如:设段的起始地址是00030H, 则图中00072H单元的偏移地址是0042H偏移地址是一个16位的无符号整数00030H00031H00032H00033H00034H.64K Bytes00072H2022/10/1112段内任意单

6、元的地址都可以表示成“段地址:偏移地址”的形式例如:设数据段的段基址为00030H,则DS寄存器中存储的是0003H,内存00072H单元的地址可表示为:0003:0042(通常写成16进制)段与段可以重叠,如图所示设另一段的首址00050H,此时00072H的地址又可表示为:0005:0022 00030H00031H00032H00033H00034H.64K Bytes00072H00050H64K Bytes2022/10/1113可见,同一个物理地址可有多种不同的表示法采用这种内存分段的方式使寻址能力达到了1M,但是这种寻址方式缺乏对内存的有效保护为了区别后来的保护模式,将上述内存分

7、段寻址的方式称作实地址模式或内存的实模式。00030H00031H00032H00033H00034H.64K Bytes00072H00050H64K Bytes2022/10/1114二、内存的保护模式为了保护内存,需要记录段的首地址、段长度、段的访问权限等信息,这些信息合起来是一个64位的数据结构(结构体变量)-段描述符显然,段寄存器存储不下这个段描述符解决方法:在内存中开辟一段区域,把所有段的段描述符按顺序存入其中,组成一个段描述符表段寄存器中只存储段描述符的索引(段选择子)2022/10/1115三、默认的段寄存器CS: 总是存储代码段的段地址DS: 总是存储数据段的段地址ES: 总

8、是存储附加段的段地址SS: 总是存储堆栈段的段地址2022/10/1116四、近程指针和远程指针近程指针是一个16位的指针,用来在段内寻址。近程指针在定义时,使用near关键字说明(可以省略)如:int near *p; /或 int *p;p存储的是偏移地址,用于段内寻址,而段地址由相应的段寄存器中的数据决定2022/10/1117四、近程指针和远程指针近程指针的最大值只能到0 xffff,即65535,超过将出错。如:char near *p;p = (char near *)0 xffff;p+;printf(“%pn”, p); / %p是用十六进制输出地址其运行结果是:0000因为6

9、5535加1将产生进位(丢弃),使p的16位都是0。这种现象称作折回。2022/10/1118四、近程指针和远程指针远程指针是一个32位的指针,用来寻址不同的段。其中高位的两个字节存储段值,低位的两个字节存储偏移地址。由于远程指针对应的单元可能在不同的段,故使用远程指针会使段寄存器中的段值发生改变。远程指针定义时用far说明,如:char far *p;p = (char far*)0 x2A000002;对远程指针加减运算,只对偏移地址进行,段地址不参与运算,故也会发生折回现象。2022/10/1119四、近程指针和远程指针对于同一个物理地址,用“段地址:偏移地址”的方式表示时,可以有若干种

10、形式,如物理地址1234H可以表示为:0000:1234, 0001:1224, 0002:1214, 虽然这些地址表示的是同一物理地址,但如果对它们进行比较,得出的结果是不相等。 设远程指针p1、p2存储的是同一物理地址,但段地址和偏移地址不同,则表达式p1= p2的值为0。因为计算机是直接比较两个指针变量中的32位二进制数,而不是转化为物理地址后再比较。2022/10/1120五、与地址操作有关的几个函数TC在dos.h中定义了几个函数(实际是宏),用来处理段地址或偏移地址FP_SEGFP_OFFMK_FPpeekb和peekpokeb和poke2022/10/1121五、与地址操作有关的

11、几个函数1、FP_SEG功 能:获取远地址中的段值原型:unsigned FP_SEG(void far *farptr); 例8.1 #include #include int main() char far *filename = “fpseg.c”; printf(%04xn,FP_SEG(filename); /0表示用0补足4位 return 0;2022/10/1122五、与地址操作有关的几个函数2、FP_OFF功能: 获取远地址中的偏移地址原型: unsigned FP_OFF(void far *farptr);例8.2#include #include int main()

12、char far *str = fpoff.c; printf(%04xn , FP_OFF(str); return 0;2022/10/1123五、与地址操作有关的几个函数3、MK_FP功能:由段值和偏移地址组成一个远程指针。原型:void far *MK_FP(unsigned seg, unsigned off);例8.3 (主要程序段): char far *p; unsigned seg, off; p = MK_FP(0 xb000, 0 x20); seg = FP_SEG(p); off = FP_OFF(p); printf(“far p:%Fp,seg:%04X,off:

13、%04Xn”, p,seg,off); 2022/10/1124五、与地址操作有关的几个函数4、peekb和peek功能:按给定的地址从内存读取一个字节或一个字原型: char peekb(unsigned seg, unsigned off); int peek(unsigned seg, unsigned off);例如: char c, s=“hello”; /s数组在栈区 c=peekb(_SS, s); printf(%cn, c);输出结果是:h 2022/10/1125五、与地址操作有关的几个函数5、pokeb和poke功能:向指定的位置写一个字节或一个字原型:void pokeb(unsigned seg, unsigned off, char value);void poke (unsigned seg, unsigned off, int value);例如:char s10;int a=0 x0041;poke(_SS, s, a);printf(“%sn”, s);输出结果是:A 2022/10/1126第三节 TC的编译模式微模式(Tiny)小模式(Small) 中模式(Medium) 紧凑模式(Compact)大模式(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论