第3章指令系统.docx
《第3章指令系统.docx》由会员分享,可在线阅读,更多相关《第3章指令系统.docx(29页珍藏版)》请在冰豆网上搜索。
第3章指令系统
第三章MCS-51系列单片机的指令系统
重点及难点:
51系列单片机的寻址方式、数据传送指令、算术运算类指令、逻辑运算与移位类指令、控制转移类指令、位操作指令。
教学基本要求:
1、掌握51系列单片机的寻址方式;
2、掌握数据传送指令的格式、功能和使用方法;
3、掌握算术运算类指令的格式、功能和使用方法;
4、掌握逻辑运算与移位类指令的格式、功能和使用方法;
5、掌握控制转移类指令的格式、功能和使用方法;
6、掌握位操作指令的格式、功能和使用方法。
教学内容
§3.1指令系统概述
一、几个基本概念
指令:
计算机能够直接识别执行的命令即为指令也称为机器指令或机器语言。
指令系统:
一台计算机所能执行的所有指令的集合即为指令系统
一台计算机的指令系统很大程度上决定了它的能力和使用是否方便灵活。
比如有的指令系统中拥有乘法指令,而有的没有,这样当需要使用乘法运算时,拥有乘法指令的计算机就方便得多。
由于机器语言记忆和理解都很困难,为了解决这个问题,采用助记符的方式来表示指令,这就时所谓的汇编语言。
指令系统是由计算机生产厂家预先定义的,用户必须遵循这个预定的规定。
因为不同的生产厂家定义不一样,所以各厂家生产的单片机的指令系统也不一样,所以通过机器语言或汇编语言书写的程序没有通用性。
二、指令的格式
指令格式通常如下:
<操作码>[操作数]
操作码是用来指定指令的功能的,而超作数则是指令操作的对象。
比如做加法运算:
ADDA,R0就表示将寄存器A和R0中的数据相加然后将结果存放到A寄存器中。
在这里ADD即为操作码,A和R0即为操作数。
指令有定长和不定长之分,定长指令其操作码的位数为一定值,不定长指令其操作码为变动的,一般使用频率最高的采用最短的操作码。
单片机一般采用的是不定长指令格式,我们根据指令的长短又将指令分为一字节指令、二字节指令、三字节指令。
一字节指令即在程序存储器中需要一个字节的单元来存储;二字节指令即在程序存储器中需要二个字节的单元来存储;三字节指令即在程序存储器中需要三个字节的单元来存储。
§3.2寻址方式
所谓的寻址就是指的寻找超作数的地址。
由于大多数指令都需要操作数,而操作数往往均存储在存储器中,因此在使用超作数的过程中就存在一个寻找存储单元的问题。
在MCS-51系列单片机中共有7中寻址方式:
寄存器寻址、立即寻址、直接寻址、寄存器间接寻址、变址寻址、相对寻址、位寻址。
1、寄存器寻址:
寄存器寻址方式就是操作数存储在寄存器中,指定寄存器就得到了操作数,例如:
MOVA,R0
就是将寄存器R0中的数据传送到A中,这样通过直接指定寄存器的方式进行寻址即为寄存器寻址。
可以采用这种方式进行寻址分寄存器包括通用寄存器和部分专用寄存器,比如累加器A、B寄存器、
2、直接寻址
直接寻址就是直接在指令中指定操作数的地址,比如:
MOVA,3AH代表的意思就是将地址为3AH的存储单元中数据取出来传送给累加器。
这里的操作数就是直接通过数据存储器的地址3AH来指定的。
直接寻址方式的寻址范围仅限于内部数据存储器。
对于内部数据存储器的低128个字节可以直接通过地址的方式来指定,而对于高128个字节除了可以通过地址的方式来指定外还可以通过特殊功能寄存器的寄存器符号给出。
3、寄存器间接寻址
寄存器间接寻址就是通过寄存器指定数据存储单元的地址,寄存器中存储的是地址。
采用用寄存器间接寻址方式时应在寄存器前加上@符号。
比如:
MOVEA,@R0它的功能就是将R0中所存储的地址所指向的存储单元中的数据取出来传送到累加器中去。
对于这种寄存器间接寻址,用来存储地址的寄存器只能为R0或R1或DPTR。
其中R0和R1用来访问片内数据存储器的低128字节和片外数据存储器的低256字节,DPTR用来访问片外数据存储器。
比如MOVXA,@DPTR
4、变址寻址
变址寻址是以某个寄存器的内容为基础,然后在这个基础上再加上地址偏移量,形成真正的操作数地址,需要特别指出的是用来作为基础的寄存器可以是PC或是DPTR,地址偏移量存储在累加器A中比如:
MOVA,@A+DPTR,其意思就是将DPTR内存储的地址和A里面的偏移量相加最后根据得到的地址来查找相应的存储单元。
5、立即寻址
立即寻址就是直接将需要访问的数据在指令中给出,这样的寻址方式就是立即寻址。
立即寻址的方式为:
MOVA#30H。
值得注意的一点是:
在立即数寻址中立即数前面必须要加上一个“#”号。
6、位寻址
位寻址方式是指将要访问的数据是一个单独的位,指定位数据的方式有:
通过位地址、通过字节地址加点及位数、通过寄存器名加点及位数、通过位的名称。
7、相对寻址
相对寻址主要是针对跳转指令而言的。
对于跳转指令,跳转去的目标指令的地址是通过正在执行的指令地址来确定的,一般是采用正在执行的指令地址加上偏移量的方式。
偏移量可以是正也可以是负,偏移量是采用有符号数的存储形式即补码的形式来存储的。
§3MCS-51系列单片机的指令系统
一、数据传送类指令
数据传送类指令就相当于C语言中的赋值语句,它的作用就是将某一个操作数复制到其它存储单元中去,其一般格式为:
MOV目的操作数源操作数
其中目的操作数不能采用立即寻址的方式。
根据目的操作数和源操作数的不同可以将数据传送指令分为六类:
1、内部RAM中数据传送指令
(1)、立即数传送指令
立即数传送指令共有四条分别为:
MOVA,#data
MOVdirect,#data
MOVRn,#data
MOV@Ri,#data
除此以外还有一个很特殊的寄存器寻址指令:
MOVDPTR,#data
这五条指令均是将立即数传送内部RAM中去
(2)、内部RAM的存储单元中的数据传送,共五条指令
MOVdirect2,direct1
MOVdirect,Rn
MOVRn,direct
MOVdirect,@Ri
MOV@Ri,direct
(3)、通过累加器的数据传送指令,共六条
MOVA,direct1
MOVdirect,A
MOVRn,A
MOVA,Rn
MOVA,@Ri
MOV@Ri,A
2、外部RAM数据传送指令
外部RAM中数据传送均是通过间接寻址的方式来实现的,共有四条指令:
MOVXA,@DPTR
MOVXA,@Ri
MOVX@DPTR,A
MOVX@Ri,A
其中需要注意的几点是:
(1)、这里的地址寄存器只能使用DPTR和Ri,并且当使用Ri时只能访问外部RAM的的256字节。
(2)、与外部RAM传送数据只能通过累加器A来实现。
(3)、与外部RAM传送数据时使用MOVX指令。
3、程序存储器传送指令
程序存储器数据传送指令必须使用MOVC,并且只能通过累加器A来实现。
共两条指令:
MOVCA,@A+PC
MOVCA,@A+DPTR
由于程序存储器只能读不能写,因此程序存储器的数据传送都是单向的。
4、数据交换指令
数据交换主要用在累加器和其它内部RAM中的数据交换,数据交换指令分为三类:
整字节交换,使用指令XCH,比如:
XCHA,Rn
它表示将A内的数据和Rn中的数据交换,其中指令中目的操作数只能使用累加器A,源操作数可以是直接寻址、寄存器寻址、寄存器间接寻址
半字节交换
XCHDA,@Ri
注意半字节交换指令使用这一种方式,它实现的功能是将累加器A中的低四位和(Ri)中的低四位进行交换。
累加器高低半字节交换指令
SWAPA,其作用就是将A中的高低四位互换
5、堆栈操作指令
PUSH表示压栈、POP出栈
二、算术运算类指令
1、加法指令ADD
加法指令的格式如下:
ADDA,源操作数
其中要注意的几点:
(1)源操作数可以是立即数,也可以是直接寻址、寄存器寻址、寄存器间接寻址,但目的操作数必须是累加器。
该指令代表的意思是将A中的数据和源操作数相加然后将结果写入A中。
(2)该运算会影响程序状态字PSW中的CY、AC、OV
2、带进位加法指令ADDC
带进位加法指令ADDC的基本格式和ADD指令相似,唯一不同的是计算加法时同时还要加上CY中的值。
3、带借位减法指令SUBB
带借位减法指令的格式和ADDC差不多,其结果是先用被减数减去减数后再减去CY。
4、加1指令INC和减1指令DEC
这两个指令均可实现对累加器、寄存器、直接寻址方式以及寄存器间接寻址方式下的存储单元进行加1或减1。
值得指出的几点:
(1)加1减1指令不影响程序状态字PSW
(2)对于DPTR只能使用加1指令,不能使用减1指令。
5、乘除法指令MUL、DIV
乘除法指令是整个单片机指令系统中执行时间最长的指令,乘除法运算均只能使用A、B两个寄存器。
这两条指令均影响PSW中的CY位和OV位,其总是将CY位清0,然后根据运算结果对OV位进行操作。
6、十进制调整指令DA
其格式如下:
DAA
该指令的功能主要是对上一次运算压缩BCD码存储十进制数进行加法运算时修正加法运算结果。
在单片机内部,该指令的修正方法是这样的:
(1)如果八位BCD码运算中低四位大于9或AC等于1结果低四位加上6,即整个字节加上06
(2)如果高四位大于9或CY大于1则高四位加上6,即整个字节加上60;
(3)如果高四位等于9,低四位大于9则高低四位均需要加上6,即整个字节加上66。
例:
A=56H,R5=67H,其中A和R5中均存储的为十进制数BCD码,执行如下指令:
ADDA,R5
DAA
结果为:
A=23H,CY=1。
三、逻辑运算与移位类指令
逻辑运算包括与、或和异或3类指令,每类有6条指令,此外,还有累加器A清零、求反的指令和4条移位指令。
本节我们将学习这24条指令。
1、逻辑与运算指令组
逻辑运算都是按位进行的,逻辑与运算用符号“∧”表示。
6条逻辑与运算指令如下:
ANL
A,
Rn
;A←(A)∧(Rn)
ANL
A,
direct
;A←(A)∧(direct)
ANL
A,
@Ri
;A←(A)∧((Ri))
ANL
A,
#data
;A←(A)∧data
ANL
direct,
A
;direct←(direct)∧(A)
ANL
direct,
#data
;direct←(direct)∧data
其中前4条指令运算结果存放在A中,而后2条指令的运算结果则存放在直接寻址的地址单元中。
2、逻辑或运算指令组
逻辑或运算指令用符号“∨”表示,6条逻辑或运算指令如下:
ORL
A,
Rn
;A←(A)∨(Rn)
ORL
A,
direct
;A←(A)∨(direct)
ORL
A,
@Ri
;A←(A)∨((Ri))
ORL
A,
#data
;A←(A)∨data
ORL
direct,
A
;direct←(direct)∨(A)
ORL
direct,
#data
;direct←(direct)∨data
其中前4条指令的操作结果存放在累加器A中,后2条指令的操作结果存放在直接寻址的地址单元中。
3、逻辑异或运算指令组
XRL
A,
Rn
;A←(A)
(Rn)
ORL
A,
direct
;A←(A)
(direct)
ORL
A,
@Ri
;A←(A)
((Ri))
ORL
A,
#data
;A←(A)
data
ORL
direct,
A
;direct←(direct)
(A)
ORL
direct,
#data
;direct←(direct)
data
前4条指令操作结果存放在累加器A中,后2条指令的操作结果存放在直接寻址的
地址单元中。
4、累加器清“0”和取反指令组
累加器清“0”指令一条:
CLR
A
;A←0
累加器按位取反指令一条:
CPL
A
;A←(
)
注意,累加器按位取反实际上就是逻辑非运算。
[例3-1]当需要只改变字节数据的某几位,而其余位不变时,不能使用直接传送方法,而只能通过逻辑运算完成,以下举例说明。
例如将累加器A的低4位传送到P1口的低4位,但P1口的高4位需保持不变,对此可由以下程序段实现:
MOV
R0,
A
;内容暂存R0
ANL
A,
#0FH
;屏蔽A的高4位(低4位不变)
ANL
P1,
#F0H
;屏蔽P1口的低4位(高4位不变)
ORL
P,
A
;实现低4位传送
MOV
A,
R0
;恢复A的内容
[例3-2]利用逻辑运算指令,可以模拟各种硬件逻辑电路,如对图3-1所示的组合逻辑电路,试编写一程序模拟其功能。
设输入信号放在X、Y、Z单元中,输出信号放在F单元。
图3-1组合逻辑原理
MOV
A,
X
;A←(X)
ANL
A,
Y
;A←(A)∧(Y)
MOV
R1,
A
;A内容暂存
MOV
A,
Y
;A←(Y)
XRL
A,
Z
;A←(Y)
(Z)
CPL
A
;A←
ORL
A,
R1
;得到输出
MOV
F,
A
;存输出
5、移位指令组
MCS-51的移位指令只能对累加器A进行移位,共有不带进位的循环左、右移和带进位的循环左、右移指令4条。
(1)循环左移
RL
A
;An+1←An,A0←A7
累加器A
(2)循环右移
RR
A
;An←An+1,A7←A0
累加器A
累加器A
(3).带进位循环左移
RLC
A
;An+1←An,CY←A7,A0←CY
累加器A
(4).带进位循环右移
RRC
A
;An←An+1,A7←CY,CY←A0
累加器A
四、控制转移类指令
程序的顺序执行是由PC自动加1实现的。
要改变程序的执行顺序,实现分支转向,应通过强迫改变PC值的方法来实现,这就是控制转移类指令的基本功能。
共有两类转移:
无条件转移和有条件转移。
本节还要介绍子程序调用及返回指令。
1、无条件转移指令组
不规定条件的程序转移称之为无条件转移。
MCS-51共有4条无条件转移指令。
(1).长转移指令
LJMP
addr16
;PC←addr16
指令执行后把16位地址(addrl6)送PC,从而实现程序转移。
因转移范围大,可达64KB,称之为“长转移”。
长转移指令是三字节指令,依次是操作码、高8位地址、低8位地址。
(2).绝对转移指令
AJMP
addr11
这是一条二字节指令,其指令格式为
A10
A9
A8
0
0
1
0
0
A7
A6
A5
A4
A3
A2
A1
A0
指令提供的11位地址中,A7~A0在第二字节。
A10~A8则占据第一字节的高3位,而指令操作码只占第一字节的低5位。
AJMP指令的功能是构造程序转移的目的地址,实现程序转移,其构造方法是:
以指令提供的11位地址去替换PC的低11位内容,形成新的PC值,此即转移的目的地址。
但要注意,被替换的PC值是本条指令地址加2以后的PC值,即指向下一条指令的PC值。
因此AJMP指令的操作过程可表示为:
PC←(PC)+2
PC10~0←addr11
例如程序中2070H地址单元有绝对转移指令:
2070HAJMP16AH
11位绝对转移地址为:
00101101010B(16AH)。
因此,指令代码为:
0
0
1
0
0
1
0
0
0
1
1
0
1
0
1
0
程序计数器PC加2后的内容为:
0010000001110010B(2072H),以11位绝对转移地址替换PC的低11位内容,最后形成的目的地址为0010000101101010B(2l6AH)。
其中B表示二进制数,H表示十六进制数。
addr11是地址,因此是无符号数,其最小值为000H,最大值为7FFH,因此绝对转移指令所能转移的最大范围是2KB。
对于“2070HAJMPl6AH”指令,其转移范围是2000H~27FFH。
例如指令:
LOOP:
AJMP
addr11`
假设addr11=00100000000B,标号LOOP的地址为1030H,则执行指令后,程序将转移到1100H。
该指令的机器码为21H,00H(A10A9A8=001),即指令的第一字节为21H。
(3).短转移指令
SJMP
Rel
SJMP相对寻址方式转移指令,其中rel为相对偏移量,其功能是计算目的地址,并按计算得到的目的地址实现程序的相对转移。
计算公式为:
目的地址=(PC)+2+rel
偏移量rel是一个带符号的8位二进制补码数,因此所能实现程序转移是双向的。
如rel为正数则向前转移;如rel为负数则向后转移。
转移的范围笼统地说是256,因此称为短转移。
对于短转移指令的使用可从如下两个方面进行讨论。
①根据偏移量rel计算转移的目的地址
这种情况经常在读目标程序时遇到,是解决往哪儿转移的问题。
例如在853AH地址上有SJMP指令:
835AH
SJMP
35H
源地址为835AH,rel=35H是正数,因此程序向前转移。
目的地址=835AH+35H=8931H。
即执行完本指令后,程序转到8931H地址去执行。
又例如在835AH地址上SJMP指令是:
835AH
SJMP
0E7H
rel=0E7H,是负数19H的补码,因此,程序向后转移,目的地址=835AH+02H–19H=8343H。
即执行完本指令后,程序向后转到8343H地址去执行。
②根据目的地址计算偏移量
这是编程时必须解决的问题,也是一项比较麻烦的事情。
对于二字节的SJMP指令,rel的计算公式如下:
向前转移时:
rel=目的地址-源地址–2=(地址差)-2
向后转移时,目的地址小于源地址,rel应为负数的补码:
rel=(目的地址-(源地址+2))补
=FFH-(源地址+2–目的地址)+1
=FEH-(地址差)
为方便起见,在汇编程序中都有计算偏移量的功能。
用户编写汇编源程序时,只需在相对转移指令中直接写上要转向的地址标号就可以了。
程序汇编时由汇编程序自动计算和填入偏移量。
但手工汇编时,偏移量的值则需程序设计人员自己计算。
此外,在汇编语言程序中,为等待中断或程序结束,常有使程序“原地踏步”的需要,对此可使用SJMP指令完成:
HERE:
SJMP
HERE
或HERE:
SJMP$
指令机器码为80FE。
在汇编语言中,以“$”代表PC的当前值。
[例3-3]执行指令:
LOOP:
SJMPLOOPl。
如果LOOP的标号值为0100H(即SJMP这条指令的机器码存于0100H和0101H两个单元之中)。
标号LOOPl的值为0123H,即跳转的目标地址为0123H,则指令的第二个字节(相对偏移量)应为:
rel=0123H-0102H=21H
(4).变址寻址转移指令
JMP
@A+DPTR
;PC←(A)+DPTR
这是一条一字节转移指令。
转移的目的地址由A的内容和DPTR内容之和来确定,即目的地址=(A)+(DPTR)。
本指令以DPTR内容为基址,而以A的内容作变址,因此只要把DPTR的值固定,而给A赋以不同的值,就可实现程序的多分支转移。
键盘译码程序就是本指令的一个典型应用。
2、条件转移指令组
所谓条件转移就是程序转移是有条件的。
执行条件转移指令时,如指令中规定的条件满足,则进行程序转移,否则程序顺序执行,相当于高级语言中的if…goto语句。
条件转移有如下指令:
(1).累加器判零转移指令
JZ
rel
;若(A)=0,则PC←(PC)+2+rel
若(A)≠0,则PC←(PC)+2
JNZ
rel
;若(A)≠0,则PC←(PC)+2+rel
若(A)=0,则PC←(PC)+2
这两条指令都是二字节指令,是有条件的相对转移指令,以rel为偏移量。
[例3-4]将外部数据RAM的一个数据块传送到内部数据RAM中,两者的首地址分别为DATA1和TATA2,遇到传送的数据为0时停止。
解:
外部RAM向内部RAM的数据传送一定要借助于累加器A,利用累加器判零转移指令正好可以判别是否要继续传送或者终止。
MOV
R0,
#DATA1H
;外部数据块首地址
MOV
R1,
#DATA2H
;内部数据块首地址
LOOP:
MOVX
A,
@R0
;外部数据送给A
HERE:
JZ
HERE
;为0则终止
MOV
@R1,
A
;不为0传送内部RAM数据
INC
R0
;修改地址指针
INC
R1
SJMP
LOOP
;继续循环
(2).数值比较转移指令
数值比较转移指令把两个操作数进行比较,比较结果作为条件来控制程序转移,共有4条指令:
CJNE
A,
#data,
rel
;累加器内容与立即数不等则转移
CJNE
A,
direct,
rel
;累加器内容与内部RAM单元内容不等则转移
CJNE
Rn,
#data,
rel
;寄存器内容与立即数不等则转移
CJNE
@Ri,
#data,
rel
;内部RAM低128单元内容与立即数不等则转移
数值比较转移指令是三字节指令,这是MCS-51指令系统中仅有的4条3个操作数的指令。
在程序设计中非常有用。
这4条指令的功能可从程序转移和数值比较两个方面来说明。
①程序转移
为简单起见,把指令中的两个比较数据分别称之为左操作数和右操作数,则指令的转移可按以下3种情况说明:
若左操作数=右操作数,则:
程序顺序执行PC←(PC)+3
进位标志位清“0”CY←0
若左操作数>右操作数,则:
程序转移PC←(PC)+3+rel
进位标志位清“0”CY←0
若左操作数<右操作数,则:
程序转移PC←(PC)+3+rel
进位标志位置“l”CY