第2章 MCS-51单片机指令系统
第二章 MCS-51单片机指令系统
常用符号
Rn(n = 0~7):当前选中的工作寄存器组R0~R7。它在片内的地址由PSW中的RS1,RS0确定
Ri(i = 0,1):当前选中的工作寄存器组中可作为地址指针的两个工作寄存器R0,R1
#data:8位立即数,即指令中给出的8位常数
#data16:16位立即数,即指令中给出的16位常数
direct:8位片内RAM(包括SFR)的直接地址
addr11:11位目的地址。用于ACALL和AJMP指令中。目的地址必须放在与下一条指令第一字节同2k字节的程序存储器区地址空间内。
addr16:16位目的地址。用于LCALL和LJMP指令中,它的地址范围是64k字节程序存储器地址空间
rel:8位带符号的偏移量。用于SJMP和所有的条件转移指令中地址偏移量范围在-128~+127(即偏移量用补码形式表示)
bit:片内RAM和SFR的直接寻址位地址
@:间接寻址方式,表示间址寄存器的符号
/:位操作数前缀,表示对该位操作数求反
(x):表示x中内容
((x)):表示x寻址的单元中的内容
←:指令操作流程,将箭头右边的内容送到箭头左边的单元中
寻址方式
立即寻址
寻址空间:程序存储器(ROM)
指令所用到的操作数以指令字节的形式存放在程序存储器
直接寻址
寻址空间:内部RAM的低128字节,特殊功能寄存器(RAM高128字节)
直接寻址是访问SFR的唯一方式。意思是对于52系列单片机,片内RAM高128字节与特殊功能寄存器SFR地址重叠,此时只有直接寻址,才能访问到SFR,如只有寻址80H,才能访问到P0,若要访问RAM高128字节,则只能通过寄存器间接寻址的方式来实现
操作码后面的一个字节是实际操作数地址。这种直接在指令中给出操作数真实地址的方式称为直接寻址。
寄存器寻址
寻址空间:R0~R7(由PSW中RS1、RS0两位的值选定工作寄存器区),A、B、CY(位),DPTR
指令选定的寄存器所存储的内容是实际的操作数
寄存器寻址无需额外空间存储寄存器变量,即寄存器变量不占字节
MOV A,#00H ;该代码中对A的寻址方式为寄存器寻址,只有以Acc形式出现时,对A的寻址方式为直接寻址。
;因此,PUSH、POP指令对A进行出栈、弹栈时,必须要写Acc。因为PUSH、POP只能对direct操作
寄存器间接寻址
寻址空间:内部RAM(@R0,@R1,SP), 外部数据存储器(@R0,@R1,@DPTR)
指令所选中的寄存器内容是实际操作数的地址(而不是操作数)
寄存器间接寻址无需额外空间存储寄存器变量地址,即寄存器变量的地址不占字节
基址寄存器加变址寄存器间接寻址
寻址空间:程序存储器(@A+DPTR,@A+PC)
以DPTR或PC作基址寄存器,A作变址寄存器(存放8位无符号数),两者相加以形成16位程序存储器地址作操作数地址
相对寻址
用于程序控制,利用指令修正PC指针的方式实现转移。即以程序计数器PC的内容为基地址,加上指令中给出的偏移量rel,所得结果为转移目标地址。
偏移量rel是一个8位有符号补码数,范围-128~+127。
正向跳转:rel = 目的地址 - 源地址 - 2
反向跳转时,目的地址小于源地址,rel用负数的补码表示rel=(目的地址 -(源地址 + 2))补
位寻址
寻址空间:片内RAM的20H~2FH,SFR中12个能被8整除的字节
位寻址与直接寻址中的字节地址形式完全一样,是访问“字节”还是访问“位”完全以指令来区分
CLR C
SETB C
数据传送类指令
重点的4+3+5+3种MOV要给一个总结的话,就是:所有数据迁移指令,只有direct允许全部方式,其他
目的操作数不允许使用同个或同组寄存器(详细说就是,A不允许使用A,@Ri不允许使用@Ri与Rn,Rn
不允许使用@Ri与Rn);
查表MOVC牢记MOVC A, @A+DPTR
MOVC查表指令(2条)(必须使用累加器A,访问ROM)
MOVC A, @A+DPTR ; (A) <- ((A) + (DPTR))
MOVC A, @A+PC ; (A) <- ((A) + (PC))
此时PSEN信号有效
MOVX传送类指令(4条)(必须使用累加器A,使用寄存器间接寻址方式,访问片外RAM)
MOVX A, @DPTR ; (A) <- ((DPTR))
MOVX @DPTR, A ; ((DPTR)) <- (A)
MOVX A, @Ri ; (A) <- ((Ri))
MOVX @Ri, A ; ((Ri)) <- (A)
向DPTR/寄存器读数据时,RD信号有效;向DPTR/寄存器写数据时,WR信号有效
交换指令(5条)(前3条为字节交换,后2条为半字节交换)
XCH A, Rn ; (A) <-> (Rn)
XCH A, direct ; (A) <-> (direct)
XCH A, @Ri ; (A) <-> ((Ri))
XCHD A, @Ri ; (A3 ~ 0) <-> ((Ri)3 ~ 0) 半字节交换
SWAP A ; (A3 ~ 0) <-> (A7 ~ 4) 交换低四位和高四位
堆栈类
PUSH direct ; (SP) <- (SP) + 1
; ((SP)) <- (direct)
POP direct ; (direct) <- ((SP))
; (SP) <- (SP) - 1
注意,若想要对累加器A进行压栈弹栈操作,必须写PUSH Acc。看到Acc时,才是直接寻址。
算数运算类指令
加法指令(4条)
ADD A, Rn ; (A) <- (A) + (Rn)
ADD A, direct ; (A) <- (A) + (direct)
ADD A, @Ri ; (A) <- (A) + ((Ri))
ADD A, #data ; (A) <- (A) + #data
带进位加法指令(4条):
ADDC A, Rn ; (A) <- (A) + (Rn) + (CY)
ADDC A, direct ; (A) <- (A) + (direct) + (CY)
ADDC A, @Ri ; (A) <- (A) + ((Ri)) + (CY)
ADDC A, #data ; (A) <- (A) + #data + (CY)
带借位减法指令(4条)(这个借位是指低位从当前这里借走,而不是自己从高位那里借来。因为运算是从低位算到高位的)
SUBB A, Rn ; (A) <- (A) - (Rn) - (CY)
SUBB A, direct ; (A) <- (A) - (direct) - (CY)
SUBB A, @Ri ; (A) <- (A) - ((Ri)) - (CY)
SUBB A, #data ; (A) <- (A) - #data - (CY)
乘法指令(仅1条合法,必须一字不差,空格数除外):
MUL AB ; (B)(A) <- (A) * (B)
除法指令(仅1条合法,必须一字不差,空格数除外):
DIV AB ; (A) <- (A) / (B) 的商
; (B) <- (A) / (B) 的余
自增指令(5条):
INC A ; (A) <- (A) + 1
INC Rn ; (Rn) <- (Rn) + 1
INC direct ; (direct) <- (direct) + 1
INC @Ri ; ((Ri)) <- ((Ri)) + 1
INC DPTR ; (DPTR) <- (DPTR) + 1
自减指令(4条)(DPTR不允许自减):
DEC A ; (A) <- (A) - 1
DEC Rn ; (Rn) <- (Rn) - 1
DEC direct ; (direct) <- (direct) - 1
DEC @Ri ; ((Ri)) <- ((Ri)) - 1
无DPTR减1指令。若要做DPTR-1,必须要用一段程序实现。
CLR C
MOV A,#DPL
SUBB A,#1
MOV DPL,A
MOV A,DPH
SUBB A,#0
MOV DPH,A
十进制调整指令(仅1条合法,必须一字不差,空格数除外):
DA A
这条指令是在进行BCD码运算时,跟在ADD和ADDC指令之后,将相加后存放在累加器A中的结果进行修正。
不能用于BCD码减法结果调整
逻辑操作类指令
循环移位指令(4条)
RL A ; A的内容循环左移
RR A ; A的内容循环右移
RLC A ; A的内容带C位循环左移
RRC A ; A的内容带C位循环右移
左移/右移可以和乘/除等效
求反指令(1条)
CPL A
清0指令(1条)
CLR A
逻辑与指令(6条)
ANL A,#data
ANL direct,#data
ANL A,Rn
ANL A,direct
ANL direct,A
ANL A,@Ri
逻辑或指令(6条)
ORL A,#data
ORL direct,#data
ORL A,Rn
ORL A,direct
ORL direct,A
ORL A,@Ri
逻辑异或指令(6条)
XRL A,#data
XRL direct,#data
XRL A,Rn
XRL A,direct
XRL direct,A
XRL A,@Ri
控制转移类指令
无条件转移指令(4条)
LJMP跳转范围为64K
AJMP为绝对跳转指令,跳转11位地址,执行前PC会先加2,跳转范围为2K
SJMP为短跳转指令,跳转范围是-128——+127
LJMP addr16 ; (PC) ← addr16,长跳转指令,跳转范围64K
AJMP addr11 ; (PC) ← (PC)+ 2,
; (PC(10-0)) ← addr11,(PC(15-11))保持不变
; 绝对跳转指令,跳转范围2K
SJMP rel ; (PC) ← (PC)+ 2 + rel
; 短跳转,跳转范围为-128~+127
JMP @A+DPTR ; (PC) ←(A)+ (DPTR),散转指令
; A的内容为8位无符号数
条件转移指令(8条)
理解:
JZ——jump if zero
JNZ——jump if not zero(这两个后面都不会跟变量,所以默认的是累加器A)
CJNE——compare jump not equal,先对两个变量做减法,改变进位位,有借位C为1,无借位C为0;然后比较两个变量如果不等则跳转
DJNZ——decrement jump if not zero
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
CJNE A,direct,rel ; (A)≠(direct)时跳转,(PC) ← (PC) + 3 + rel
; (A) = (direct)不跳转,(PC) ← (PC) + 3
; 会影响进位标志,(A)>(direct)时, (C) ← 0
;(A)<(direct)时, (C) ← 1
CJNE A,#data,rel
CJNE Rn,#data,rel
CJNE @Ri,#data,rel
DJNZ Rn,rel ; (Rn)←(Rn)- 1
; 若(Rn)≠0则跳转, (PC) ← (PC)+ 2 + rel
; 若(Rn)=0则不跳转,(PC) ← (PC)+ 2
DJNZ direct,rel
子程序调用及返回指令(4条)
LCALL addr16 ; (PC) ← (PC) + 3
; (SP) ← (SP) + 1 ,((SP)) ← (PC(7~0))
; (SP) ← (SP) + 1 ,((SP)) ← (PC(15~8))
; (PC) ← addr16
ACALL addr11 ; (PC) ← (PC) + 2
; (SP) ← (SP) + 1 ,((SP)) ← (PC(7~0))
; (SP) ← (SP) + 1 ,((SP)) ← (PC(15~8))
; (PC(10-0)) ← addr11,(PC(15-11))保持不变
RET ; (PC(15~8)) ← ((SP)) , (SP) ← (SP) - 1
; (PC(7~0)) ← ((SP)) , (SP) ← (SP) - 1
RETI ; (PC(15~8)) ← ((SP)) , (SP) ← (SP) - 1
; (PC(7~0)) ← ((SP)) , (SP) ← (SP) - 1
; 中断子程序返回,除具有RET的功能外,还可以恢复中断逻辑
NOP ; (PC) ← (PC) + 1(延时用)
RET和RETI不能互换使用
位操作类指令
在指令中,位地址的表达方式有以下4种:
1.直接用位地址表示:如 0D5H
2.点操作符方式:PSW.5
3.位名称方式:F0
4.用户使用伪指令事先定义的符号地址:USER-FLG bit F0
位数据传送指令(2条)
MOV C,bit ; (C) ← (bit)
MOV bit,C ; (bit) ← (C)
; bit表示可位寻址的各位(221位)的位地址
位状态控制指令(6条)
CLR C ; 清0
CLR bit ; 清0
CPL C ; 求反
CPL bit ; 求反
SETB C ; 置1
SETB bit ; 置1
位逻辑运算指令(4条)
ANL C,bit ; 与
ANL C,/bit ; 与
ORL C,bit ; 或
ORL C,/bit ; 或
位条件转移指令(5条)
JC rel ;(C)=1,跳。 (PC) ← (PC) + 2 + rel
;(C)=0,不跳。 (PC) ← (PC) + 2 ,顺序执行
JNC rel ;(C)=0,跳。 (PC) ← (PC) + 2 + rel
;(C)=1,不跳。 (PC) ← (PC) + 2
JB bit,rel ; bit =1,跳。 (PC) ← (PC) + 3 + rel
; bit =0,不跳。 (PC) ← (PC) + 3
JNB bit,rel ; bit =0,跳。 (PC) ← (PC) + 3 + rel
; bit =1,不跳。 (PC) ← (PC) + 3
JBC bit,rel ; bit =1,则(bit)← 0, (PC) ← (PC) + 3 + rel
; bit =0,则顺序执行,(PC) ← (PC) + 3
伪指令
ORG、END、DB、DW、DS
EQU:把一个数据或汇编符号用自定义的字符代替 被定义的字符名称可用作数据地址、位地址、寄存器或立即数等
DATA:把数据地址或代码地址用自定义的字符替代(DATA是数据不是地址)
BIT:把位地址用自定义的字符替代
指令的字节和周期
字节的判断:执行这件事需要一个字节,指令中含有的变量需要占用对应的字节(寄存器寻址、寄存器间接寻址不占字节,DPTR的16位数据占用两个字节)
共分为单字节、双字节、三字节指令三种
按照周期可分为单周期、双周期、四周期三种,四周期指令只有乘除,三字节一定是双周期,其他的似乎只能背了……