之前第二章讲的重点是理解8086地址的组成方式,相关的寄存器以及6个命令的使用:
r,d,a,e,t,u
第三章继续从访问内存的角度学习寄存器。
3.1 内存中字的存储
一个字由两个字节组成,而一个字节占一个存储单元,所以用16位寄存器来存储一个字
具体存储采用小端法,一个字单元由连续的两个内存单元组成
比如4E20 高字节存在高地址单元;4E存在1号单元 ;低字节存在底地址单元:20存在0号单元
注意的一点是 字单元 和 单元的 区别:
我们可以说0地址字单元中存放字型数据时4E20H,但0单元中时20H,两者不同。
3.2 DS和【address】
8086有一个DS寄存器,通常用来存放要访问的数据的段地址
比如读取10000H单元的内容:
mov bx,1000H
mov ds,bx
mov al,[0]
[..]:代表一个内存单元,其中的数字代表内存单元的偏移地址
mov al ,[0]所使用的段地址来自ds,但ds不能直接写入数据(8086不支持将数据直接送入段寄存器的操作)
所以借助其他的一般性寄存器
3.3.字的传送
8086CPU是16位结构,有16根数据线,可以一次性传送一个字
如:
mov ax,[0];
mov [0],cx;
不过传送字后要注意字的存储方式,小端法,占两个内存单元
3.4.mov,add,sub指令
操作对象:寄存器,常数,内存单元,段寄存器
mov:不支持内存单元与内存单元,段寄存器与常数,段寄存器与段寄存器
注意点: (1 )两个操作数长度要一致。
(3)不能使用mov指令修改CS和IP的值 r cs ; r ip
add:不支持对段寄存器的操作,操作数不能同时是内存单元
sub:两个内存单元不能直接使用sub指令相减,sub指令的操作数不能是段寄存器
3.5.数据段
8086pc机在编程是可根据需要,将一组内存单元定义为一个段,可以将一组长度为N(N<=64kb),地址连续,
起始地址为16的倍数的内存单元当做专门存储数据的内存空间,从而定义一个数据段。
访问时可以用ds存放数据段的段地址,再根据需要,用相关指令访问数据段中的具体单元
3.6./3.7 栈及CPU提供的栈机制
是一个逻辑上的概念,数据存储的方式,可以将一段内存空间当做栈来使用,特性后进先出
8086中栈以字为单位。
栈顶:最后入栈的字数据所对应的地址单元
栈底:固定的一端,栈区最高地址单元的前一个单元
操作:push(入栈),栈顶上移,栈顶-2
pop(出栈),栈顶下移,栈顶+2
栈为空时,栈顶指向栈底+2
两个问题:1.我们把一段内存当成栈来用,CPU如何知道?
2.push,pop需要知道栈顶单元位置,如何知道?
1.与栈相关的寄存器ss和sp
ss:栈段段寄存器,存放栈段的段地址
sp:栈指针寄存器,存放栈顶的偏移地址
2.push ,pop
操作对象:寄存器,内存单元,段寄存器
修改的只是sp,栈顶最大变化范围1位0~FFFFH
push,pop实质上是内存传送指令
示例:
push ax 将寄存器值入栈
pop ax 用寄存器保存出栈数据
有关内存单元,依旧默认段地址在DS中
均以字为单元,操作对象不能是常数
3.8.栈顶超界的问题
要自己注意
3.9。栈的应用
可以恢复数据以及交换数据
对于8086PC机我们可以将长度为N(N<=64kb)的一组地址连续,起始地址为16的倍数的内存单元,当做栈空间使用,
从而定义一个栈段,并将SS:IP指向栈段
其实就和指令和数据的区分一样,值得注意的是超界问题。
一个栈段栈顶范围为0~FFFFH,栈空时SP=0到栈满时SP=0,再次压栈的话会覆盖掉原来的数据
所以一个栈段最大容量为64KB
一段内存,可以既是代码的存储空间,又是数据的存储空间,还可以是栈空间,也可以什么也不是,
关键看CPU寄存器的设置,CS,IP,DS,SS,SP的指向