主要内容:寻址方式;基本指令系统(一)、(二)、(三)
随堂笔记:
基本指令系统(一)
汇编指令概述
寻址方式
1.寄存器寻址
2.立即数寻址
3.存储器寻址 直接寻址、间接寻址、基址寻址和变址寻址
——CPU设计这么多寻址方式是为了在程序设计时对数据读写操作的方便、灵活。
基本指令系统(二)
汇编指令分类:(按功能)
1.传送类指令
2.算术运算类指令
3.位操作类指令
4.处理器控制类指令
5.程序转移类指令
6.串操作类指令
汇编指令分类:(按格式)
1.双操作数指令
2.单操作数指令
3.无操作数指令
注意掌握:
1.指令对操作数的寻址方式
2.指令对标志位的影响、标志位对指令的影响
3.指令的执行时间,对可完成同样功能的指令,要选用执行时间短的指令。
传送类指令:
注意:
1.在五寄存器寻址指令中,需指明内存单元的类型,否则数据类型将出现二义性。
2.两个操作数中,只容许有一个为存储器寻址
3.如果要实现两个内存单元间的数据传送,必须通过两条数据传送指令实现,以寄存器作中转。
4.两个操作数的数据类型要相同
5.立即数不能作为目的操作数
6.指令指针IP,不能作为MOV指令的操作数
交换指令:
堆栈操作指令:
入栈指令:
出栈指令:
注意:出栈顺序一定要和入栈顺序相反
标志位传送指令:
地址传送指令:
算术运算类指令:
ADD
INC
SUB
DEC
NEG
求相反数指令
比较指令
基本指令系统(三)
巩固拓展:
《汇编语言》第三章:寄存器(内存访问)
CPU中,用16位寄存器来存储一个字。高八位存放高位字节,第八位存放低位字节。
3.1内存中字的存储
在内存中存储时,由于内存单元是字节单元(一个单元存放一个字节),则一个字要用两个地址连续的内存单元来存放,这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。
我们提出了字单元的概念:字单元,即存放一个字行数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的地位字节。
3.2 DS和[address]
CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086PC中,内存地址由段地址和偏移地址组成。8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。
比如我们要读取10000H单元的内容,可以用如下程序:
mov bx,1000H mov ds,bx mov al,[0]
mov指令:可以完成两种传送:将数据直接送入寄存器;将一个寄存器中的内容送入另一个
[……]表示一个内存单元,"0"表示内存单元的偏移地址。但是我们知道,只有偏移地址是不能定位一个内存单元的,那么内存单元的段地址是多少呢?
指令执行时,8086CPU自动取ds中的数据位内存单元的段地址。
如何把一个数据送入寄存器呢?
以前用类似“mov ax ,1”这样的指令来完成,相似的方式:mov ds.1000H
可是8086CPU不支持将数据直接送入寄存器的操作,ds是一个段寄存器,所以这条指令是非法的。
只好用一个寄存器来进行中转——mov bx,1000H——mov ds,bx
3.3字的传送
比如:
mov bx,1000H
mov ds,bx
mov ax,[0] //1000:0处的字型数据送入ax
mov [0],cx //cx中的16位数据送到1000:0处
3.4 mov、add、sub指令
3.5 数据段
我们可以将一组长度位N(N <= 64KB)、地址连续、起始地址位16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。
将一段内存当作数据段,是我们在编程时的一种安排。
可以在具体操作的时候,用ds存放数据段的段地址,在根据需要,用相关指令访问数据段中的具体单元。
3.6 栈
栈是一种具有特殊访问方式的存储空间。
操作规则:先进后出
3.7 CPU提供的栈机制
现今的CPU中都有栈的设计,8086CPU也不例外。8086CPU提供相关的指令来以栈的方式访问内存空间。
这意味着,在基于8086CPU编程的时候,可以将一段内存当作栈来使用。
8086CPU提供入栈和出栈的指令,最基本的两个是:
PUSH(入栈)
POP(出栈)
8086CPU的入栈和出栈操作都是以字为单位进行的。
既然我们可以将一段内存来当作栈使用,那么CPU是如何知道当前的栈顶单元?
——也有相应的寄存器来存放栈顶的地址。
在8086CPU中,有两个寄存器,段寄存器SS和寄存器SP
栈顶的段地址存放在SS中,偏移地址存放在SP中。
任意时刻SS:SP指向栈顶元素。
push指令和pop指令执行时,CPU从SS和SP中得到栈顶的地址。
push ax的执行,由两步完成:
1.SP=SP-2,SS:SP指向当前栈顶前面的单元,以当前栈顶前面的单元位新的栈顶。
2.将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。
pop ax的执行,由两步完成:
1.将SS:SP指向的内存单元出的数据送入ax中
2.SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
出栈后,原来位置的数据任然存在,只不过不在栈中。当再次执行push等入栈指令后,SS:SP移至曾经来过的位置,并在里面写入新的数据,并将其覆盖。
3.8栈顶超界问题
新的问题:如何能够保证在入栈、出栈时,栈顶不会超过栈空间?
栈顶超界是危险的,因为我们既然将一段空间安排为栈,那么在栈空间之外的空间里很可能存了其他未知的重要数据、程序……,意外改写麻将会引发一连串错误。
8086CPU 不保证我们对栈的操作不会超界。
也就是说,CPU只知道栈顶在何处,而不知道我们安排的栈空间有多大。
在编程时要操心栈顶超界问题,根据可能用到的最大栈空间,来安排栈的大小。