3.1内存以字节为单位,划分为若干个单元。
字数据的存-取原则:高-高 低-低
即:
① 字数据的低位字节存放在低地址内存单元;
字数据的高位字节存放在高地址内存单元;
② 取低地址内存单元地址作为字数据地址
小端法
3.2要在CPU和内存单元之间传送数据,就必须知道内存单元的地址。
DS: 数据段段寄存器,用于存放数据段的「段地址」
说明:
(1)将一段内存用作数据段,是编程时的一种安排;
(2)在mov, add, sub等汇编指令中,访问内存单元时,默认情况下,指的是数据段。
3.3
汇编指令mov, add, sub
例:假定(DS)=2000H,(ES)=2100H, (SS)=1500H, (SI)=00A0H, (BX) =0100H,(BP)=0010H,数据段中变量名VAL的偏移地址为0050H,试指出下列源操作数字段的寻址方式是什么?其物理地址值是多少?
(1) MOV AX, OABH 立即寻址 操作数在指令中
(2) MOV AX, BX 寄存器寻址操作数为(BX) =0100H
(3) MOV AX, [100H] 直接寻址20100H
(4) MOV AX, VAL 直接寻址20050H
(5) MOV AX, [BX] 寄存器间接寻址20100H
(6) MOV AX, ES:[BX] 寄存器间接寻址21100H
(7) MOV AX, [BP] 寄存器间接寻址15010H (BP默认段为SS)
(8) MOV AX, [SI] 寄存器间接寻址200A0H
(9) MOV AX, [BX+10] 寄存器相对寻址20110H
(10) MOV AX, VAL [BX] 寄存器相对寻址20150H
(11) MOV AX, [BX][SI] 基址变址寻址201A0H
(12) MOV AX,VAL[BX][sI] 相对基址变址寻址201FOH
注意mov指令
(1) 两个操作数长度要一致。
(2) 关于常数(也叫立即数):
1.不能作为第1个操作数(目的操作数)
2.作第2个操作数(源操作数)时,如果最高位是十六进制的a~f或A~F,前面要加零!
(3) 两个内存单元之间不能直接传送数据。
(4) 不能使用mov指令修改CS和IP的值。
(5)① 两个段寄存器之间不能直接传送;
② 不能把常数送到段寄存器。
注意add指令
(1) add指令的操作数不能同时是内存单元
(2) add指令的操作数不能是段寄存器。
注意sub指令
(1) 两个内存单元不能直接使用sub指令相减。
(2) sub指令的操作数不能是段寄存器。
3.4
栈的特性: 后进先出
两个概念: 栈底、栈顶
两个操作: 入栈、出栈
一个约定: 8086中栈以字为存取单位
栈的大小是靠我们自己决定的,如何确定这段内存为栈,就需要两个寄存器,段寄存器ss和存放偏移地址的寄存器sp,比如我们决定10000-1000f为寄存器那么ss:sp一开始应该为 1000:0010执行栈有两个指令push,pop,push是入栈执行过程是先sp+2之后在把数据放进去,pop指令是先出栈,先将指令放进栈接着再sp-2。
栈最大为64kb,这和sp的寻址能力有关,比如10000-1ffff为栈,那么ss:sp一开始应该指向那里呢?按照之前的算法sp应该为ffff+1 = 10000但是sp只能储存4个字节所以sp = 0,当栈满了之后sp还是为0,这个时候再次入栈0-2 = fffffffe,所以sp = fffe,之后再次入栈的话就会将原数据给覆盖掉,所以要尽量避免这种情况。
「栈」操作指令: push和pop
注意:以下两种情形会发生「栈顶超界」问题:
当栈满的时候,再使用push指令入栈;
当栈空的时候,再使用pop指令出栈;
3.5关于「段」的小结
(1) 「段」是一个逻辑上的概念。
编程时,可根据需要指定一段内存区用作数据段、代码段或是栈段。
(2) 用作数据段时,要把段地址→DS
用作栈段时,要把段地址→SS,栈顶偏移地址 → SP
用作代码段时,段地址→CS,要取的指令偏移地址→IP。但CS和IP的值不能使用mov改变。
(3) 一段内存可以同时用作代码段、数据段、栈段。
由编程时灵活确定。
(4) 在8086CPU中,每个段的最大长度不能超过64KB。
(因为寄存器是16位的,能表示的地址范围只能是0000H~FFFFH,即0~216-1)