1 指令格式※
MCS-51 单片机汇编语言指令格式如下:
[标号:] 操作码 [操作数或操作数地址] [;注释]
- 标号是程序员根据编程需要,给指令所在地址设定的符号表示;标号由1~8个字符组成,第一个字符必须是英文字母,不能是数字或其他符号,标号不允许与保留字(关键字,如指令中的助记符或伪指令助记符)重名;标号后必须用冒号,标号不能重复使用。
- 操作码表示指令的操作类型或操作功能,如
MOV
表示数据传送操作,ADD
表示加法操作等。 - 操作数或操作数地址表示参加运算的数据或数据的有效地址。操作数一般有以下几种形式:没有操作数项,操作数隐含在操作码中,如
RET
、NOP
等指令;只有一个操作数,如CPL A
指令;有两个操作数,如MOV A,#00H
指令,操作数之间以逗号相隔;有三个操作数,如CJNE A,#00H,NEXT
指令,操作数之间以逗号相隔。如指令“MOV 78H,#80H
”的机器码为 747880H,即第一字节(操作码):01110100B,第二字节[第一操作数(目的地址)]:01111000B,第三字节[第二操作数(立即数80H)]:10000000B。 - 注释是对指令的解释说明,用以提高程序的可读性,注释前必须加分号。
特别要强调的是,汇编指令中涉及的特殊符号都为半角符号,汇编指令中的英文字母不区分大小写,编程时要严格按照指令格式的顺序书写,各部分之间要加上规定的分隔符。标号以冒号结束,操作码与操作数之间用空格分开,操作数与操作数之间用逗号分隔,注释前用分号作引导。
2 寻址方式※
寻找操作数地址的方式称为寻址方式。
2.1 寄存器寻址※
2.2 直接寻址※
2.3 立即寻址※
2.4 寄存器间接寻址※
2.5 变址寻址※
2.6 相对寻址※
2.7 位寻址※
3 指令系统类型※
MCS-51 单片机指令系统包括 111 条指令,可按照下表进行分类。
按功能分类 | 按字节数分类 | 按周期数分类 | |||
---|---|---|---|---|---|
指令类型 | 数量 | 指令类型 | 数量 | 指令类型 | 数量 |
数据传送指令 | 29 | 单字节指令 | 49 | 单周期指令 | 64 |
算术运算指令 | 24 | 双字节指令 | 45 | 双周期指令 | 45 |
逻辑运算指令 | 24 | 三字节指令 | 17 | 三周期指令 | 2 |
控制转移指令 | 17 | ||||
位操作指令 | 17 |
MCS-51 单片机指令系统出现的相关符号的含义如表 2.2 所示。
符号 | 含义或取值 |
---|---|
A | 累加器 ACC(若指令中写成 ACC 则为直接寻址) |
B | 寄存器 B,主要用于乘除指令,也可作通用寄存器 |
C | 进位标志 CY,在位操作中作为位运算累加器,又称布尔累加器 |
#data | 8 位立即数(常数) |
#data16 | 16 位立即数(常数) |
direct | 存储单元直接地址,如 30H |
Ri | 寄存器间接地址,i 取 0 或 1 |
@ | 间接寻址方式中,作为间接寻址寄存器的前缀 |
Rn | 工作寄存器,n 取 0~7 |
rel | 补码形式表示的 8 位相对偏移地址,取值范围 −128~+127 |
addr11 | 11 位目的地址 |
addr16 | 16 位目的地址 |
$ | 当前指令地址 |
bit | 片内 RAM 或 SFR 中某一可寻址位的位地址 |
/ | 位操作数的取反操作前缀符号 |
(PC) | 16 位二进制数 |
(DPTR) | 16 位二进制数 |
(X) | X 可为 A、B、Rn、(Ri)、(direct)、(DPTR) 等,(X) 表示 X 对应单元或寄存器中的 8 位二进制内容 |
((X)) | 以 X 单元或寄存器内容为地址的单元中的内容 |
3.1 数据传送指令※
3.1.1 以 MOV 为操作符的指令※
- 格式:MOV <目的操作数>,<源操作数>
目的操作数 | 源操作数 | 数量 | 说明 | ||||
A | Rn | direct | @Ri | #data | |||
A | X | 4 | 每一行代表的是以A、Rn、direct、@Ri、DPTR为目的操作数的指令,“X”表示该指令不存在。其中#datal6表示16位二进制数 | ||||
Rn | X | X | 3 | ||||
direct | 5 | ||||||
@Ri | X | X | 3 | ||||
DPTR | X | X | X | X | #data16 | 1 | |
数量 | 3 | 2 | 4 | 2 | 5 | 16 |
3.1.2 以 MOVX 为操作符的指令※
- 格式:MOVX <目的操作数>,<源操作数>
- 解释:A 和 RAM 的数据交换
操作符 | 目的操作数 | 源操作数 | 数量 | 说明 | ||
A | @DPTR | @Ri | ||||
MOVX | A | X | √ | √ | 2 | 把外部 RAM数据取到A |
@DPTR | √ | X | X | 1 | 把A的数据送外部RAM | |
@Ri | √ | X | X | 1 | 把A的数据送外部RAM | |
数量 | 2 | 1 | 1 | 4 |
3.1.3 以 MOVC 为操作符的指令※
- 格式:MOVC <目的操作数>,<源操作数>
- 解释:ROM → A 的数据传送
MOVC A, @ A + DPTR ;A ← ((A) + (DPTR))
MOVC A, @ A + PC ;A ← ((PC) + (PC))
3.1.4 交换指令※
- 格式:XCH/XCHD <目的操作数>,<源操作数>
操作符 | 目的操作数 | 源操作数 | 数量 | 说明 | ||
Rn | direct | @Ri | ||||
XCH | A | √ | √ | √ | 3 | 字节交换指令 |
XCHD | A | X | X | √ | 1 | 半字节交换指令 |
3.1.5 堆栈操作指令※
PUSH direct
POP direct
3.2 算术运算指令※
3.2.1 加法指令※
ADD A, Rn ;A ← (A) + (Rn)
ADD A, @Ri ;A ← (A) + ((Ri))
ADD A, direct ;A ← (A) + (direct)
ADD A, #data ;A ← (A) + #data
3.2.2 带进位加法指令※
ADDC A, Rn ;A ← (A) + (Rn) + (CY)
ADDC A, @Ri ;A ← (A) + ((Ri)) + (CY)
ADDC A, direct ;A ← (A) + (direct) + (CY)
ADDC A, #data ;A ← (A) + #data + (CY)
3.2.3 加 1 指令※
INC A ;A ← (A) + 1
INC Ri ;Ri ← (A) + 1
INC direct ;direct ← (direct) + 1
INC @Ri ;(Ri) ← ((Ri)) + 1
INC DPTR ;DPTR ← (DPTR) + 1
3.2.4 十进制调整指令※
DA A
3.2.5 带借位减法指令※
SUBB A, Rn ;A ← (A) - (Rn) - (CY)
SUBB A, @Ri ;A ← (A) - ((Ri)) - (CY)
SUBB A, direct ;A ← (A) - (direct) - (CY)
SUBB A, #data ;A ← (A) - #data - (CY)
3.2.6 减 1 指令※
DEC A ;A ← (A) - 1
DEC Ri ;Ri ← (A) - 1
DEC direct ;direct ← (direct) - 1
DEC @Ri ;(Ri) ← ((Ri)) - 1
3.2.7 乘法指令※
MUL AB
- (AB)16 ← (A)8 × (B)8
- (A)8 ← (AB)7-0
- (B)8 ← (AB)15-8
3.2.8 除法指令※
DIV AB
- (A)8 ÷ (B)8 → (A)8 …… (B)8
3.3 逻辑运算指令※
3.3.1 清零取反指令※
CLR A ;A ← 0
CPL A ;A ← A
3.3.2 循环移位指令※
RL A ;循环左移1位
RLC A ;带进位循环左移一位
RR A ;循环右移1位
RRC A ;带进位循环右移一位
3.3.3 逻辑与指令※
ANL A, Rn ; (A) ∧ (Rn) → (A)
ANL A, direct ; (A) ∧ (direct) → (A)
ANL A, #data ; (A) ∧ data → (A)
ANL A, @Ri ; (A) ∧ ( (Ri) ) → (A)
ANL direct, A ; (direct) ∧ (A) → (direct)
ANL direct, #data ; (direct) ∧ data → (direct)
3.3.4 逻辑或指令※
ORL A, Rn ; (A) ∨ (Rn) → (A)
ORL A, direct ; (A) ∨ (direct) → (A)
ORL A, #data ; (A) ∨ #data → (A)
ORL A, @Ri ; (A) ∨ ( (Ri) ) → (A)
ORL direct, A ; (direct) ∨ (A) → (direct)
ORL direct, #data ; (direct) ∨ data → (direct)
3.3.5 逻辑异或指令※
XRL A, Rn ; (A) ⊕ (Rn) → (A)
XRL A, direct ; (A) ⊕ (direct) → (A)
XRL A, #data ; (A) ⊕ #data → (A)
XRL A, @Ri ; (A) ⊕ ( (Ri) ) → (A)
XRL direct, A ; (direct) ⊕ (A) → (direct)
XRL direct, #data ; (direct) ⊕ data → (direct)
3.4 位操作指令※
3.4.1 数据位传送指令※
MOV C, bit ; bit 可直接寻址位 C ← (bit)
MOV bit, C ; C 进位位 (bit) ← C
3.4.2 位变量修改指令※
CLR C ; 将 C = 0
CLR bit ; (bit) ← 0
CPL C ; 将 C 求反再存入 C
CPL bit ; 将 bit 求反再存入 bit
SETB C ; 将 C = 1
SETB bit ; (bit) ← 1
3.4.3 位变量逻辑指令※
ANL C, bit ; (C) ∧ (bit) → (C)
ANL C, /bit ; (C) ∧ (/bit) → (C)
ORL C, bit ; (C) ∨ (bit) → (C)
ORL C, /bit ; (C) ∨ (/bit) → (C)
3.5 控制转移指令※
3.5.1 无条件跳转指令※
AJMP addr11 ; (PC) + 2 → (PC), addr11 → (PC10~0), 跳转范围 2K
LJMP addr16 ; PC ← addr16, 跳转范围 64K
JMP @A+DPTR ; PC ← (A) + (DPTR)
SJMP rel ; (PC) + 2 → (PC), (PC) + rel → (PC)
3.5.2 条件转移指令※
JZ rel ; 若 (A) = 0, 转移, 即 (PC) + 2 + rel → (PC)
; 若 (A) ≠ 0, 不转移, 即 (PC) + 2 → (PC)
JNZ rel ; 若 (A) ≠ 0, 转移, 即 (PC) + 2 + rel → (PC)
; 若 (A) = 0, 不转移, 即 (PC) + 2 → (PC)
JC rel ; 若 CY = 1, 转移, 即 (PC) + 2 + rel → (PC)
; 若 CY = 0, 不转移, 即 (PC) + 2 → (PC)
JNC rel ; 若 CY = 0, 转移, 即 (PC) + 2 + rel → (PC)
; 若 CY = 1, 不转移, 即 (PC) + 2 → (PC)
JB bit, rel ; 若 bit = 1, 转移, 即 (PC) + 3 + rel → (PC)
; 若 bit = 0, 不转移, 即 (PC) + 3 → (PC)
JNB bit, rel ; 若 bit = 0, 转移, 即 (PC) + 3 + rel → (PC)
; 若 bit = 1, 不转移, 即 (PC) + 3 → (PC)
JBC bit, rel ; 若 bit = 1, 转移, 即 (PC) + 3 + rel → (PC), 且 bit = 0
; 若 bit = 0, 则 (PC) + 3 → (PC)
3.5.3 比较不相等转移指令※
CJNE A, direct, rel
CJNE Rn, #data, rel
CJNE @Ri, #data, rel
3.5.4 减 1 不为 0 转移指令※
DJNZ Rn, rel
DJNZ direct, rel
3.5.5 调用子程序指令※
短调用指令(绝对调用):
ACALL addr11 ; (PC) + 2 → (PC), (SP) + 1 → (SP), PC7~0 → (SP);
; (SP) + 1 → (SP), PC11~8 → (SP); addr11 → PC10~0
长调用指令:
LCALL addr16 ; (PC) + 3 → (PC), (SP) + 1 → (SP), PC7~0 → (SP);
; (SP) + 1 → (SP), PC15~8 → (SP); addr16 → (PC)
子程序返回指令:
RET ; ((SP)) → PC15~8, 弹出 PC 高 8 位, (SP) - 1 → (SP)
; ((SP)) → PC7~0, 弹出 PC 低 8 位, (SP) - 1 → (SP)
中断返回指令:
RETI ; ((SP)) → PC15~8, 弹出 PC 高 8 位, (SP) - 1 → (SP)
; ((SP)) → PC7~0, 弹出 PC 低 8 位, (SP) - 1 → (SP)
3.5.6 空操作指令※
NOP