第三章 MCS-51单片机指令系统
(一) 指令系统简介
1. 指令分类统计
指令总数:111条 操作码:255个 助记符:48个
单字节指令:49条 单周期指令:64条
双字节指令:48条 双周期指令:45条
三字节指令:17条 四周期指令:2条
表3-1 MCS-51指令分类
数据传送指令(29) 数据处理指令(48) 位操作指令(12) 程序控制指令(22)
1) 内部传送(16)
2) 外部传送(4)
3) 查表 (2)
4) 交换 (5)
5) 栈操作 (2) 1) 算术运算(24)
2) 逻辑运算(24) 1) 位传送(2)
2) 位置值(4)
3) 位逻辑(6) 1) 调用及返回(4)
2) 无条件转移(4)
3) 条件转移 (11)
4) 循环 (2)
5) 空操作 (1)
2. 符号约定
Rn 表示当前工作寄存器中的R0R7
Direct 表示对内部单元直接寻址的8位地址
Ri 表示8位地址指针R0或R1,地址在R0或R1中。
DPTR 表示16位地址指针,地址在DPTR中。
#data 表示8位立即数。
#data16 表示16位立即数。
A+基地址 表示以A为变址寄存器。
addr11 表示短转移的11位地址。
addr16 表示长转移的16位地址。
rel 表示相对转移的地址偏移量。
bit 表示位地址。
(xx) 表示XX单元的内容,如(A)表示寄存器A的内容。
((xx)) 表示以(xx)为指针,所指单元的内容。例如,
((DPTR))表示数据指针DPTR所指单元的内容。
3. 寻址方式
表 F1-1 MCS-51指令系统的寻址方式
寻 址
方 式
寻 址 范 围
操作数形式
举 例
寄存器
寻址 R0-R7 ,DPTR
Acc,B,C(Cy 位)
寄存器名 MOV R3,A
INC DPTR
直接
寻址 内部RAM 00H-7FH
特殊功能寄存器 80H-FFH 8位地址
SFR名 MOV 79H,SP
PUSH P1
直接
位寻址 内部RAM位寻址区 (20H-2FH):
位地址00H-7FH
可寻址的特殊功能寄存器:
位地址 80H-F7H 8位地址
位名
SFR名.位序 MOV C,78H
CLR TR0
ANL C,P0.1
寄存器
间接
寻址 以数据指针表示操作数。
内部RAM 00H-7FH @R0
@R1 MOV A, @R0
ADD A, @R1
外部RAM或I/O端口
00H-FFH / 0000H-FFFFH @R0 ,@R1@DPTR MOVX A, @R0
MOVX @DPTR,A
立即
寻址 8位(二进制)立即数, # data MOV A,# 1
16位(二进制)立即数 # data16 MOV DPTR,#2000H
基址
加
变址
寻址 以变址方式读程序存贮器
实际地址=基址+变址偏移量
8位无符号变址偏移量由A提供
基址由PC或DPTR提供 @A+DPTR
@A+PC MOVC A,@A+DPTR
MOVC A,@A+PC
转 移 地 址 的 寻 址 方 式
相对
寻址 转移地址= 基址+相对偏移量rel
基址为取指令后的PC 值
8位有符号数rel在指令中给出 rel SJMP 0EBH
标号 SJMP LOOP 标号
直接
寻址 短转移,指令直接给出11位地址 Addr11或标号 AJMP NEW 标号
长转移,指令直接给出16位地址 Addr16或标号 LJMP 2010H
(二) 数据传送指令
表 3-2 数据传送指令
操作码 目标操作数 可选择的源操作数 说 明
MOV A
Rn
direct
@Ri
DPTR Rn;direct;@Ri;# data
A;direct;# data
A;Rn;direct;@Ri;# data
A;direct;# data
# data16 内部传送
内部传送
内部传送
内部传送
数据指针赋值
PUSH
POP 隐含(SP)
direct direct
隐含(SP) 压栈,只能用直接寻址
退栈,只能用直接寻址
XCH A Rn; direct; @Ri 内部交换
XCHD
SWAP A
A @Ri
隐含A 只交换低四位
A的高、低四位互换
MOVX A
@Ri
@DPTR @Ri; @DPTR
A
A A与外部数据存储器间传送
MOVC A @A+DPTR; @A+PC 读外部程序存储器
MOV C
bit bit
C Cy与可寻址位间传送
1. 数据传送指令的一般性说明
指令的一般格式: 操作码 目标操作数,源操作数
操作码 说明操作的性质
操作内容一般为 (目标操作数)←(源操作数)
8位操作数的形式有A、Rn、direct、@Ri、# data 等五种
16位操作数的形式有DPTR 与 # data16
1位操作数的形式有 C 与 bit
目标与源应同类型,且有规定的允许搭配,一般可逆。
A及direct可全搭配,@Ri、Rn不能相互搭配,# data只可作源.。
传送指令一般不影响标志位。
直接改写PSW的情况除外,改写Acc影响P标志。
2. 内部传送(MOV)
内部RAM、特殊功能寄存器(SFR)之间的数据传送。
注意立即数 #XXH与直接地址XXH 的区别。
@Ri指针使用要点:①与循环配合,适用于连续数据区的操作。
②Ri应先赋确定值。i=0,1。
③是XCHD指令唯一的源操作数。
3. 外部传送(MOVX)
以指针方式读、写外部数据存储器或I/O端口。
@DPTR提供16位地址指针,可访问总线扩展的整个64k空间。
@Ri只提供低8位地址指针,适用于256个地址的小规模总线扩展。
或者由P2口以I/O方式提供高8位(页) 地址,采用页访问模式。例如:
MOV P2,#30H ;由P2口提供高8位地址30H
MOV R0,#0 ;低8位地址为00H
MOVX A,@R0 ;读(3000H)单元
应用例:将内部30H40H单元的内容送外部数据存储器,从4000H单元开始存放。
MOV R0,#30H
MOV R2,#17
MOV DPTR,#4000H
LOOP: MOV A,@R0
MOVX @DPTR,A
INC R0
INC DPTR
DJNZ R2,LOOP
;设置(内部)源指针初值
;设置循环计数器初值
;设置(外部)目标指针初值
;循环入口,读源数据
;写目标数据
;源指针下移
;目标指针下移
;循环计数器减一,不为0则继续循环
4. 读外部程序存储器(MOVC)
读取外部程序存储器中的数据,用于查表。
MOVC A,@A+PC ;(A)←((A)+(PC)+1)
PC为本指令的地址,取指令后加一。
变址偏移量(A)是8位无符号数,因此查表的范围在(PC)+1 (PC)+255。
MOVC A,@A+DPTR ;(A)←((A)+(DPTR))
DPTR是16位指针,因此查表的范围为全64k空间。
应用例:查Y(x)函数表。
3000H MOV A,#表元素序号
3002H ADD A,#表头偏移量
3004H MOVC A, @A+PC
ORG 30A0H
TABLE: DB 17,22,34,58,82,103
表头偏移量=表头地址-(MOVC指令地址+1)
5. 栈操作(PUSH / POP)
堆栈在内部RAM区。
PUSH和POP的对象可以是内部RAM单元或SFR。
寻址方式只能用direct。例如,
PUSH 30H ;(SP)←(SP)+1,((SP))←(30H)
POP DPH ;(DPH)←((SP)),(SP)←(SP)-1
6. 交换(XCH / XCHD /SWAP)
XCH 字节交换:A与内部RAM单元或SFR交换。例如
XCH A,R2 ;(A)(R2)
XCHD 半字节交换:A与内部RAM单元进行低四位交换,只能用寄存器间址@Ri。例如
XCHD A,@R1 ;(A)D0- D 3 ((R1))D0- D 3
SWAP A ;(A)D0- D 3 (A)D4- D 7
应用例:拆字,将压缩BCD码扩展为单字节BCD码。
MOV R0, #30H 设立指针
MOV A, #0 ;(A)=0
XCHD A, @R0 ;(A)=0BH
MOV R4, A ;(R4)=0BH
XCH A,30H ;(A)=30H
SWAP A ;(A)=03H
MOV R3,A ;(R3)=03H
(三) 算术运算指令
表 3-3 算术运算指令
操作码 目标操作数 参与运算的操作数 说 明 Cy AC OV P
ADD A Rn; direct; @Ri; # data 不带进位加
ADDC A Rn; direct; @Ri; # data 带进位加
SUBB A Rn; direct; @Ri; # data 带借位减
MUL AB (A)*(B) 积在(B)(A)
0
-
DIV AB (A)/(B) 商 (A) ,余数 (B)
DA A 只对加法作十进制修正 - -
INC A; Rn; direct; @Ri; DPTR 加一
-
-
-
DEC A; Rn; direct; @Ri (无DPTR) 减一
*“”表示标志位根据运算结果取值,“-”表示对标志位无影响。
1. 算术运算指令的一般性说明
除加1/减1指令外,一般以累加器Acc为目标,且影响标志位。
没有不带借位减指令。用SUBB作不带借位减运算,Cy应先清零。
乘法若 积 > 255 , 则OV = 1 除法若 除数 = 0 , 则OV = 1 。
DA A 指令只对ADD 或ADDC作十进制修正。
无 DEC DPTR指令。
2. 加/减指令应用例
将内部RAM中从30H开始存放的10个双字节无符号整数相加,其和送(R5 R4 R3),低字节在R3。
MOV R0,#30H
MOV R2,#10
MOV R3,#0
MOV R4,#0
MOV R5,#0
LOOP:MOV A,@R0
ADD A, R3
MOV R3,A
INC R0
MOV A,@R0
ADDC A,R4
MOV R4,A
INC R0
MOV A,#0
ADDC A,R5
MOV R5,A
DJNZ R2,LOOP
将内部RAM中从30H开始存放的10个4位十进制正整数(压缩BCD码)相加,其和送(R5 R4 R3),低字节在R3。
比较A与B中的无符号数,大数存B。
MOV R2,A
CLR C ;确保C = 0
SUBB A,B
JC DONE ;若有借位,A<B,转DONE 结束。
MOV B,R2 ;没有借位,A>B,将大数存B。
DONE:
3. 乘/除指令应用例
双字节数乘单字节数:双字节数在(R3R4),单字节数在(R2),积送(R3R4R5)
MOV A,R2
MOV B,R4
MUL AB (R4)(R2)
MOV R5,A
MOV R4,B
MOV A,R2
MOV B,R3
MUL AB (R3)(R2)
ADD A,R4
MOV A,#0
ADDC A,B
MOV R3,A
单字节二进制数转十进制(BCD)数:二进制数在A,十进制数存入(R2R3)
MOV B,#10
DIV AB 除十, 余个位
MOV R3,B 个位存R3
MOV B,#10
DIV AB 再除十, 余十位
MOV R2,A 商为百位,存R2
MOV A,B
SWAP A
ADD A,R3 十位与个位合并
MOV R3,A;
(四) 逻辑运算指令
表 3-4 逻辑运算指令
操作码 目标操作数 参与运算的操作数 说 明
ANL A Rn; direct; @Ri; # data
逻辑与
direct A; # data
ORL A Rn; direct; @Ri; # data
逻辑或
direct A; # data
XRL A Rn; direct; @Ri; # data
逻辑异或
direct A; # data
CPL A — 累加器(A)取反
CLR A — 累加器(A)清零
RL
A
D7←…←D0 (A)左小循环,不影响Cy
RLC
A
D7←…←D0← C (A)左大循环
RR
A
D7→…→D0 (A)右小循环,不影响Cy
RRC
A
C →D7→…→D0 (A)右大循环
1. 逻辑运算指令的一般性说明
与、或、异或的逻辑运算指令可以Acc或direct为目标。但是以direct为目标时,另一操作数只能是Acc或立即数。
与、或、异或是对位逻辑运算。
其他逻辑运算指令只对Acc操作。
小循环不影响Cy,大循环Cy在循环圈内。
除了RLC和RRC,逻辑运算指令不影响P以外的标志位。
2. 与、或、异或的特殊用途
用ANL指令屏蔽指定位
例:ANL A,#0FH ;屏蔽高4位
用ORL指令将指定位置1
例:ORL A,#0FH ;将低4位置1
用ORL指令拼接一个字节
例:ANL A,#0FH
ANL B,#0F0H
ORL A,B
用XRL指令将指定位取反
例:XRL A,#55H ;将D0、D2、D4、D6等位取反
3. 循环移位指令的应用
乘除法运算
左移=无符号数乘2,右移=有符号数除2。
例:A×B,积存(BA)
算法:乘数在(A),积在(R2)(A)。
1) (A)右移一位;
2) (A)移出的一位若为1,则(R2)+被乘数(B);
3) 积(R2)(A)双字节右移一位;第2、3步循环8次。
为简化,假定为4位,循环4次。(A)=1011, (B)=1111
MOV R2,#0
MOV R3,#8
CLR C
RRC A
LP:XCH A,R2
JNC RRR
ADD A,B
RRR:RRC A
XCH A,R2 ;①
RRC A ;②
DJNZ R3,LP
MOV B,R2
下表第一列为:循环次数-执行点
其余各列为执行点的操作结果。
逻辑尺
以二进制数表示二值逻辑序列,逐位移出,并据此行逻辑控制。
(五) 位处理指令
表 3-5 位处理指令
操作码 目标操作数 源操作数 说 明
ANL
C
b i t / b i t / b i t表示取(b i t)的非值运算, 但不影响原值。
ORL
CPL C 或 b i t 将指定位取反。
SETB
C 或 b i t 将指定位置 “1”。
CLR 将指定位清零。
1. 位处理指令的一般性说明
在分类时将位传送归入传送指令类,条件转移归入程序控制类。其余位操作归为位处理指令。
位逻辑运算以C为目标,/ b i t表示取(b i t)的非值运算, 但不影响原值。
2. 位逻辑运算应用例
以软代硬:
MOV C, P1.1
ORL C, /P1.2
CPL C
ANL C, P1.0
ANL C, /P1.3 图3-1 应用例中的端口硬件逻辑
MOV P1.5, C
3. 位置值操作应用例
直接操作各功能部件的控制位。例如, 启动T0定时器。
SETB TR0
输出某一路开关量控制信号。例如, 从P1.0输出脉冲。
LOOP:CPL P1.0
延时半个脉冲周期,
返回LOOP,不断循环。
(六) 程序控制指令
表 3-6 程序控制指令
操作码 操作数 条 件 转 移 地 址 说 明
AJMP
addr11
无条件 (PC)←(PC)+2
(PC)0-10←addr11 短转移,只改变PC的低11位,转移范围2K。
LJMP addr16 无条件 (PC)←addr16 长转移,转移范围全64K空间
SJMP rel 无条件 (PC)←(PC)+2+rel 相对转移 ,范围-126~+129。
JMP @A+DPTR 无条件 (PC)←(A)+(DPTR) 散转指令,根据A值变址转移
ACALL
addr11
无条件 (PC)←(PC)+ 2
(PC)L、(PC)H压栈
(PC)0-10←addr11 短调用,只改变PC的低11位,转移范围2K。
LCALL addr16 无条件 (PC)←(PC)+ 3
(PC)L、(PC)H压栈
(PC)←addr16 长调用,调用范围全64K空间
RET 隐含
((SP))
无条件 (PC)H←((SP))
(PC)L←((SP)-1)) 子程序返回。
RETI 中断返回。
JZ
rel (A)= 0
(PC)←(PC)+2+rel
根据A的值条件转移。
JNZ (A)≠0
JC
rel (C)= 0
(PC)←(PC)+2+rel
根据C的值条件转移。
JNC (C)= 1
JNB
bit, rel
(bit)=0
(PC)←(PC)+3+rel
位值判别转移。(负逻辑)
JB (bit)=1 位值判别转移。(正逻辑)
JBC (bit)=1 同 JB ,加(bit)清零功能。
DJNZ Rn, rel (Rn)-1≠0 (PC)←(PC)+2+rel 循环指令。循环计数器自动
减1,归0则退出循环。
dir, rel (dir)-1≠0 (PC)←(PC)+3+rel
操作码
操作数
条 件
转 移 地 址
说 明
CJNE
A,dir,rel
A,#data,rel Rn,#data,rel
@Ri,#data,rel (A)≠(direct)
(A)≠#data
(Rn)≠#data
((Ri))≠#data
(PC)←(PC)+3+rel 按无符号数比较,两数不等则转移。若前一数小,C置1;若前一数不小于后一数,C清零。
NOP 无 无 (PC)←(PC)+1 空操作,顺序执行。
1. 程序控制指令的一般性说明
程序控制指令又分“无条件转移”、“调用与返回”和“条件转移”等三类。
对程序控制指令应掌握:转移地址如何生成及其转移范围。
注意!MCS-51条件转移指令的运用与计算并无特别的联系。
位值判别转移使程序设计更为灵活,是MCS-51指令系统的特色。
应特别注意变址转移指令JMP与比较转移指令CJNE的用法。
2. AJMP、LJMP及SJMP的转移范围
指令 转移地址 转移范围 说明
AJMP addr11 (PC)+2的高5位
+ addr11
(PC)+2所在的2k页 2k页:X000HX7FFH
X800HXFFFH
LJMP addr16 addr16 全64k空间
SJMP rel (PC)+2+rel (PC)-126(PC)+129 Rel是8位有符号数
注:①表中的(PC)是转移指令的地址。
②在实际使用时,地址一般用标号表示。
3. 变址转移指令JMP的使用
JMP的转移地址 = 基址(DPTR)+变址偏移量(A)。
应用例:按照(A)= 0,1,2,分别转向三个不同的程序分支。
MOV DPTR,#GO ;设立散转入口地址
MOV B A, ;
RL A (A) ←(A)+3
ADD A,B ;
JMP @A+DPTR
GO: LJMP GO1 ;指令地址为GO
LJMP GO2 ;指令地址为GO+3
LJMP GO3 ;指令地址为GO+6
问题一:上例中,如果由LJMP改用AJMP,程序应如何变化?
问题二:上例中,如果A的值大于2会如何?怎样解决?
4. 条件转移指令的使用
因为A与C的值并不一定由计算操作而改变,故JZ、JNZ、JC、JNC等指令的运用与计算并无特别的联系,
位值判别转移指令使条件转移的功能更丰富和灵活。例如:
如果(B)0,转向POS分支:JNB B.7,POS
如果计算溢出,转向FL分支: JB OV,FL
如果C=1,将C清零并转向NEG分支:JBC C,NEG
由P1.4检测火灾传感器,1有效。传感器报警时转向FIRE分支:JB P1.4,FIRE
5. 比较转移指令CJNE及其使用
格式:CJNE 前数,后数,相对偏移量
转移条件:前数≠后数
对C的影响:按无符号数减法。前数减后数,有借位C = 1,否则C = 0。
应用例:A、B中为无符号数,比较两数,大数存A,小数存B。
CJNE A,B,0
JNC DONE
EXC A,B
DONE:……
应用例:A、B中为有符号数,比较两数,大数存A,小数存B。
有符号数比较的算法:
以A 与B 表示A与B的无符号值。
对于A >B 有,若A>0 则A>B,A<0 则A<B;
据此可以画出右边的流程图,相应的程序如下
CJNE A,B,NEQ
SJMP DONE
NEQ:JNC AGT
XCH A,B
AGT:JNB Acc.7,DONE
XCH A,B
DONE:……
图3-2 有符号数比较
(七) MCS-51汇编语言程序设计方法
1. 汇编语言程序的基本结构
YES NO
(a)顺序结构 (b)分支结构
PC压栈
NO PC退栈
YES
(c)循环结构 (d)子程序结构
图3-3 四种基本程序结构
1) 顺序结构
程序模块或指令依次执行的结构。
2) 分支结构
根据条件,转向不同程序段(分支)的结构。
分支不应是模块间的转移,执行分支后应返回流程主线。
注意防止从一个分支的出口进入另一个分支的入口
3) 循环结构
按循环控制条件重复执行某一段程序,用于连续重复性操作。
循环圈包括循环体与循环控制;循环结构还包括循环初始化与后处理。循环控制有计数循环与条件循环两种。
循环可以嵌套,但不应交叉,也不要从循环体外跳入循环圈。
4) 子程序结构
在主程序中执行调用子程序指令,CPU转去执行子程序。在子程序中由返回指令返回主程序,继续执行调用指令的下一条指令。
调用时,先将返回地址压栈,并按调用指令提供的地址转入子程序。返回时,从堆栈弹出返回地址送PC,重返主程序。
程序中多处使用的功能模块可采用子程序结构,以节省程序空间。
编写与使用子程序的七要素:
功能说明。
子程序名与入口地址。
入口条件。
出口状态。
占用资源。
子程序中的调用。
编写与使用子程序的四项注意:
现场保护与现场恢复,避免与主程序冲突。
堆栈操作应成对,且PUSH先行,保护返回地址。
多重调用应考虑堆栈的容量,不宜直接或间接的自反调用。
防止不经调用进入子程序,禁止不经返回指令跳出子程序。
5) MCS-51汇编语言程序的一般格式
与8086不同,没有代码段、数据段等区分,统一编址。
程序由指令行或注释行组成,指令行每行只能写一条指令。
指令前可用“标号:”表示指令地址,以便在指令中引用;标号是符号名,以字母开头。
注释行应以“;”号开头;指令后也可用“;”号分隔,附加注释。
程序由伪指令ORG XXXXH 定位,ORG中的16位地址就是将来写入程序存储器的绝对地址。程序中的ORG应按地址从小到大排列。由ORG定位的程序段可以不连续,汇编程序将会在段间的空地址上填00H,即NOP。因此,每个ORG段的最后一条指令一般应是转移指令。
数据由伪指令DB(字节)或DW(双字节)说明。数值应以数码0-9开头;尾缀说明:B-二进制,D-十进制,H-十六进制。十进制D可缺省。
伪指令EQU可定义等价字段,以便用符号名代表某个操作数,例如:
aa EQU 30H
bb EQU #30H
MOV A,aa aa等价于“30H”, 该指令即 MOV A, 30H
MOV R0,bb bb等价于“#30H”,该指令即 MOV R0,#30H
2. 汇编语言程序设计方法
1) 评价程序优劣的因素
正确性,容错性。
结构化,简明易读,易检验,易维护。
省资源,高效率,易操作。
2) 程序设计过程与基本设计方法
模块化;结构化;自顶而下与自底而上。
结构化设计:
结构设计自顶而下:
功能设计→总体结构设计→局部结构设计→底层模块设计
→验证方法设计
具体设计自底而上:
模块→局部→整体,逐步整合、协调,调试与验证,最后总结建档。
从原理到程序实现
原理→模型→算法→流程→程序设计→调试→优化→验证→建档
3) 常用的程序调试方法
原则:先硬后软;先局部,后整体。
汇编检错-语法检查。
审视推演-逻辑检查。
准备测试数据,试运行。
附加测试指令,设置标志,输出中间结果。
单步调试
设置断点
4) 程序的优化与文件编制
参照评价因素,修改程序结构、数据结构、算法及程序,等等。
总结建档,编制说明文件
设计说明:
设计目标,原理,模型;设计方案,性能与特点;程序结构,数据结构,存储器分配;流程,加注释的程序清单;等等。
测试报告:
测试方法,测试数据,测试结果分析。
使用说明
功能,操作方法,出错信息与排除方法,注意事项,等等。
1楼
0
0
回复
(一) 指令系统简介
1. 指令分类统计
指令总数:111条 操作码:255个 助记符:48个
单字节指令:49条 单周期指令:64条
双字节指令:48条 双周期指令:45条
三字节指令:17条 四周期指令:2条
表3-1 MCS-51指令分类
数据传送指令(29) 数据处理指令(48) 位操作指令(12) 程序控制指令(22)
1) 内部传送(16)
2) 外部传送(4)
3) 查表 (2)
4) 交换 (5)
5) 栈操作 (2) 1) 算术运算(24)
2) 逻辑运算(24) 1) 位传送(2)
2) 位置值(4)
3) 位逻辑(6) 1) 调用及返回(4)
2) 无条件转移(4)
3) 条件转移 (11)
4) 循环 (2)
5) 空操作 (1)
2. 符号约定
Rn 表示当前工作寄存器中的R0R7
Direct 表示对内部单元直接寻址的8位地址
Ri 表示8位地址指针R0或R1,地址在R0或R1中。
DPTR 表示16位地址指针,地址在DPTR中。
#data 表示8位立即数。
#data16 表示16位立即数。
A+基地址 表示以A为变址寄存器。
addr11 表示短转移的11位地址。
addr16 表示长转移的16位地址。
rel 表示相对转移的地址偏移量。
bit 表示位地址。
(xx) 表示XX单元的内容,如(A)表示寄存器A的内容。
((xx)) 表示以(xx)为指针,所指单元的内容。例如,
((DPTR))表示数据指针DPTR所指单元的内容。
3. 寻址方式
表 F1-1 MCS-51指令系统的寻址方式
寻 址
方 式
寻 址 范 围
操作数形式
举 例
寄存器
寻址 R0-R7 ,DPTR
Acc,B,C(Cy 位)
寄存器名 MOV R3,A
INC DPTR
直接
寻址 内部RAM 00H-7FH
特殊功能寄存器 80H-FFH 8位地址
SFR名 MOV 79H,SP
PUSH P1
直接
位寻址 内部RAM位寻址区 (20H-2FH):
位地址00H-7FH
可寻址的特殊功能寄存器:
位地址 80H-F7H 8位地址
位名
SFR名.位序 MOV C,78H
CLR TR0
ANL C,P0.1
寄存器
间接
寻址 以数据指针表示操作数。
内部RAM 00H-7FH @R0
@R1 MOV A, @R0
ADD A, @R1
外部RAM或I/O端口
00H-FFH / 0000H-FFFFH @R0 ,@R1@DPTR MOVX A, @R0
MOVX @DPTR,A
立即
寻址 8位(二进制)立即数, # data MOV A,# 1
16位(二进制)立即数 # data16 MOV DPTR,#2000H
基址
加
变址
寻址 以变址方式读程序存贮器
实际地址=基址+变址偏移量
8位无符号变址偏移量由A提供
基址由PC或DPTR提供 @A+DPTR
@A+PC MOVC A,@A+DPTR
MOVC A,@A+PC
转 移 地 址 的 寻 址 方 式
相对
寻址 转移地址= 基址+相对偏移量rel
基址为取指令后的PC 值
8位有符号数rel在指令中给出 rel SJMP 0EBH
标号 SJMP LOOP 标号
直接
寻址 短转移,指令直接给出11位地址 Addr11或标号 AJMP NEW 标号
长转移,指令直接给出16位地址 Addr16或标号 LJMP 2010H
(二) 数据传送指令
表 3-2 数据传送指令
操作码 目标操作数 可选择的源操作数 说 明
MOV A
Rn
direct
@Ri
DPTR Rn;direct;@Ri;# data
A;direct;# data
A;Rn;direct;@Ri;# data
A;direct;# data
# data16 内部传送
内部传送
内部传送
内部传送
数据指针赋值
PUSH
POP 隐含(SP)
direct direct
隐含(SP) 压栈,只能用直接寻址
退栈,只能用直接寻址
XCH A Rn; direct; @Ri 内部交换
XCHD
SWAP A
A @Ri
隐含A 只交换低四位
A的高、低四位互换
MOVX A
@Ri
@DPTR @Ri; @DPTR
A
A A与外部数据存储器间传送
MOVC A @A+DPTR; @A+PC 读外部程序存储器
MOV C
bit bit
C Cy与可寻址位间传送
1. 数据传送指令的一般性说明
指令的一般格式: 操作码 目标操作数,源操作数
操作码 说明操作的性质
操作内容一般为 (目标操作数)←(源操作数)
8位操作数的形式有A、Rn、direct、@Ri、# data 等五种
16位操作数的形式有DPTR 与 # data16
1位操作数的形式有 C 与 bit
目标与源应同类型,且有规定的允许搭配,一般可逆。
A及direct可全搭配,@Ri、Rn不能相互搭配,# data只可作源.。
传送指令一般不影响标志位。
直接改写PSW的情况除外,改写Acc影响P标志。
2. 内部传送(MOV)
内部RAM、特殊功能寄存器(SFR)之间的数据传送。
注意立即数 #XXH与直接地址XXH 的区别。
@Ri指针使用要点:①与循环配合,适用于连续数据区的操作。
②Ri应先赋确定值。i=0,1。
③是XCHD指令唯一的源操作数。
3. 外部传送(MOVX)
以指针方式读、写外部数据存储器或I/O端口。
@DPTR提供16位地址指针,可访问总线扩展的整个64k空间。
@Ri只提供低8位地址指针,适用于256个地址的小规模总线扩展。
或者由P2口以I/O方式提供高8位(页) 地址,采用页访问模式。例如:
MOV P2,#30H ;由P2口提供高8位地址30H
MOV R0,#0 ;低8位地址为00H
MOVX A,@R0 ;读(3000H)单元
应用例:将内部30H40H单元的内容送外部数据存储器,从4000H单元开始存放。
MOV R0,#30H
MOV R2,#17
MOV DPTR,#4000H
LOOP: MOV A,@R0
MOVX @DPTR,A
INC R0
INC DPTR
DJNZ R2,LOOP
;设置(内部)源指针初值
;设置循环计数器初值
;设置(外部)目标指针初值
;循环入口,读源数据
;写目标数据
;源指针下移
;目标指针下移
;循环计数器减一,不为0则继续循环
4. 读外部程序存储器(MOVC)
读取外部程序存储器中的数据,用于查表。
MOVC A,@A+PC ;(A)←((A)+(PC)+1)
PC为本指令的地址,取指令后加一。
变址偏移量(A)是8位无符号数,因此查表的范围在(PC)+1 (PC)+255。
MOVC A,@A+DPTR ;(A)←((A)+(DPTR))
DPTR是16位指针,因此查表的范围为全64k空间。
应用例:查Y(x)函数表。
3000H MOV A,#表元素序号
3002H ADD A,#表头偏移量
3004H MOVC A, @A+PC
ORG 30A0H
TABLE: DB 17,22,34,58,82,103
表头偏移量=表头地址-(MOVC指令地址+1)
5. 栈操作(PUSH / POP)
堆栈在内部RAM区。
PUSH和POP的对象可以是内部RAM单元或SFR。
寻址方式只能用direct。例如,
PUSH 30H ;(SP)←(SP)+1,((SP))←(30H)
POP DPH ;(DPH)←((SP)),(SP)←(SP)-1
6. 交换(XCH / XCHD /SWAP)
XCH 字节交换:A与内部RAM单元或SFR交换。例如
XCH A,R2 ;(A)(R2)
XCHD 半字节交换:A与内部RAM单元进行低四位交换,只能用寄存器间址@Ri。例如
XCHD A,@R1 ;(A)D0- D 3 ((R1))D0- D 3
SWAP A ;(A)D0- D 3 (A)D4- D 7
应用例:拆字,将压缩BCD码扩展为单字节BCD码。
MOV R0, #30H 设立指针
MOV A, #0 ;(A)=0
XCHD A, @R0 ;(A)=0BH
MOV R4, A ;(R4)=0BH
XCH A,30H ;(A)=30H
SWAP A ;(A)=03H
MOV R3,A ;(R3)=03H
(三) 算术运算指令
表 3-3 算术运算指令
操作码 目标操作数 参与运算的操作数 说 明 Cy AC OV P
ADD A Rn; direct; @Ri; # data 不带进位加
ADDC A Rn; direct; @Ri; # data 带进位加
SUBB A Rn; direct; @Ri; # data 带借位减
MUL AB (A)*(B) 积在(B)(A)
0
-
DIV AB (A)/(B) 商 (A) ,余数 (B)
DA A 只对加法作十进制修正 - -
INC A; Rn; direct; @Ri; DPTR 加一
-
-
-
DEC A; Rn; direct; @Ri (无DPTR) 减一
*“”表示标志位根据运算结果取值,“-”表示对标志位无影响。
1. 算术运算指令的一般性说明
除加1/减1指令外,一般以累加器Acc为目标,且影响标志位。
没有不带借位减指令。用SUBB作不带借位减运算,Cy应先清零。
乘法若 积 > 255 , 则OV = 1 除法若 除数 = 0 , 则OV = 1 。
DA A 指令只对ADD 或ADDC作十进制修正。
无 DEC DPTR指令。
2. 加/减指令应用例
将内部RAM中从30H开始存放的10个双字节无符号整数相加,其和送(R5 R4 R3),低字节在R3。
MOV R0,#30H
MOV R2,#10
MOV R3,#0
MOV R4,#0
MOV R5,#0
LOOP:MOV A,@R0
ADD A, R3
MOV R3,A
INC R0
MOV A,@R0
ADDC A,R4
MOV R4,A
INC R0
MOV A,#0
ADDC A,R5
MOV R5,A
DJNZ R2,LOOP
将内部RAM中从30H开始存放的10个4位十进制正整数(压缩BCD码)相加,其和送(R5 R4 R3),低字节在R3。
比较A与B中的无符号数,大数存B。
MOV R2,A
CLR C ;确保C = 0
SUBB A,B
JC DONE ;若有借位,A<B,转DONE 结束。
MOV B,R2 ;没有借位,A>B,将大数存B。
DONE:
3. 乘/除指令应用例
双字节数乘单字节数:双字节数在(R3R4),单字节数在(R2),积送(R3R4R5)
MOV A,R2
MOV B,R4
MUL AB (R4)(R2)
MOV R5,A
MOV R4,B
MOV A,R2
MOV B,R3
MUL AB (R3)(R2)
ADD A,R4
MOV A,#0
ADDC A,B
MOV R3,A
单字节二进制数转十进制(BCD)数:二进制数在A,十进制数存入(R2R3)
MOV B,#10
DIV AB 除十, 余个位
MOV R3,B 个位存R3
MOV B,#10
DIV AB 再除十, 余十位
MOV R2,A 商为百位,存R2
MOV A,B
SWAP A
ADD A,R3 十位与个位合并
MOV R3,A;
(四) 逻辑运算指令
表 3-4 逻辑运算指令
操作码 目标操作数 参与运算的操作数 说 明
ANL A Rn; direct; @Ri; # data
逻辑与
direct A; # data
ORL A Rn; direct; @Ri; # data
逻辑或
direct A; # data
XRL A Rn; direct; @Ri; # data
逻辑异或
direct A; # data
CPL A — 累加器(A)取反
CLR A — 累加器(A)清零
RL
A
D7←…←D0 (A)左小循环,不影响Cy
RLC
A
D7←…←D0← C (A)左大循环
RR
A
D7→…→D0 (A)右小循环,不影响Cy
RRC
A
C →D7→…→D0 (A)右大循环
1. 逻辑运算指令的一般性说明
与、或、异或的逻辑运算指令可以Acc或direct为目标。但是以direct为目标时,另一操作数只能是Acc或立即数。
与、或、异或是对位逻辑运算。
其他逻辑运算指令只对Acc操作。
小循环不影响Cy,大循环Cy在循环圈内。
除了RLC和RRC,逻辑运算指令不影响P以外的标志位。
2. 与、或、异或的特殊用途
用ANL指令屏蔽指定位
例:ANL A,#0FH ;屏蔽高4位
用ORL指令将指定位置1
例:ORL A,#0FH ;将低4位置1
用ORL指令拼接一个字节
例:ANL A,#0FH
ANL B,#0F0H
ORL A,B
用XRL指令将指定位取反
例:XRL A,#55H ;将D0、D2、D4、D6等位取反
3. 循环移位指令的应用
乘除法运算
左移=无符号数乘2,右移=有符号数除2。
例:A×B,积存(BA)
算法:乘数在(A),积在(R2)(A)。
1) (A)右移一位;
2) (A)移出的一位若为1,则(R2)+被乘数(B);
3) 积(R2)(A)双字节右移一位;第2、3步循环8次。
为简化,假定为4位,循环4次。(A)=1011, (B)=1111
MOV R2,#0
MOV R3,#8
CLR C
RRC A
LP:XCH A,R2
JNC RRR
ADD A,B
RRR:RRC A
XCH A,R2 ;①
RRC A ;②
DJNZ R3,LP
MOV B,R2
下表第一列为:循环次数-执行点
其余各列为执行点的操作结果。
逻辑尺
以二进制数表示二值逻辑序列,逐位移出,并据此行逻辑控制。
(五) 位处理指令
表 3-5 位处理指令
操作码 目标操作数 源操作数 说 明
ANL
C
b i t / b i t / b i t表示取(b i t)的非值运算, 但不影响原值。
ORL
CPL C 或 b i t 将指定位取反。
SETB
C 或 b i t 将指定位置 “1”。
CLR 将指定位清零。
1. 位处理指令的一般性说明
在分类时将位传送归入传送指令类,条件转移归入程序控制类。其余位操作归为位处理指令。
位逻辑运算以C为目标,/ b i t表示取(b i t)的非值运算, 但不影响原值。
2. 位逻辑运算应用例
以软代硬:
MOV C, P1.1
ORL C, /P1.2
CPL C
ANL C, P1.0
ANL C, /P1.3 图3-1 应用例中的端口硬件逻辑
MOV P1.5, C
3. 位置值操作应用例
直接操作各功能部件的控制位。例如, 启动T0定时器。
SETB TR0
输出某一路开关量控制信号。例如, 从P1.0输出脉冲。
LOOP:CPL P1.0
延时半个脉冲周期,
返回LOOP,不断循环。
(六) 程序控制指令
表 3-6 程序控制指令
操作码 操作数 条 件 转 移 地 址 说 明
AJMP
addr11
无条件 (PC)←(PC)+2
(PC)0-10←addr11 短转移,只改变PC的低11位,转移范围2K。
LJMP addr16 无条件 (PC)←addr16 长转移,转移范围全64K空间
SJMP rel 无条件 (PC)←(PC)+2+rel 相对转移 ,范围-126~+129。
JMP @A+DPTR 无条件 (PC)←(A)+(DPTR) 散转指令,根据A值变址转移
ACALL
addr11
无条件 (PC)←(PC)+ 2
(PC)L、(PC)H压栈
(PC)0-10←addr11 短调用,只改变PC的低11位,转移范围2K。
LCALL addr16 无条件 (PC)←(PC)+ 3
(PC)L、(PC)H压栈
(PC)←addr16 长调用,调用范围全64K空间
RET 隐含
((SP))
无条件 (PC)H←((SP))
(PC)L←((SP)-1)) 子程序返回。
RETI 中断返回。
JZ
rel (A)= 0
(PC)←(PC)+2+rel
根据A的值条件转移。
JNZ (A)≠0
JC
rel (C)= 0
(PC)←(PC)+2+rel
根据C的值条件转移。
JNC (C)= 1
JNB
bit, rel
(bit)=0
(PC)←(PC)+3+rel
位值判别转移。(负逻辑)
JB (bit)=1 位值判别转移。(正逻辑)
JBC (bit)=1 同 JB ,加(bit)清零功能。
DJNZ Rn, rel (Rn)-1≠0 (PC)←(PC)+2+rel 循环指令。循环计数器自动
减1,归0则退出循环。
dir, rel (dir)-1≠0 (PC)←(PC)+3+rel
操作码
操作数
条 件
转 移 地 址
说 明
CJNE
A,dir,rel
A,#data,rel Rn,#data,rel
@Ri,#data,rel (A)≠(direct)
(A)≠#data
(Rn)≠#data
((Ri))≠#data
(PC)←(PC)+3+rel 按无符号数比较,两数不等则转移。若前一数小,C置1;若前一数不小于后一数,C清零。
NOP 无 无 (PC)←(PC)+1 空操作,顺序执行。
1. 程序控制指令的一般性说明
程序控制指令又分“无条件转移”、“调用与返回”和“条件转移”等三类。
对程序控制指令应掌握:转移地址如何生成及其转移范围。
注意!MCS-51条件转移指令的运用与计算并无特别的联系。
位值判别转移使程序设计更为灵活,是MCS-51指令系统的特色。
应特别注意变址转移指令JMP与比较转移指令CJNE的用法。
2. AJMP、LJMP及SJMP的转移范围
指令 转移地址 转移范围 说明
AJMP addr11 (PC)+2的高5位
+ addr11
(PC)+2所在的2k页 2k页:X000HX7FFH
X800HXFFFH
LJMP addr16 addr16 全64k空间
SJMP rel (PC)+2+rel (PC)-126(PC)+129 Rel是8位有符号数
注:①表中的(PC)是转移指令的地址。
②在实际使用时,地址一般用标号表示。
3. 变址转移指令JMP的使用
JMP的转移地址 = 基址(DPTR)+变址偏移量(A)。
应用例:按照(A)= 0,1,2,分别转向三个不同的程序分支。
MOV DPTR,#GO ;设立散转入口地址
MOV B A, ;
RL A (A) ←(A)+3
ADD A,B ;
JMP @A+DPTR
GO: LJMP GO1 ;指令地址为GO
LJMP GO2 ;指令地址为GO+3
LJMP GO3 ;指令地址为GO+6
问题一:上例中,如果由LJMP改用AJMP,程序应如何变化?
问题二:上例中,如果A的值大于2会如何?怎样解决?
4. 条件转移指令的使用
因为A与C的值并不一定由计算操作而改变,故JZ、JNZ、JC、JNC等指令的运用与计算并无特别的联系,
位值判别转移指令使条件转移的功能更丰富和灵活。例如:
如果(B)0,转向POS分支:JNB B.7,POS
如果计算溢出,转向FL分支: JB OV,FL
如果C=1,将C清零并转向NEG分支:JBC C,NEG
由P1.4检测火灾传感器,1有效。传感器报警时转向FIRE分支:JB P1.4,FIRE
5. 比较转移指令CJNE及其使用
格式:CJNE 前数,后数,相对偏移量
转移条件:前数≠后数
对C的影响:按无符号数减法。前数减后数,有借位C = 1,否则C = 0。
应用例:A、B中为无符号数,比较两数,大数存A,小数存B。
CJNE A,B,0
JNC DONE
EXC A,B
DONE:……
应用例:A、B中为有符号数,比较两数,大数存A,小数存B。
有符号数比较的算法:
以A 与B 表示A与B的无符号值。
对于A >B 有,若A>0 则A>B,A<0 则A<B;
据此可以画出右边的流程图,相应的程序如下
CJNE A,B,NEQ
SJMP DONE
NEQ:JNC AGT
XCH A,B
AGT:JNB Acc.7,DONE
XCH A,B
DONE:……
图3-2 有符号数比较
(七) MCS-51汇编语言程序设计方法
1. 汇编语言程序的基本结构
YES NO
(a)顺序结构 (b)分支结构
PC压栈
NO PC退栈
YES
(c)循环结构 (d)子程序结构
图3-3 四种基本程序结构
1) 顺序结构
程序模块或指令依次执行的结构。
2) 分支结构
根据条件,转向不同程序段(分支)的结构。
分支不应是模块间的转移,执行分支后应返回流程主线。
注意防止从一个分支的出口进入另一个分支的入口
3) 循环结构
按循环控制条件重复执行某一段程序,用于连续重复性操作。
循环圈包括循环体与循环控制;循环结构还包括循环初始化与后处理。循环控制有计数循环与条件循环两种。
循环可以嵌套,但不应交叉,也不要从循环体外跳入循环圈。
4) 子程序结构
在主程序中执行调用子程序指令,CPU转去执行子程序。在子程序中由返回指令返回主程序,继续执行调用指令的下一条指令。
调用时,先将返回地址压栈,并按调用指令提供的地址转入子程序。返回时,从堆栈弹出返回地址送PC,重返主程序。
程序中多处使用的功能模块可采用子程序结构,以节省程序空间。
编写与使用子程序的七要素:
功能说明。
子程序名与入口地址。
入口条件。
出口状态。
占用资源。
子程序中的调用。
编写与使用子程序的四项注意:
现场保护与现场恢复,避免与主程序冲突。
堆栈操作应成对,且PUSH先行,保护返回地址。
多重调用应考虑堆栈的容量,不宜直接或间接的自反调用。
防止不经调用进入子程序,禁止不经返回指令跳出子程序。
5) MCS-51汇编语言程序的一般格式
与8086不同,没有代码段、数据段等区分,统一编址。
程序由指令行或注释行组成,指令行每行只能写一条指令。
指令前可用“标号:”表示指令地址,以便在指令中引用;标号是符号名,以字母开头。
注释行应以“;”号开头;指令后也可用“;”号分隔,附加注释。
程序由伪指令ORG XXXXH 定位,ORG中的16位地址就是将来写入程序存储器的绝对地址。程序中的ORG应按地址从小到大排列。由ORG定位的程序段可以不连续,汇编程序将会在段间的空地址上填00H,即NOP。因此,每个ORG段的最后一条指令一般应是转移指令。
数据由伪指令DB(字节)或DW(双字节)说明。数值应以数码0-9开头;尾缀说明:B-二进制,D-十进制,H-十六进制。十进制D可缺省。
伪指令EQU可定义等价字段,以便用符号名代表某个操作数,例如:
aa EQU 30H
bb EQU #30H
MOV A,aa aa等价于“30H”, 该指令即 MOV A, 30H
MOV R0,bb bb等价于“#30H”,该指令即 MOV R0,#30H
2. 汇编语言程序设计方法
1) 评价程序优劣的因素
正确性,容错性。
结构化,简明易读,易检验,易维护。
省资源,高效率,易操作。
2) 程序设计过程与基本设计方法
模块化;结构化;自顶而下与自底而上。
结构化设计:
结构设计自顶而下:
功能设计→总体结构设计→局部结构设计→底层模块设计
→验证方法设计
具体设计自底而上:
模块→局部→整体,逐步整合、协调,调试与验证,最后总结建档。
从原理到程序实现
原理→模型→算法→流程→程序设计→调试→优化→验证→建档
3) 常用的程序调试方法
原则:先硬后软;先局部,后整体。
汇编检错-语法检查。
审视推演-逻辑检查。
准备测试数据,试运行。
附加测试指令,设置标志,输出中间结果。
单步调试
设置断点
4) 程序的优化与文件编制
参照评价因素,修改程序结构、数据结构、算法及程序,等等。
总结建档,编制说明文件
设计说明:
设计目标,原理,模型;设计方案,性能与特点;程序结构,数据结构,存储器分配;流程,加注释的程序清单;等等。
测试报告:
测试方法,测试数据,测试结果分析。
使用说明
功能,操作方法,出错信息与排除方法,注意事项,等等。