汇编:8086的内存管理方式及数据寻址方式

8086内存管理方式

80x86内存管理:分段管理,CPU共有20根地址线,最大寻址范围为1MB(2的20次方),8086将1MB空间分为许多段,每个段在内存中占据连续空间,但各段之间可以不相邻。

每个段的最大限制为64KB(2的16次方),按照这个限制,最少可以只有16(2的4次方)个段,那么最多呢?8086又规定段的开始地址要能被16整除,16 = 10000B,去掉后面四个零,剩余部分做为段地址。那么最小的段就是16B,所以最多可以有2^16(2的16次方)个段。

通过上面的计算,我们可以发现某些精心设计的“巧合”,地址总是和16扯上关系,而16位刚好可以存放在一个寄存器中。

段内偏移地址:说明数据在段内的相对位置,由于一个段最大为64KB,所以偏移地址也可以用16位二进制数表示。这里有一个问题,因为段最大为64KB,但是实际并不一定会有最大的段,所以可能存在越界的情况,即偏移地址>段大小,按照操作系统相关知识,此时应该产生越界中断。

如果拿生活中的小区管理来模拟内存管理的话,那么一个段就相当于小区里面的一栋楼,而段内偏移地址就是一栋楼里面某个房间的房间号。

对于8086来说,物理地址可以通过下面公式计算得出:
物理地址 = 段地址*16+偏移地址


在代码段中取指令时,指令的物理地址计算方式:(CS)左移四位+(IP)
在数据段中读写数据时,数据的物理地址计算方式:(DS或ES)左移四位 + 16位偏移地址
在堆栈操作时,栈顶的物理地址计算方式:(SS)左移四位 + (SP)

PUSH,POP规定访问堆栈段,所以按照上面说的堆栈方式寻址

寻址方式

寻址可分为指令寻址和数据寻址
指令寻址:找到下一条欲执行的指令的指令地址,一般由操作系统自动完成。在8086系统中一般由CS:IP给出,所以一般不要改CS、IP的内容。

数据寻址:确定本条指令的操作数地址,除外设数据外的操作数寻址方式有3类:用常量表达的具体数值(立即数寻址)、用寄存器名表示的其中内容(寄存器寻址)、用存储器地址代表保存的数据(存储器寻址)

1、立即数寻址

操作数直接放在指令中,通常用来给寄存器赋值

mov al, 05h
mov dx, 0102h

2、寄存器寻址

操作数存放在寄存器中

mov bx, ax

3、直接寻址

指令中直接包含有效地址(偏移地址),操作数存放在给出的有效地址中

mov ax, [2000h]

4、寄存器间接寻址

操作数有效地址(偏移地址,注意和寄存器寻址的区别:这里是存放地址,而寄存器寻址是数据直接放在寄存器里)存放在寄存器中(8086中只能是 BX、BP、SI、DI),默认段地址存放在DS中,如果寄存器是BP,则段地址放在SS中,可以使用段超越改变。联系高级语言数组,指针。

mov ax, [si]    ==>  ax = ds[si]

5、寄存器相对寻址

操作数有效地址(偏移地址)是寄存器内容和有符号8位或16位位移量之和,寄存器可以是BX、BP、SI、DI,BP默认配SS,其余配DS,可以使用段超越改变。
加了个相对就是在原来的基础上多了个8位或16位的相对位移量。

mov ax, [di+06h]   ==>  ax = ds[di+06h]

6、基址变址寻址

有效地址(偏移地址)由基址寄存器(BX或BP)的内容加上变址寄存器(SI或DI)的内容构成

mov ax, [bx+si]  ==>  ax = ds[bx+si]

7、相对基址变址寻址

有效地址(偏移地址)由基址寄存器(BX或BP)的内容加上变址寄存器(SI或DI)的内容再加上一个8位或16位的位移量构成。就是在基址变址寻址方式的基础上多了一个位移量。

mov ax, [bx+si+06h]  ==>  ax = ds[bx+si+06h]

注意

  • 双操作数指令的源操作数和目的操作数不能都是存储器(主存)寻址方式。
  • 双操作数的指令操作数类型(字节、字)一定要匹配。
  • 指令的目的操作数不能为立即数。
  • 不能将立即数赋值给段寄存器
  • 段寄存器之间不能直接赋值
  • 不能用mov指令改变CS、IP

参考资料

《汇编语言程序设计》钱晓捷 第五版

猜你喜欢

转载自blog.csdn.net/m0_51566872/article/details/127477174
今日推荐