本节将列举 51 中的汇编指令。我就不解释什么是汇编语言了,直接介绍格式。汇编程序是文本文件格式,文件类型一般是 .asm
,文件中每一行是一条语句,每条语句可以分成 4 部分:
[标号:] [操作码] [操作数] [;注释]
标号和注释不是必须的,可以不写。
51 一共有 111 条指令,按功能分可以分为:
功能 | 数目 |
---|---|
数据传送指令 | 28 |
算术运算指令 | 24 |
逻辑运算及移位指令 | 25 |
控制转移指令 | 17 |
位操作指令(布尔操作) | 17 |
我们规定如下符号,方便后续讲解。这些不用死记,看多就懂了:
符号 | 解释 |
---|---|
Rn(n=0-7) | 当前选中的工作寄存器组R0-R7。包括特殊功能寄存器。 |
Ri(i=0,1) | 作为地址指针的两个工作寄存器R0,R1。 |
#data | 8位立即数 |
#data16 | 16位立即数 |
direct | 8位片内RAM单元(包括SFR)的直接地址。 |
addr11 | 11位目的地址,用于ACALL和AJMP指令中。 |
addr16 | 16位目的地址。用于LCALL和LJMP指令中。 |
rel | 补码表示的8位地址偏移量。范围:-128-+127D |
bit | 片内RAM或SFR的直接寻址位地址。 |
@ | 间接寄存器的符号 |
/ | 位操作指令中对该位先取反再参与操作,不影响原值。 |
(×) | ×中的内容(相当于直接寻址)。 |
((×)) | ×指出的地址单元中的内容(相当于间接寻址) |
→ | 指令操作流程方向 |
寻址方式
程序需要对“数”操作,而数从哪里来呢?有如下七种方式:
寻址方式 | 源操作数寻址空间 |
---|---|
立即数寻址 | 程序存储器ROM |
直接寻址 | 片内RAM低128B、特殊功能寄存器 |
寄存器寻址 | 工作寄存器R0-R7、A、B、C、DPTR |
寄存器间接寻址 | 片内RAM低128B、片外RAM |
变址寻址 | 程序存储器(@A+PC,@A+DPTR) |
相对寻址 | 程序存储器256B范围(PC+偏移量) |
位寻址 | 片内RAM的20H-2FH字节地址、部分SFR |
数据传送指令
数据传送指令就是高级语言中的“赋值”,根据赋值的对象,分为如下几类:
- 以 A 为目的的操作数
MOV A, Rn MOV A, direct MOV A, @Ri MOV A, #data
xch A, Rn xch A, direct xch A, @Ri xchd A, @Ri ;低半字节交换
- 以寄存器为目的操作数
MOV Rn, A MOV Rn, direct MOV Rn, #data
- 以直接地址为目的操作数
MOV direct, A MOV direct, Rn MOV direct, direct MOV direct, @Ri MOV direct, #data
- 以间接地址为目的操作数
MOV @Ri, A MOV @Ri, direct MOV @Ri, #data
- 访问片外RAM
MOVX A, @Ri MOVX @Ri, A MOVX A,@DPTR MOVX @DPTR,A
- 十六位传送指令
MOV DPTR,#data16
- 读程序存储器的数据
MOVC A, @A+PC MOVC A,@A+DPTR
此外,还有栈操作(注意栈指针指向栈顶元素):
- PUSH(入栈)指令,堆栈指针自动加1
PUSH direct
- POP(出栈)指令,堆栈指针自动减1
POP direct
算术运算指令
加法
- 不带进位的加法,前面加后面,加完后结果放到 A 中
ADD A, Rn ; A-Rn→A,下同 ADD A, direct ADD A, @Ri ADD A, #data
- 带进位的加法,还会加上 PSW 中的 C 位,加完后结果放到 A 中
ADDC A, Rn ADDC A, direct ADDC A, @Ri ADDC A, #data
- 加 1 指令 (注意:加 1 和减 1 指令不影响 C 标志位)
INC A INC Rn INC direct INC @Ri INC DPTR
减法
- 带借位的减法,前面减后面,减完后结果放到 A 中
SUBB A, Rn SUBB A, direct SUBB A, @Ri SUBB A, #data
- 减 1 指令 (注意:加 1 和减 1 指令不影响 C 标志位)
DEC A DEC Rn DEC direct DEC @Ri
乘法和除法
- 乘法:将累加器A和寄存器B中两个无符号数相乘,所得16位积的低字节存放在A中,高字节存放中B中。
MUL AB
- A中内容除以B中内容,整数商存于A中,余数存于B中。
DIV AB
十进制调整指令
- 调整累加器内容为BCD码。
DA A
这个指令并不是将二进制转为 BCD 的,而是说如果两个 BCD 相加,那么 DA A
能将结果调整为 BCD。也就是说,DA A
一定要紧跟在 ADD
、ADDC
后面使用。
- 低四位
- 如果 A 的低四位小于等于 9,那么就已经是 BCD 了;反之,如果是大于 9,比如说 0AH,那么就加上 6,变成 11H,这样低四位就是 BCD 了
- 还有一种特殊情况,如果 AC flag=1,那么低四位也会加 6
- 注意,加 6 后会向高四位进 1
- 高四位
- 高四位基本上与低四位的情况一致,如果大于 9 或 C flag=1,那么高四位加 6,如果有进位,那么就将 C 置 1,但不会影响 OV
示例用法:
设(A)=55H, (30H)=66H
执行 ADD A,30H 后 (A)=0BBH, C=0
再执行 DA A 后 (A)=21H,C=1
相当十进制的55+66=121
逻辑操作指令与移位
- 清零,只影响标志位P
CLR A
- 取反,不影响标志位
CPL A
- 移位
- 非循环移位(算数移位):舍弃多的一位,并在另一边补 0
RL A ; 左移 RR A ; 右移
- 循环移位:将累加器A的内容连同进位位CY一起循环移位,多的一位移到 CY,然后将原来 CY 补回另一边
RLC A ; 左移 RRC A ; 右移
- 非循环移位(算数移位):舍弃多的一位,并在另一边补 0
- 半字节交换:将累加器A的高低两半字节交换
SWAP A
- 与
ANL A,Rn ANL A,direct ANL A, @Ri ANL A, @Ri ANL direct, A ANL direct,#data
- 或
ORL A,Rn ORL A,direct ORL A, @Ri ORL A, @Ri ORL direct, A ORL direct,#data
- 异或
XRL A,Rn XRL A,direct XRL A, @Ri XRL A, @Ri XRL direct, A XRL direct,#data
控制转移指令
- 空操作
NOP
- 无条件转移指令
AJMP Addr11 ; 短转移,在2KB范围内跳转 LJMP Addr16 ; 长转移,在64KB范围内跳转 SJMP Rel ; 相对转移,在256字节内跳转 JMP @A+DPTR ; 间接转移
- 条件转移指令
- 将 A 与 0 比较
JZ Rel ; 当累加器A的内容为0时跳转到Rel JNZ Rel ; 当累加器A的内容不为0时跳转到Rel
- 将 A 与其他数比较
CJNE A, Rn, Rel ; A与Rn不相等则跳转到Rel CJNE A, #data, Rel ; A与data不相等则跳转到Rel CJNE Rn, #data, Rel ; Rn与data不相等则跳转到Rel CJNE @Ri, #data, Rel ; @Ri与data不相等则跳转到Rel
- 减一后与 0 比较
DJNZ Rn, Rel ; Rn先减1,当Rn=0往下执行,否则跳转到rel DJNZ direct, Rel ; direct先减1,当direct=0往下执行,否则跳转到rel
- 将 A 与 0 比较
- 调用与返回指令
ACALL addr ; 短调用,2KB范围 LCALL addr ; 长调用,64KB范围 RET ; 从子程序返回 RETI ; 中断返回
位操作类指令
位地址的表示方式:
- 直接写位地址: 如0D4H;
- 点操作符号: 如PSW.4或(0D0H).4;
- 位名称方式: 如RS1;
- 用户定义方式:Speaker bit P0.3
位操作类指令:
- 位数据传送
MOV C, bit MOV bit, C
- 位清零、置位、取反
CLR C ; 清零 CLR bit SETB C ; 置位 SETB bit CPL C ; 取反 CPL bit
- 位逻辑运算
ANL C, bit ; C与bit的值进行逻辑“与”操作,结果在C中 ANL C, /bit ; 和上面类似,/表示取反 ORL C, bit ; ORL C, /bit ;
- 位条件转移
JC rel ; 当C=1时跳转 JNC rel ; 当C=0时跳转 JB bit, rel ; 当bit=1时跳转 JNB bit, rel ; 当bit=0时跳转 JBC bit, rel ; 当bit=1时跳转,同时清除bit
伪指令
① ORG:
- 格式:ORG 地址(16进制表示)
- 作用:用于指明程序或数据从程序存储空间的什么位置开始存放。ORG伪指令后的地址是程序或数据的起始地址。
例:
ORG 1000H(指明后面的程序从程序存储器的1000H单元开始存放)
START:MOV A,#7FH
② DB:
- 格式:[标号:] DB 项或项表
- 作用:用于定义字节数据,可以定义一个字节也可以定义多个字节。定义多个字节时,两两之间用逗号隔开,定义时多个字节是在存储器中连续存放的。
例:
ORG 3000H
TAB1: DB 12H,34H
DB '5','A','abc'
③ DW
- 格式:[标号:] DW 项或项表
- 作用:与DB相似,但用于定义字数据。项或项表所定义的一个字在存储器中占两个字节。汇编时,机器自动按高字节在前、低字节在后存放,即高字节存放在低地址单元,低字节存放在高地址单元。
例:
ORG 3000H
TAB2:DW 1234H, 5678H
④ DS
- 格式:[标号:] DS 数值表达式
- 作用:用于在存储器中保留一定数量的字节单元。保留存储单元空间是为了以后存放数据使用。保留的字节单元数由表达式的值决定。
例:
ORG 3000H
TAB1: DB 12H, 34H
DS 4H
DB '5'
⑤ EQU
- 格式:EQU 项
- 作用:将指令中项的值赋予EQU前面的符号。项可以是常数、地址标号或表达式。
例:
TAB1 EQU 1000H
TAB2 EQU 2000H
结果:TAB1的值为1000H,TAB2的值为2000H。
⑥ DATA
- 格式:符号 DATA 直接字节地址
- 作用:用于给片内RAM字节单元地址赋予DATA前面的符号,符号以字母开头,同一单元地址可以赋予多个符号。赋值后可用该符号代替DATA后面的片内RAM字节单元地址(有点像C里面的define)
例:
RESULT DATA 60H (RESULT代表片内RAM的60H单元)
....
MOV RESULT , A
⑦ XDATA
- 格式:符号 XDATA 直接字节地址
- 作用:与DATA基本相同,不同点是对片外RAM的字节单元
⑧ bit
- 格式:符号 bit 位地址
- 作用:用于给位地址赋予符号,经赋值后可用该符号代替bit后面的位地址。
例:
PLG bit F0
AL bit P1.0
⑨ END
- 格式:放于程序最后位置,指明程序的结束位置。
指令对比
影响 PSW 的指令
下表中,0 表示置零,1 表示置 1,x 表示根据结果置位
C | OV | AC | C | OV | AC | ||
---|---|---|---|---|---|---|---|
ADD |
x | x | x | CLRC |
o | ||
ADDC |
x | x | x | CPLC |
x | ||
SUBB |
x | x | X | ANL C,bit |
X | ||
MUL |
o | x | ANL C,/bit |
X | |||
DIV |
o | x | ORL C,bit |
X | |||
DA |
x | ORL C,bit |
X | ||||
RRC |
x | MOV C,bit |
X | ||||
RLC |
x | CJNE |
x | ||||
SETB C |
1 |
参考
https://www.keil.com/dd/docs/datashts/intel/ism51.pdf