mov、add、sub指令
mov 指令可以有以下几种形式:
mov 寄存器,数据 比如:mov ax,8
mov 寄存器,寄存器 比如:mov ax,bx
mov 寄存器,内存单元 比如:mov ax,[0]
mov 内存单元,寄存器 比如:mov [0],ax
mov 段寄存器,寄存器 比如:mov ds,ax
add 和 sub 指令同 mov 一样,都有两个操作对象。它们有一下几种形式:
add 寄存器,数据 比如:add ax,8
add 寄存器,寄存器 比如:add ax,bx
add 寄存器,内存单元 比如:add ax,[0]
add 内存单元,寄存器 比如:add [0],ax
sub 寄存器,数据 比如:sub ax,9
sub 寄存器,寄存器 比如:sub ax,bx
sub 寄存器,内存单元 比如:sub ax,[0]
sub 内存单元,寄存器 比如:sub [0],ax
延伸出来的方式
mov 寄存器,段寄存器
mov ax,ds
mov 内存单元,段寄存器
mov ax,1000H mov ds,ax mov [0],cs
mov 段寄存器,内存单元
mov ax,1000H mov ds,ax mov ds,[0]
段寄存器
CS: 代码段寄存器
IP:代码段偏移
DS:数据段寄存器
SS:栈顶段寄存器
SP:栈顶段偏移地址栈
任意时刻,SS:SP 指向栈顶元素
push ax的执行,由两步完成。SP = SP - 2,SS:SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶;
- 将ax中的内容送入 SS:SP 指向的内存单元处,SS:SP 此时指向新栈顶。
栈越界
8086 CPU并没有提供是否越界的寄存器,所有我们在编程的时候要自己操作栈顶越界的问题,要根据可能用到的最大栈空间来安排栈的大小,防止入栈出栈的数据太多而导致超界。
pop和push
栈的操作都是以字为单位,即2个字节、16位
#将一个寄存器中的数据入栈
push 寄存器
#出栈,用一个寄存器接收出栈的数据
pop 寄存器
#段寄存器也可以
push / pop 段寄存器
#内存单元
push / pop 内存单元
#比如
mov ax,1000H
mov ds,ax ;内存单元的段地址放在ds中
push [0] ;将1000:0 处的字压入栈中
pop [2] ;出栈,出栈的数据送入 1000:2 处
总结
- 8086 CPU提供了栈操作机制,方案如下,在SS、SP存放栈顶的段地址和偏移地址;提供入栈和出栈指令,他们根据SS:SP 指示的地址,按照栈的方式访问内存单元
- push 指令的执行步骤:a. SP=SP-2;b. 向SS:SP 指向的字单元送入数据
- pop指定的执行步骤:a. 从SS:SP 指向的字单元读取数据;b. SP=SP+2
- 任意时刻,SS:SP 指向栈顶元素
- 8086CPU只记录栈顶,栈空间大小需要自己管理
- 栈特点:FILO,先进后出
- push、pop 实质上是一种内存传送指令,注意灵活使用
实验二
在2000:0 f 内存中,存放了CS,IP,标志寄存器问题:
错误,段寄存器不可在算术指令中。add ds,ax
正确吗?