8051指令系统

本节将列举 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 一定要紧跟在 ADDADDC 后面使用。

  • 低四位
    • 如果 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 ; 右移
      
  • 半字节交换:将累加器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
      
  • 调用与返回指令
    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