一、DS和[address]
1.CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址。
2.在8086PC中,内存地址由段地址和偏移地址组成。
3.8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。
mov al,[0]
已知的mov指令可完成的两种传送功能:
(1)将数据直接送入寄存器;
如mov ax,2
(2)将一个寄存器中的内容送入另一个寄存器中。
如mov bx,ax
除此之外,mov指令还可以将一个内存单元中的内容送入一个寄存器。
4.8086CPU不支持将数据直接送入段寄存器的操作,DS是一个段寄存器。但是8086CPU可以将数据直接送入通用寄存器。
8086CPU5.若想将数据送入段寄存器,首先要先将数据送入通用寄存器,然后将通用寄存器中的内容送入段寄存器。
数据→通用寄存器→段寄存器
二、mov、add、sub指令
1.add和sub指令同mov一样,都有两个操作对象。
2.一个段最大的长度是16位,它的偏移地址最多是ffff(一共16位),16位最大是64KB,所以段的偏移地址是不可能大于64KB的。
我们可以将一组长度为N(N≤64K)、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。
比如我们用123B0H~123B9H这段空间来存放数据:
段地址:123BH
长度:10字节
看段地址的方式:把123B0和123B9向右移一位,就是段地址;
看长度的方式:123B是段地址,偏移地址是0,123B是段地址,偏移地址是9,0到9是十个数字,所以长度是10个字节。
3.
(1)字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。
(2)用mov指令要访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。
(3)[address]表示一个偏移地址为address的内存单元。
(4)在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。
(5)mov、add、sub是具有两个操作对象的指令。jmp是具有一个操作对象的指令。
三、栈
push ax:将通用寄存器ax中的数据送入栈中;
pop ax:从栈顶取出数据送入ax,详细来说就是把当前栈顶地址指向的一个字单元内存中的值放到ax通用寄存器中。
1.8086CPU的入栈和出栈操作都是以字为单位进行的。
CPU如何指导当前要执行的指令所在的位置?
答:寄存器CS和IP中存放着当前指令的段地址和偏移地址。
8086CPU中,有两个寄存器:
段寄存器SS 存放栈顶的段地址
寄存器IP 存放栈顶的偏移地址
任意时刻,SS:SP指向栈顶元素。
执行push ax指令时,事实上是执行两步:
第一步:将SP减二,即SP=SP-2,指向栈顶的指针上移两位;
第二步:然后再把ax中的数据放入栈中;
1.当栈是空的时候,偏移指针SP是指向了栈的最高地址单元的下一位地址10010H,即此时SP=0010H
2.我们将1000H—1000FH这段空间当做栈段,SS=1000H,栈空间大小为16字节,栈最底部的字单元地址为1000:000E。
3.任意时刻,SS:SP指向栈顶,当栈中只有一个元素的时候
SS=1000H,SP=000EH
2.当栈满的时候再使用push指令入栈,栈空的时候再使用pop指令出栈,都将发生栈顶超界问题。
栈顶超界是危险的。
3.push和pop指令是可以在寄存器和内存之间传动数据的。
4.通用寄存器都是以x结尾的,段寄存器都是以s结尾的。
5.数据的段地址永远是从ds中获得,代码的段地址永远是从cs中获得,栈的段地址永远是从ss中获得
一些结论:
1.push、pop 实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由SS:SP指出的。
因为push和pop是对栈进行操作的,SS:SP指的是栈顶的地址,CPU只能识别栈中的栈顶。
2.执行push时:
先改变SP,后向SS:SP处传送;
执行pop时:
先读取SS:SP处的数据,后改变SP。
多尝试,多失败,多让它死机几次,就会接近成功啦!
未完待续