汇编语言第三章知识梳理及思考
第三章
内存访问的角度学习寄存器
3.1内存中字的存储
0号单元是低地址单元,1号单元是高地址单元。
问题:
(1)0地址单元(字节单元)中存放的字节型数据是多少?20H
(2)0地址字单元中存放的字型数据是多少?4E20
(3)2地址字单元中存放的字节型数据是多少?12H
(4)2地址单元中存放的字型数据是多少?0012H
(5)1地址字单元中存放的字型数据是多少?124EH
结论:任何两个连续的内存单元,N号单元和N+1号单元,可以将它们看成一个地址为N的字单元中的高位字节单元N+1和低位字节单元N。
3.2DS和[address]
CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址;在8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。执行指令时,8086CPU自动从DS中的数据为内存单元的段地址。
MOV指令的格式:
MOV 寄存器名,内存单元地址
“[……]”表示一个内存单元,“[……]”中的0表示内窜单元的偏移地址。
问题:能不能mov ds,1000
8086CPU不支持将数据直接送入段寄存器的操作,ds是一个段寄存器。数据>>通用寄存器>>段寄存器
将数据从寄存器送入内存单元:
MOV BX,1000H
MOV DS,BX
MOV [0],AL
3.3字的传送
3.4mov、add、sub指令
以学的mov指令的几种形式:
MOV 寄存器,数据
MOV AX,1234
MOV 寄存器,寄存器
MOV AX,BX
MOV 寄存器,内存单元
MOV AX,[0]
MOV 内存单元,寄存器
MOV [0],AX
MOV 段寄存器,寄存器
MOV DX,AX
根据已知的指令进行推测:
MOV 段寄存器,寄存器
验证有效
MOV 内存单元,段寄存器
MOV 段寄存器,内存单元
对add、sub的总结:
问题:它们可以对段寄存器进行操作吗?
验证结果:不能。
3.5数据段
DS—>数据段 CS—>代码段
小结:
1. 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在地地址单元中高位字节存放在高地址单元中。
2. 用mov指令访问内存单元,可以在mov指令中只给出内存单元的偏移地址,此时,段地址默认在DS寄存器中。
3. [address]表示一个偏移地址为address的内存单元。
4. 在内存和及窜起之间传递字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。
5. MOV、ADD、SUB是具有两个操作对象的指令。JMP是具有一个操作对象的指令。
6. 可以根据自己的推测,在Debug中实验指令的新格式。
3.6栈
8086CPU提供入栈和出栈指令(最基本的):
PISH(入栈)
POP(出栈)
PUSH AX :将寄存器ax中的数据送入栈中;
POP AX :从栈顶取出数据送入ax;
8086CPU的入栈和出栈操作都是以字位单位进行的。
两个疑惑:
1. CPU如何知道一段内存空间被当作栈使用?
寄存器cs和ip中存放着当前指令的段地址和偏移地址。
8086CPU中有两个寄存器:
段寄存器ss 存放栈顶的段地址
寄存器sp 存放栈顶的偏移地址
任意时刻,ss:sp指向栈顶元素
2. 执行push和pop的时候,如何知道哪个单元是栈顶单元?
任意时刻,ss:sp指向栈顶元素
PUSH指令的执行过程:
(1) sp=sp-2;
(2) 将ax中的内容送入ss:sp指向的内存单元处,ss:sp此时指向新栈顶;
POP指令执行过程:
(1) 将ss:sp指向的内存单元处的数据送入ax中;
(2) sp=sp+2,ss:sp指向当前栈顶下面的单元,以当前栈顶下面的单元为新栈顶。
问题:如果我们将10000H~1000FH这段空间当作栈,初始状态栈是空的,此时,ss=1000H,sp=?
栈空,ss:sp指向占空间最高地址单元的下一个单元。
任何时刻,ss:sp指向栈顶元素,当栈为空的时候,栈中没有元素,也就不存在栈顶元素。所以ss:sp只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2。
3.8栈顶超界的问题
在编程的时候要自己小心栈顶超界的问题,要根据可能用到的最大栈空间来安排栈的大小,防止入栈的数据与太多而导致的超界;执行出栈的时候继续出栈二导致的超界。
3.9push、pop指令
push和pop指令的格式(1)
push 寄存器 将一个寄存器中的数据入栈
pop寄存器 用一个寄存器接收出栈的数据
push和pop指令的格式(2)
push 段寄存器 将一个段寄存器中的数据入栈
pop 段寄存器 用一个段寄存器接收出栈的数据
push和pop指令的格式(3)
push 内存单元 将一个内存单元处的字入栈(栈操作都是以字为单位)
pop内存单元 用一个内存字单元接收出栈的数据
push、pop实质上就是一种内存传送指令,可以在寄存器和内存之间传送数据,与mov指令不同的是,push和pop指令访问的内存单元的地址不是在指令中给出的,而是由ss:sp指出的。
执行push时:先改变sp,后向ss:sp处传送。
执行pop时:先读取ss:sp处的数据,后改变sp。
栈顶的最大变化范围为0~FFFFH。
3.10栈段
我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问内存单元。数据段放在DS中,代码段放在CS中,栈段放在SS中。一段内存可以是代码的存储空间,又可以是数据的存储空间,还可以是栈空间,也可以什么都不是。关键在于CPU中寄存器的设置,即CS、IP、SS、SP、DS的指向。