第 3 章 MCS-51 单片机指令系统

第 3 章 MCS-51 单片机指令系统

1.MCS-51 单片机指令概述

  • MCS-51系列单片机指令系统共有111条指令。

按功能分为5类:①数据传送(29条)②算术运算(24条)③逻辑运算(24条)④控制转移(17条)⑤布尔处理(17条)

按字节长度分为3类:①单字节指令(49条)②双字节指令(46条)③三字节指令(只有16条)

按执行时间分为3类:①单机器周期指令(64条)②双机器周期指令(45条)③四机器周期指令(只有2条)

  • MCS-51单片机指令系统的特点:
    • ① 助记符少:MCS-51指令系统用44种助记符表示了33种指令功能。
    • ②空间和时间效率均较高:平均指令长度和平均指令执行时间短。
    • ③更适合于实时控制: MCS-51指令系统中有17条布尔处理指令。

1.MCS-51单片机汇编语言指令格式

在这里插入图片描述

  • 操作码用来规定指令进行什么操作;
  • 操作数则是指令操作的对象;
  • 有单字节指令、双字节指令、三字节不同长度的指令,格式不同:
    • 1)单字节指令:指令只有一个字节,操作码和操作数同在一个字节中。
    • 2)双字节指令:一个字节为操作码,另一个字节是操作数。
    • 3)三字节指令:操作码占一个字节,操作数占二 个字节。其中操作数既可能是数据,也可能是地址。

操作数的特点:

① 操作数可以是数据本身,也可以是数据的地址、数据地址的地址或操作数的其他信息;

② 操作数可分为目的操作数和源操作数;

③ 操作数可用二进制数、十进制数或十六进制数表示;

④ 操作数的个数可以是0~3个;

⑤ 操作数与操作码之间用空格分隔,操作数与操作数之间用逗号“,”分隔。

2.布尔处理机

  • 布尔处理机——位处理机,专门用于位处理。

布尔处理机硬件主要由以下五部分支持:

① 布尔运算器ALU。

② 布尔累加器Cy(PSW.7)。

③ 布尔RAM区。

④ 布尔I/O口

⑤ 布尔指令集

3.指令中的常用符号

  • 1)#:立即数前导符。#data:8 位立即数;#data16:16 位立即数。
  • 2)direct:8 位直接地址,代表片内 RAM 或 SFR 的地址 00H~7FH 或 80H~FFH。
  • 3)@:间接寻址符。在间接寻址方式中,表示间接寻址寄存器指针的前缀标志。如@Ri, @DPTR,@A+PC,@A+DPTR。
  • 4)addr11:11 位目的地址。主要用于 ACALL 和 AJMP 指令中。
  • 5)addr16:16 位目的地址。主要用于 LCALL 和 LJMP 指令中。
  • 6)rel:带符号的 8 位偏移地址。主要用于相对转移指令,以形成转移的目的地址,其 范围是相对于下一条指令第 1 字节地址的−128~+127 个字节。
  • 7)bit:位地址。代表片内 RAM 中的可寻址位 00H~7FH 及 SFR 中的可寻址位。
  • 8)Rn(n=0~7):表示当前工作寄存器 R0~R7 中的任一个寄存器。
  • 9)Ri(i=0 或 1):表示通用寄存器组中用于间接寻址的两个寄存器 R0 或 R1。
  • 10)A(或 ACC)、B:表示累加器、B 寄存器(A 是寄存器寻址方式,ACC 是直接寻 址方式的累加器)。
  • 11)C:表示 PSW 中的进位标志位 Cy,也称位累加器。
  • 12)$:表示当前指令的地址。
  • 13)/:在位逻辑与、逻辑或操作指令中,表示对该位先求反后再参与相应的逻辑运算, 但该位的内容保持不变。
  • 14)(X):表示由 X 所指定的某寄存器或某单元中的内容。
  • 15)((X)):表示由 X 间接寻址单元中的内容。
  • 16)←:表示指令的操作结果是将箭头右边的内容传送到左边。
  • 17)→:表示指令的操作结果是将箭头左边的内容传送到右边。
  • 18) ∧ 、∨ 、⊕ :表示逻辑与、或、异或。

2.MCS-51 单片机的寻址方式

寻址方式——计算机指令中说明操作数所在地址的方法。

MCS-51 单片机的指令系统有 7 种寻址方式,分别为立即寻址、直接寻址、寄存器寻址、 寄存器间接寻址、基址加变址寻址、相对寻址和位寻址。

1.立即寻址

  • 寻址空间:程序存储器。
  • 立即寻址是指指令中直接给出操作数本身的寻址方式。指令中的操作数称为立即数,立即数前面加“#”以区别直接寻址。

在这里插入图片描述

例如:MOV A,#45H

  • 其中,45H就是立即数,指令的功能是把立即数45H传送到累加器A中。参考下图:

在这里插入图片描述

注:E0H为累加器A的字节地址。

  • 在MSC-51型单片机中,除了有8位立即数外,还有一条16位立即数的数据传送指令,即MOV DPTR,#dataH,其功能是把16位立即数传送到数据指针DPTR中。

例如:MOV DPTR,#1234H

  • 上式表示把立即数1234H传送到数据指针DPTR中,其中12H传送到DPH,34H传送到DPL中。参考下图:

在这里插入图片描述

注:DPH的字节地址是83H,DPL的字节地址是82H。

2.直接寻址

  • 寻址空间:内部RAM的低128字节和特殊功能寄存器SFR(直接寻址是访问SFR的唯一寻址方式)。
  • 指令中给出的不是操作数本身,而是操作数的单元地址称为直接寻址
  • 直接寻址的指令有三种形式:

在这里插入图片描述

例如:MOV A, 45H

  • 45H就是要操作的数据所在的单元地址,如果内RAM(45H)=36H,那么指令执行后(A)=36H。参考下图:

在这里插入图片描述

例如:ANL 30H,#30H

  • ANL是逻辑“与”操作指令,第一个30H是操作数地址,第二个30H是参加“与”运算的操作数。最后将“与”的结果存入第一个30H单元中。

在这里插入图片描述

例如:
	MOV 40H,B		// 将寄存器B中的数值送入内部RAM的40H单元中
    INC 30H			// 将内部RAM的30H单元中的数值加一
    MOV TL0,R7		// 将寄存器R7中的数值送入特殊功能寄存器TL0中

3.寄存器寻址

  • 寻址空间:R0~R7,A、B、Cy(位),DPTR。

  • 寄存器寻址方式:指令给出存放操作数据的某个寄存器,而不是数据本身。即指出寄存器组R0~R7中的某一个或其他寄存器(A,B,DPTR和进位Cy等)的内容为操作数。当寄存器为Rn时,操作码的低3位指明是R0~R7中的哪一个。

  • 寄存器寻址有三种指令形式:

在这里插入图片描述

例如:MOV A,R7

  • 指令中R7就是存放源操作数据的寄存器,如果(R7)=19H,则指令执行后(A)=19H,而上述指令为:01011111,其中低三位111就表示操作数寄存器是R7。

在这里插入图片描述

例如:
    MOV R1,B		// 将寄存器B中的数值送入寄存器R1中
    INC R2			// 将寄存器R2中的数值加一
    MOV A,R5		// 将寄存器R5中的数值送入累加器A中

4.寄存器间接寻址

  • 寻址空间:内部RAM(@R0,@R1,SP)和外部数据存储器(@R0,@R1,@DPTR)。

  • 将要处理的数据的地址放在寄存器中,即用寄存器中的数据作为存储单元的地址数值

  • 寄存器间接寻址的操作数要以寄存器的符号形式表示,即在寄存器前面添加前缀“@”

  • 寄存器间接寻址有三种指令形式:

在这里插入图片描述

例如:已知(R0)=30H,(30)=40H,分析指令:MOV A,@R0

  • 这是累加传送指令,设(R0)=30H,则该指令是把内部RAM的30H写入累加器A中。

在这里插入图片描述

例如:
    MOV @R1,#05H		// 将数值05H送入以R1内数值为地址的内部RAM中
    ADD A,@R1			// 将A寄存器中的数值加上R1内部数值为地址的内部RAM单元中的数据,结果存放于A中
    MOVX A@DPTR		// 将以DPTR中数值为地址的外部数据存储器的内容送至A中存储

5.基址加变址寻址

  • 基址加变址寻址:将要处理的数据地址分开存放在基地址和变地址寄存器中,即用一个寄存器(称为基址寄存器)中的数据作为存储单元的基本地址数值,用另一个寄存器(称为变址寄存器)中的数据作为存储单元的偏移地址数值,实际寻址单元的地址数值为两个寄存器内容之和
  • 寻址空间:程序存储器(@A+DPTR,@A+PC)
  • 以DPTR或PC作基址寄存器,A作变址寄存器(存放8位无符号数),两者相加形成16位程序存储器地址作操作数地址,用改地址去访问ROM
  • 该寻址方式是单字节指令,用于读出程序存储器中数据表格中的常数(查表)到累加器A中。

例如:已知(DPTR)=1234H,(A)=50H,程序存储器(1284H)=65H,分析如下执行结果:MOVC A,@A+DPTR。

  • DPTR与A相加后的地址是1284H,而实际寻址地址是1284H,其操作数是65H,最后将65H送至累加器A中。

在这里插入图片描述

例如:
	MOVC A,@A+PC		// 将A和PC两个寄存器的数值相加之和作为程序存储器中的数据地址,将该地址的内容送到A中
	MOVC A,@A+DPTR    	 // 将A和DPTR两个寄存器的数值相加之和作为程序存储器中的数据地址,将该地址的内容送到A中

6.相对寻址

  • 相对寻址是把程序计数器PC的内容加上指令格式中的形式地址D而形成操作数的有效地址。程序计数器的内容就是当前指令的地址。“相对”寻址,就是相对于当前的指令地址而言。
  • 寻址空间:程序存储器
  • 在相对转移指令中使用,相对转移指令执行时,将当前的PC值加上指令中规定的偏移量rel,其和作为实际的转移目标地址。
  • PC的当前值是相对转移指令下面一条指令的地址。
  • 目标地址、当前的PC值和rel三者之间的关系:
    • rel=目标地址-(PC)
    • rel为补码形式的8位地址偏移量(-128~+127)
  • 相对转移指令有三种指令形式:

在这里插入图片描述

例如:2000H:SJMP 06H

  • 该指令是一条2B指令,它存储在ROM 2000H、2001H这两个单元中。当执行到该指令时,首先取出该指令,由于PC具有自动加1功能,取出指令后PC内容已加2,此时PC当前值为2002H,地址偏移量06H为正值,可得转移的目的地址是2002H+06H=2008H,即程序将从2008处开始执行。执行过程如图所示:

在这里插入图片描述

  • 偏移量rel的计算公式
    • 正向跳转时: r e l = 目 的 地 址 − 转 移 指 令 所 在 的 起 始 地 址 − 转 移 指 令 的 字 节 数 = 地 址 差 值 − 转 移 指 令 的 字 节 数 rel=目的地址-转移指令所在的起始地址-转移指令的字节数=地址差值-转移指令的字节数 rel==
    • 反向跳转时,目的地址小于转移指令的起始地址,rel用负数的补码形式表示。 r e l = ( 目 的 地 址 − ( 转 移 指 令 的 起 始 地 址 + 转 移 指 令 的 字 节 数 ) ) 补 rel=(目的地址-(转移指令的起始地址+转移指令的字节数))_补 rel=((+))
有如下程序段
	……
	JNZ     NEXT
	……
NEXT:……

	假设指令JNZ   NEXT的地址为2000H(当前PC的值为2002H),标号NEXT的地址为2340H,则指令JNZ  NEXT中的相对偏移量:	rel=2340H-2002H=33EH
        
        2340H:0010 0011 0100 0000
        2002H:0010 0000 0000 0010
        
        	0010 0011 0100 0000
        +	0010 0000 0000 0010
        --------------------------
        	0000 0011 0011 1110
        --------------------------
        	  0    3    3    E		H
        
        所以,rel=33EH
        
	机器汇编时,该rel的值是在汇编时由汇编器计算,人工汇编时由程序员计算
	指令JNZ   NEXT执行时,将计算当前PC的值与rel之和(2002H+33EH=2340H),然后转移到地址为2340H处执行

7.位寻址

  • 寻址空间:片内RAM的20H~2FH中的128个可寻址位和11个字节地址能被8整除的SFR中的83个可寻址位,共210个位。
  • 对内部RAM、特殊功能寄存器SFR中的位地址空间进行访问寻址方式称之为位寻址 。
  • 注意:访问累加器CY的寻址方式既可属于寄存器寻址又可属于位寻址。
  • 位地址的表示有4种方法:
    • ① 直接使用位寻址区中的位地址。MOV C,7EH; (Cy)←(7EH)
    • ② 采用“字节地址.位号”表示方法。上述位地址7EH可以表示为2FH.6,相应指令为:MOV C,2FH.6 ;(Cy)←(2FH.6)
    • ③ 采用“特殊功能寄存器名.位号”表示方法。MOV C,ACC.0 ;(Cy)←(ACC.0)
    • ④ 使用位名称。SETB EA

注:SETB EA:EA置为1;CLR EA:EA置为0

各寻址方式与相应的寻址空间

寻址方式利用的变量使用的空间
寄存器寻址R0~R7,A,B,CY,DPTR片内
直接寻址direct片内RAM低128字节 特殊功能寄存器SFR
寄存器间址@R0,@R1,SP @R0,@R1,@DPTR片内RAM 片外RAM与I/O口
立即寻址#data程序存储器
基址加变址@A+PC @A+DPTR程序存储器
相对寻址PC+rel程序存储器
位寻址bit片内RAM的20H~2FH 可位寻址的SFR

3.MCS-51 单片机的指令系统

在MCS-51单片机的指令中:操作码占1字节;

  • 操作数中:

    • 直接地址direct占1字节
    • #data占1字节
    • #data16占两字节
  • A、B、R0~R7、@Ri、@DPTR、@ A+ DPTR、 @ A+ PC等均隐含在操作码中(由操作码中的几位二进制位表示)。

1.数据传送指令

所谓数据“传送”,就是把源操作数传送到目的寄存器或RAM单元中,指令执行后一般源地址单元内容不变,属于“复制”而不是“剪切”;或者源操作数与目的地址单元内容互换(交换指令)。

数据传送指令共29条,可分为五类:

  1. 内部RAM或寄存器间的数据传送(16条)MOV

  2. 累加器A与外部RAM间的数据传送(4条)

  3. 累加器A与程序存储器间的数据传送(2条)

  4. 数据交换(5条)

  5. 堆栈操作(2条)

内部RAM或寄存器间数据传送关系图

在这里插入图片描述

1.内部RAM或寄存器间的数据传送(16条) MOV

指令格式举 例指令功能
MOV A,#dataMOV A,#25H将立即数25H送至A
MOV A,RnMOV A,R3将寄存器R3中的内容送至A
MOV A,directMOV A,45H将45H单元的内容送至A
MOV A,@RiMOV A,@R0将寄存器R0所指的内存单元内容送至寄存器A
MOV direct,#dataMOV direct,#22H将立即数22H送RAM区direct单元
MOV direct,AMOV 22H,A将A中的内容送至40H单元
MOV direct,RnMOV 23H,Rn将寄存器Rn中的内容送至23H单元
MOV direct,@RiMOV 24H,@Ri将Ri所指单元的内容送至24H单元
MOV direct,direct2MOV 30H,40H将40H单元的内容送至30H单元
MOV Rn,#dataMOV R6,#66H将8位立即数66H送至R6
MOV Rn,AMOV R7,A将A中的内容送至寄存器R7
MOV Rn,directMOV R4,60H将60H单元的内容送至寄存器R4
MOV @Ri,#dataMOV @R0,#25H将8位立即数25H送至R0所指的RAM单元中
MOV @Ri,AMOV @R1,A将A中的内容送至R1所指的RAM单元
MOV @Ri, directMOV @R0, 25H将25H单元的内容送至R1所指的RAM单元
MOV DPTR , #data16MOV DPTR , #2300H将16位立即数2300H送至数据指针寄存器
  • 注意事项:

    • 1.立即数是一个不带符号的8位常数,且立即数不能作目的操作数;

    • 2.direct表示的是8位直接地址,以此指出8051中128个RAM单元和128-255之间的特殊功能寄存器。但是要注意在128-235区有很多单元是空的写入空单元的数将被丢掉,从空单元读取的数无意义

    • 3.通用寄存器之间不允许直接传送;

    • 4.通用寄存器与寄存器间接寻址的RAM单元之间不能直接传送;

      错误的:
          MOV  Rn,Rn              
          MOV  @Ri, @Ri
          MOV  Rn, @Ri
          MOV  #data, A
      
    • 5.在指令格式中,立即数寻址和直接寻址的表示方式不同。

      MOV A,#40H   立即数40H送A 
      MOV A,40H   40H单元的内容送A 
      MOV 40H,#40H  将立即数40H送40H单元
      

2.累加器A与外部RAM间的数据传送(4条) MOVX

  • CPU与外部数据存储器或外部扩展的I/O口之间进行数据传送时,必须使用外部传送指令MOVX。
  • 外部数据传送必须通过累加器A,且只能采用寄存器间接寻址(用R0, R1和DPTR三个间接寻址的寄存器)方式完成。
汇编语言指令举例指令功能
MOVX A, @RiMOVX A, @R1将R1所指的外部存储器单元的内容送A
MOVX A, @DPTRMOVX @R0,A将A中的内容送至Ri所指的外部存储器单元
MOVX @Ri, AMOVX A,@DPTR将16位指针DPTR所指的外部存储器单元的内容送至A
MOVX @DPTR, AMOVX @DPTR,A将A中的内容送至DPTR所指的外部存储器单元
  • 例.下列指令执行完之后,累加器A和外部RAM 1234H单元内容分别是多少?
MOV		30H,#44H  		;(30H)=44H
MOV		R1,#30H    		;(R1)=30H
MOV		A,@R1     		;(A)=44H
MOV		DPTR,#1234H    	;(DPTR)=1234H
MOVX	@DPTR,A   		;(1234H)=(A)=44H

执行完上述指令之后,(A)=44H,(1234H)=44H
  • 注意:
    • 由于Ri是8位的寄存器,所以只能访问片外RAM的一页中的256个单元,页内偏移地址00H~0FFH放在Ri中,页地址先由P2口输出。
    • DPTR可以访问片外RAM的全部64KB的空间。

3.累加器A与程序存储器间的数据传送(2条)MOVC

  • MCS-51单片机的程序存储器内的数据是只读的,因此程序存储器的数据传送是单向的,并且只能读到累加器A中。这类指令在查表中经常用到,所以又称为查表指令。查表指令一共有2条,都属于基址加变址寻址
编语言指令机器码指令功能
MOVC A , @A+DPTR1001 0011将DPTR中的16位地址和A中的内容相加得新地址,将此地址单元中的内容送至A中
MOVC A , @A+PC1000 0011将PC和A中的内容相加,所得的值作为新的地址,将此地址的内容送至A中
  • 【例】将外ROM 1234H单元中的数据传送至内RAM的30H单元中。
解法:
     MOV DPTR,#1234H		;16位立即数1234H送至数据指针寄存器
     MOV A,#00H				;将立即数00H送至AMOVC A,@A+DPTR			;DPTR中的16位地址和A中的内容相加得新地址,将此地址单元中的内容送至AMOV 30H,A				;A中的数据传送至内RAM30H单元中

4.数据交换指令(5条)XCH XCHD SWAP

  • 1)半字节数据交换指令(2条)
汇编语言指令机器码指令功能
SWAP A1100 0100将A的高四位和低四位交换
XCHD A, @Ri1101 011iRi为R0或R1,将Ri所指单元的低4位与A的低4位互换,高4位不变

注:XCHD A, @Ri 指令对P标志位有影响。


  • 2)整字节交换指令(3条)
汇编语言指令机器码指令功能
XCH A,Rn1100 1rrrRn为R0~R7之一,将工作寄存器Rn的内容和A的内容交换
XCH A,direct1100 0101 direct将 direct单元内容和A的内容交换
XCH A,@Ri1100 011iRi为RO或R1,将Ri所指单元的内容和A的内容互换
  • 例1.A中为1110 0110,则执行SWAP A 后,A中为0110 1110。
  • 例2.已知(A)=12H、(R1)=30H、(30H)=34H,分析指令执行的结果。
    • XCHD A, RI
解:(A=14H、(30H)=32H,R1内容仍然保持不变。
  • 例3.已知(A)=12H、(R1)=30H、(30H)=34H,分析指令执行的结果。
    • XCH A. @ RI
解:(A=34H、(30H)=12H,R1内容保持不变。

5.堆栈操作指令(2条)PUSH POP

汇编语言指令机器码指令功能
PUSH direct1100 0000 directSP←(SP)+1 (SP)←(direct)
POP direct1101 0000 directdirect←((SP)) SP←(SP)-1
  • PUSH DPH:先将SP加1,再将数据指针高位DPH推入堆栈SP+1单元;
  • PUSH DPL:先将SP加1,再将数据指针低位DPL推入堆栈SP+1单元;
  • PUSH direct:先将SP加1,再将direct所指单元内容推入SP+1所指的堆栈单元;
  • POP direct:先将SP单元的内容弹出到 direct单元,再将SP减1;
  • POP DPH:先将栈顶SP的内容弹出到数据指针的高8位DPH,再将SP减1;
  • POP DPL:先将栈顶SP的内容弹出到数据指针的低8位DPL,再将SP减1。

  • 例.分析下面程序的执行结果,假设(30H)=55H,(40H)=AAH。
PUSH 30H
PUSH 40H
POP 30H
POP 40H

解:程序执行后(30H)=AAH,(40H)=55H

注意: 堆栈操作指令的操作数只能使用直接寻址,直接地址不能是寄存器名,因此应注意指令的书写格式。

  • 例如:
    • PUSH ACC ;(不能写成PUSH A)
    • POP 00H ; (不能写成POP R0)

2.算术运算指令

  • 算术运算指令主要完成加、减、乘、除四则运算,以及加1、减1、BCD码调(十进制调整)指令整等。
  • 加减运算指令的两个操作数中,目的操作数必须为累加器A;源操作数可以为Rn或@Ri(片内RAM)以及direct,或是#data,大多数都要影响到程序状态字PSW,乘除指令不影响AC标志位。

以下8条指令对PSW中的所有标志位均产生影响!!!

  1. 不带进位的加法指令(4条)
汇编语言指令举 例指令功能
ADD A , #dataADD A,#23H将立即数23H和A相加,结果送至A
ADD A, directADD A,40H将40H单元的内容和A相加,结果送至A
ADD A , RnADD A,R3将A的内容和R3的内容相加,结果送至A
ADD A , @RiADD A,@R0将A的内容和R0所指的片内RAM单元的内容相加,结果送至A

例.分析下面的程序段的功能。

MOV A,#85H
ADD A,#97H
MOV 50H,A
解:
      1000 0101		===>    85H
   +  1001 0111		===>    97H
  ---------------
    1 0001 1100      ===>    11EH

解析:指令的功能是将85H和97H相加,并把相加的结果传送到50H单元中,且相加后的进位标志Cy的为1
  • 加法指令影响PSW的进位标志Cy。如果最高位(D7)有进位,则Cy=1;否则Cy=0。
    • 例如,在85H+97H后最高位有进位,(Cy)=1。
  • 如果低4位有进位(即D3向D4进位),则辅助进位标志AC=1,否则AC=0。
  • 如果相加以后,D7、D6中只有一位有进位则溢出标志OV=1;若D7、D6中均有进位或均无进位,则溢出标志OV=0;
  • 若A中“1”的个数为偶数,则P=0,否则,P=1。

【例1】请分析执行如下程序段后A、Cy、AC、OV的结果。

1MOV A,#00110110B 
   ADD A,#00110101B
      
解:指令执行后 (A)=6BH、(Cy)=0(AC)=0(OV)=0
      
2MOV A,#11010001B 
   ADD A,#01011001B
      
解:指令执行后 (A)=2AH、(Cy)=1(AC)=0(OV)=0
      
3MOV A,#10010010B 
   ADD A,#11001001B
      
解:指令执行后 (A)=5BH、(Cy)=1(AC)=0(OV)=1
      
4MOV A,#0110011B 
   ADD A,#00110110B
      
解:指令执行后 (A)=9DH、(Cy)=0(AC)=0(OV)=1

  1. 带进位的加法指令(4条)
汇编语言指令举 例指令功能
ADDC A , #dataADDC A,#23HA←(A)+data+( Cy)
ADDC A, directADDC A,40HA←(A)+ (direct) +( Cy)
ADDC A , RnADDC A,R3A←(A)+(Rn) +( Cy)
ADDC A , @RiADDC A,@R0A←(A)+((Ri)) +( Cy)
  • 与ADD指令的唯一区别是:ADDC指令除了降至零中规定的两个操作数相加外,还要加上进位标志位Cy的值。此处的Cy的值是指令执行前的进位标志位的内容,不是相加后产生的Cy的值

【例2】已知当前(Cy)=1,分析下列指令执行后,A与PSW相关标志位的结果。

MOV A,#85H
ADDC A,#97H
      
解:(A)=1DH、(Cy)=1(AC)=0(OV)=1(P)=0      

【例3】编写程序,将内RAM 30H与50H为起始单元的单元2B无符号数相加,并将结果存放到30H为起始地址的区域中。设30H、50H是操作数的低字节。

解:
   MOV A,30H
   ADD A,50H
   MOV 30H,A
   MOV A,31H
   ADDC A,51H
   MOV 31H,A
   MOV A,#00H
   ADDC A,#00H
   MOV 32H,A   

【例4】将内RAM 20H单元、21H单元、22H单元中的三个无符号数相加,并将和存入R0(高位)与R1(低位)。

解:
    MOV	A,20H	;20H单元内容存入A
    ADD	A,21H	;21H单元的内容和A中单元内容(20H)相加
    MOV	R1,A	;将前两个数相加的低位存入R1
    MOV	A,#00H	;A赋值为0
    ADDC A,#00H	;将前两个数相加的进位存入A
    MOV	R0,A	;将前两个数相加的高位(进位)存入R0
      
    MOV	A,R1	;将前两个数相加的低位存入A
    ADD	A,22H	;前两个数相加的低位与第三个数相加
    MOV	R1,A	;三个数和的低位存入R1
    MOV	A,#00H	;A赋值为0
      
    ADDC A,R0	;第二次加法的进位与第一次加法的高位(R0中的数)相加
      
    MOV	R0,A	;高位和存入R0

  1. 带借位的减法指令(4条)
汇编语言指令指令功能举 例
SUBB A , #dataA←(A)-data- (Cy)SUBB A , #10H
SUBB A, directA←(A) - (direct) - (Cy)SUBB A, 50H
SUBB A , RnA←(A) - (Rn) - (Cy)SUBB A , R3
SUBB A , @RiA←(A) - ((Ri)) - (Cy)SUBB A , @R0
  • MCS-51指令系统中没有不带借位的减法,因此要实现不带借位的减法,需在执行SUBB指令前,应使用指令CLR C 对Cy清零。
  • 它对PSW中的所有标志位均产生影响

【例】.已知(Cy)=1,分析下面指令的执行结果。

MOV A,#79H
SUBB A,#56H
      
解:
    0111 1001
  - 0101 0110
----------------
    0010 0010
      
指令执行后,累加器A的内容是22H,(Cy)=0(AC)=0(OV)=0(P)=0      

  1. 十进制调整指令(1条)
汇编语言指令指令功能举 例
DA A将A的内容调整为正确的BCD码DA A
  • 十进制调整指令是一条专门用于对8421 BCD码加法结果进行调整的指令,它跟在加法指令ADD或ADDC后面,对BCD码数的和进行BCD码修正。
  • BCD码调整的原则:
    • ① 若累加器A的低4位大于9或(AC)=1,则(A)=(A)+06H;
    • ② 若累加器A的高4位大于9或(Cy)=1,则(A)=(A)+60H;
  • 它对PSW中除OV之外的的所有标志位均产生影响。
  • 另外,十进制调整指令不能对减法指令进行修正。BCD码减法必须采用BCD补码运算法则,变减法为补码加法(被减数+减数的补码,单字节减数的补码=9AH-减数),然后对其进行十进制调整来实现。

【例】试编写程序求68H和99H这两个数的BCD码之和。

解:
	MOV		A,#68H	;(A)=68H
	MOV		R0,#99H	;(R0)=99H
	ADD		A,R0		
	;未调整时 (A)=01H,(Cy)=1,(AC)=1
	DA		A 		
	;调整之后(A)=67H,(Cy)=1,结果为167,正确

  1. 加1指令(5条)
汇编语言指令指令功能举 例
INC AA←(A)+1INC A
INC directdirect←(direct)+1INC 30H
INC RnRn←(Rn) +1INC R4
INC @Ri(Ri)←((Ri))+1INC @R0
INC DPTRDPTR←(DPTR)+1INC DPTR
  • 它只对PSW中的P标志位产生影响。

【例】编写程序,将内RAM 30H为起始地址的3个无符号数相加,并将结果(假设结果小于100H)存放到40H单元中。

MOV A,#00H
MOV R0,#30H
ADD A,@R0
INC R0
ADDC A,@R0
INC R0
ADDC A,@R0
MOV 40H,A      

  1. 减1指令(4条)
汇编语言指令指令功能举 例
DEC AA←(A)-1DEC A
DEC directdirect←(direct) -1DEC 50H
DEC RnRn←(Rn) -1DEC R4
DEC @Ri(Ri)←((Ri)) -1DEC @R1
  • 它只对PSW中的P标志位产生影响。

【例】编程实现DPTR减1的运算。

解:由于减1指令中没有DPTR1的指令,因此需要将DPTR拆分为DPHDPL来进行操作。
	CLR	C		;将Cy清零
	MOV	A,DPL		;将数据指针的低8位送入A
	SUBB	A,#01H	;A的内容减1送入A
	MOV	DPL,A		;A的内容减1送入DPL
	MOV	A,DPH	;将数据指针的高8位送入A
	SUBB	A,#00H	;A的内容减0,再减去低位的借位送入A
	MOV	DPH,A	;A中得到的最终结果送入DPH

  1. 乘除指令(2条)
汇编语言指令机器码指令功能
MUL AB1010 0100(B)(A)←(A) (B)
DIV AB1000 0100(A)←(A)/(B) (B)←(A)mod(B)
  • 一条乘法指令只能完成2个8位无符号数相乘,乘数和被乘数分别放在A和B寄存器中,乘积的高8位放在B寄存器中、低8位放在累加器A中;
  • 一条除法指令只能完成2个8位无符号数相除,被除数和除数分别存放在A和B寄存器中,商存放在A中,余数存放在B中。

【例】分析下面指令的执行结果

MOV A,#36H

MOV B,#03H

MUL AB

解:
   0011 0110
 x 0000 0011
---------------
   0011 0110
 0 0110 110
---------------
 0 1010 0010 
 
结果:(A)=0A2H、(B)=00H、(Cy)=0(OV)=0(P)=1      

【例】分析下面指令执行结果

MOV A,#87H

MOV B,#0CH

DIV AB

解:(A)=0BH、(B)=03H、(Cy)=0(OV)=0(P)=1 

3.逻辑运算和移位指令

  • 常用的逻辑运算和移位类指令有: 逻辑与、逻辑或、逻辑异或、循环移位、清零、求反等指令,它们的操作数都是8位的。
  • 逻辑运算都是按位进行的。
  • 逻辑运算和移位指令中,以A为目的操作数的指令影响P标志位,带进位的循环移位指令影响Cy和P标志位,其余均不影响PSW各标志位。
  1. 逻辑与运算指令(6条)
汇编语言指令指令功能举 例
ANL A ,#dataA←(A) dataANL A ,#0F0H
ANL A , directA←(A) (direct)ANL A , 50H
ANL A , RnA←(A) (Rn)ANL A , R3
ANL A , @RiA←(A) ((Ri))ANL A , @R1
ANL direct ,Adirect←(A) (direct)ANL 40H ,A
ANL direct,#datadirect←(direct) (data)ANL 55H,#55H

注:逻辑与的规则为“见0为0,全1为1”。

  1. 逻辑或运算指令(6条)
汇编语言指令指令功能举 例
ORL A, #dataA←(A) dataORL A ,#0F0H
ORL A, directA←(A) (direct)ORL A , 50H
ORL A, RnA←(A) (Rn)ORL A , R3
ORL A, @RiA←(A) ((Ri))ORL A , @R1
ORL direct, Adirect←(A) (direct)ORL 40H ,A
ORL direct, #datadirect←(direct) (data)ORL 55H,#55H

注:逻辑或的规则为“见1为1,全0为0”。

  1. 逻辑异或运算指令(6条)
汇编语言指令指令功能举 例
XRL A, #dataA←(A) dataXRL A ,#0F0H
XRL A, directA←(A) (direct)XRL A , 50H
XRL A, RnA←(A) (Rn)XRL A , R3
XRL A, @RiA←(A) ((Ri))XRL A , @R1
XRL direct, Adirect←(A) (direct)XRL 40H ,A
XRL direct, #datadirect←(direct) (data)XRL 55H,#55H

注:逻辑异或的规则为“相同为0,相异为1”。

  1. 循环移位指令(4条)
  • MCS-51单片机的循环移位指令共有4条:
    • ①不带进位的循环左移指令RL;
    • ②不带进位的循环右移指令RR;
    • ③带进位的循环左移指令RLC;
    • ④带进位的循环右移指令RRC。
  • 它们都只能对累加器A进行移位。
  • 使用移位指令可以实现乘法或除法:
    • 左移一位相当于乘2;
    • 右移一位相当于除2。
汇编语言指令指令功能
RL A在这里插入图片描述
RR A在这里插入图片描述
RLC A在这里插入图片描述
RRC A在这里插入图片描述
  1. 累加器清零与取反指令(2条)
汇编语言指令指令功能
CLR AA←0
CPL AA←(A)
  • 利用取反,可以进行求补操作,即对要求补的数先取反再加 1。

4.控制转移指令

  • 计算机在运行的过程中,一般通过程序计数器PC的自动加1实现顺序执行,有时候对于较复杂的操作,需要通过强迫改变PC值的方法来进行程序的分支转移,这就需要用到控制转移指令。
  • 控制转移指令的功能——通过改变程序计数器PC中的内容,控制程序执行的流程,实现程序分支转向。
  • MCS-51单片机提供了17条控制转移指令。

  1. 无条件转移指令(4条)
汇编语言指令机器码指令功能
LJMP addr160000 0010 addr15~8 addr7~0PC←addr15~0
AJMP addr11A10A9A80 0001 A7~A0PC←(PC)+2, PC 10~0←addr11
SJMP rel1000 0000 relPC←(PC)+rel
JMP @A+DPTR0111 0011PC←(DPTR)+(A)

1)长转移指令(LJMP addr16)

  • 长转移指令提供了16位的目标转移地址,其功能是把指令码中的16位转移目标地址送入PC,因此这条指令可以跳转到64KB ROM的任意位置。
  • 为了方便,程序中addr16通常采用符号地址表示,汇编时再被汇编成16位二进制地址,所以该指令的使用格式通常为:
    • LJMP 标号

2)绝对转移指令(AJMP addr11)

  • 这条指令可以在该指令的下一条指令的同一个2KB区域(211)内跳转。PC15~PC11用于把64KB的ROM划分为32个区域,相当于32个页(每页2KB,由PC10~PC0确定)。

  • 指令执行时,用指令码中的11位地址替换当前PC值(AJMP的下一条指令的地址)的低11位,当前PC值的高5位不变。

  • 在实际程序设计中,addr11也常用标号代替,程序汇编时再被自动汇编成对应的11位地址。该指令的使用格式通常为:

    • AJMP 标号

3)相对(短)转移指令(SJMP rel)

  • 执行本指令时,转移的目标地址为(PC)=(PC)+rel,rel是一个用补码表示的8位带符号二进制数,范围为-128~+127,负数表示向前(地址变小方向)转移,正数表示向后(地址变大方向)转移。
  • 程序中,rel常用符号地址表示,因此,该指令的常用格式为:
    • SJMP 标号
  • 机器汇编时由汇编程序自动计算出rel的值,手工汇编时,需要人工计算rel的值:
    • rel=目标标号的地址-当前的PC值
  • 在编程中,经常使用短转移指令SJMP和绝对转移指令AJMP,以便生成浮动代码。
  • 另外,MCS-51单片机无专用的停机指令,若要求动态停机(不想单片机继续往下执行)可用SJMP指令,常用方法有以下两种:
    • 方法1:HERE :SJMP HERE
    • 方法2:SJMP $

4)间接(散)转移指令(JMP @A+DPTR)

  • 功能:把累加器A中的8位无符号数与数据指针DPTR中的16位数相加,其结果送入PC,作为转移的目标地址,利用这条指令能实现程序的散转。
  • 散转指令可以在不需要判断的情况下实现程序的多分支转移。
  • 例2. 分析下面程序的执行过程。
	MOV	DPTR,#TAB	;TAB所代表的地址送入DPTR
	MOV	A,R1		;R1中取数送入A
	MOV	B,#2		;B赋值为2
	MUL	AB		;A中的数(即原来R1中的数)乘以2
	JMP	@A+DPTR	;跳转
TAB:	SJMP	S0		;跳转表格,S0处理程序
	SJMP	S1		;S1处理程序
	SJMP	S2		;S2处理程序

  1. 条件转移指令(8条)
  • 条件转移指令的功能:在规定的条件满足时进行程序转移,否则程序往下顺序执行。

  • MCS-51单片机中,条件转移指令有:

    • 累加器A判零转移指令(JNZ/JZ)
    • 比较不相等转移指令(CJNE)
    • 减1不为0转移指令(DJNZ)(循环控制指令)

1)累加器A判零转移指令(2条)

汇编语言指令机器码指令功能
JZ rel0110 0000 rel若(A)=0,则转移(PC)←(PC)+rel; 若(A)≠0,则顺序执行
JNZ rel0111 0000 rel若(A)≠0,则(PC)←(PC)+rel; 若(A) =0,则顺序执行

2)比较转移指令(4条)

汇编语言指令机器码指令功能
CJNE A, direct, rel10110101 direct rel若(A)=(direct),则顺序执行; 若(A)>(direct),则(PC)←(PC)+rel,Cy= 0; 若(A) <(direct),则(PC)←(PC)+rel,Cy= 1

3)减1不为0转移指令(循环控制指令)(2条)

汇编语言指令机器码指令功能
DJNZ Rn, rel1101 1rrr rel(Rn)←(Rn)-1, 若(Rn)≠0则 (PC) ←(PC)+rel 若(Rn)=0则顺序执行
  • 例3. 编程计算1+2+3+……+10的值。
	解:本题目为自然数依次相加,从1加到10,故可以用循环指令来控制循环次数。
	程序如下:
	MOV	R0,#10		;设置循环次数
	CLR	A		;累加器清零
LOOP:ADD   A,R0		;循环体
	DJNZ	R0,LOOP	;控制循环次数
	SJMP	$		;结束
  1. 子程序调用与返回指令(4条)
  • 在程序运行时,可以通过调用指令来调用并执行子程序;子程序执行完后,再用返回指令从子程序返回到主程序。
  • 为了实现子程序的完整调用,子程序调用指令和返回指令必须成对出现
  • 子程序可以嵌套,即在一个子程序执行过程中可以调用另外的子程序,形成子程序的嵌套。子程序嵌套有利于模块化程序设计。

在这里插入图片描述

汇编语言指令机器码指令功能
LCALL addr160001 0010 addr15~8 addr7~0(PC)←(PC)+3, SP←(SP)+1,(SP)←(PC)7~0; SP←(SP)+1,(SP)←(PC)15~8, (PC)15~0←addr16

1)长调用指令 LCALL

  • 长调用指令,用于调用存放在 64KB 空间任意地方的子程序,本指令不影响 PSW 的各标志位。
    • 使用格式为:LCALL 标号(标号即为子程序名)

2)短调用指令 ACALL

  • 该指令的调用范围为 2KB,执行该指令时共完成 2 项操作:
    • ① 断点保护,即通过自动入栈,把断点地址((PC)+2 的值)保存起来;
    • ② 构造目的地址,即用 addr11 代替当前 PC的低 11 位,而 PC 的高 5 位不变。
  • 子程序必须存放在该指令的下一条指令的第一个字节开始 的 2KB 范围内,即同一页内。
    • 该指令的使用格式为:ACALL 标号(标号即为子程序名)

3)子程序返回指令 RET

  • 该指令与子程序调用指令成对出现,其功能是从堆栈中取出断点地址,送入 PC,使主程序从断点(调用指令的下一条指令)处继续执行。

4)中断返回指令 RETI

  • 中断服务程序是一种特殊的子程序,它是在计算机响应中断时,由硬件完成调用而进入相应的中断服务程序。
  • RETI 指令与 RET 指令的区别在于 RETI 在从中断服务程序返回时,还要对相应优先级的中断触发器清 0。无论是 RET 还是 RETI 都是子程序执行的最后一条指令。
  1. 空操作指令
汇编语言指令机器码指令功能指令字节数机器周期数
NOP0000 0000PC←PC+1,空操作11
  • 空操作指令不进行任何操作,但要占一个字节的空间,执行时要占用一个机器周期,多用于延时等待或在抗干扰设计中做指令冗余,以提高软件的可靠性。

5.位操作指令

  • 位操作指令操作对象是某个可寻址的位,由于位的取值只能是0或1,故位操作指令又称为布尔变量操作指令
  • 位操作指令操作的对象——片内RAM的128个可寻址的位和SFR中11个可位寻址的特殊功能寄存器中的82个可寻址位。
  • 位操作指令以进位标志Cy作为位累加器(C),可以实现布尔变量的传送、运算和控制转移等功能。
  1. 位数据传送指令(2 条)
  • 位数据传送可以在可寻址位与位累加器 C 之间进行,以 C 做中介可以实现两个位之间的数据传送
汇编语言指令指令功能举 例
MOV C ,bitC← (bit)MOV C ,20H MOV C ,P0.2
MOV bit , Cbit ← ©MOV 20H,C MOV P0.2,C
  1. 位状态控制指令(4 条)
  • 位状态控制主要是对位置位或复位
汇编语言指令指令功能举 例
CLR CC ← 0CLR C
CLR bitbit ← 0CLR 30H CLR EA
SETB CC ← 1SETB C
SETB bitbit ← 1SETB 30H SETB EA
  1. 位逻辑操作指令(6 条)
  • 位逻辑操作有位与、位或、位异或、位取反等,除了位取反指令 CPL bit 外,其余指令均以位累加器 C 为目的操作数,执行结果存入 C,原位的内容不发生变化
汇编语言指令指令功能机器周期数
ANL C ,bitC ←© ∧ (bit)ANL C ,30H
ANL C ,/bitC ←© ∧ (bit)ANL C ,/30H
ORL C,bitC ←© ∨ (bit)ORL C,30H
ORL C ,/bitC ←© ∨ (bit)ORL C ,/30H
CPL CC ← ©CPL C
CPL bit(bit) ← (bit)CPL TR0

例:用软件实现下图所示的P1.0 ~ P1.3间的逻辑运算。

MOV  C,P1.1
ORL  C,P1.2
ANL  C,P1.0
MOV  P1.3,C 

在这里插入图片描述

  • (P1.1 ≥ P1.2) & P1.0

例3.25 设x, y, z为不同的位地址,编程实现(z)=(x) ⊕ (y)

解 析 : M O V C , y ; ( C ) = ( y ) A N L C , / x ; ( C ) = ( y ) ∧ ( x ˉ ) M O V Z , C ; ( z ) = ( C ) = ( y ) ∧ ( x ˉ ) M O V C , x ; ( C ) = ( x ) A N L C , / y ; ( C ) = ( x ) ∧ ( y ˉ ) O R L C , Z ; ( C ) = ( y ) ∧ ( x ˉ ) + ( x ) ∧ ( y ˉ ) M O V Z , C ; ( Z ) = ( y ) ∧ ( x ˉ ) + ( x ) ∧ ( y ˉ ) = ( x ) ⊕ ( y ) \begin{aligned} 解析: &MOV \quad C,y \quad ;(C)=(y) \\ &ANL \quad C,/x \quad ;(C)=(y) ∧ ( \bar{x} ) \\ &MOV \quad Z,C \quad ;(z)=(C)=(y)∧ (\bar{x} )\\ &MOV \quad C,x \quad ;(C)=(x) \\ &ANL \quad C,/y \quad ;(C)=(x) ∧ ( \bar{y} )\\ &ORL \quad C,Z \quad ;(C)=(y) ∧ ( \bar{x} )+(x)∧ (\bar{y} ) \\ &MOV \quad Z,C \quad ;(Z)=(y) ∧ ( \bar{x} )+(x)∧ (\bar{y} )=(x) ⊕ (y)\\ \end{aligned} MOVC,y;(C)=(y)ANLC,/x;(C)=(y)(xˉ)MOVZ,C;(z)=(C)=(y)(xˉ)MOVC,x;(C)=(x)ANLC,/y;(C)=(x)(yˉ)ORLC,Z;(C)=(y)(xˉ)+(x)(yˉ)MOVZ,C;(Z)=(y)(xˉ)+(x)(yˉ)=(x)(y)

  1. 位条件(控制)转移指令(5 条)
  • 位条件(控制)转移指令和前面介绍过的条件转移指令类似,只不过是以位的状态作为 程序转移的判断条件,可以使程序设计更加方便、灵活。
汇编语言指令指令功能举 例
JC rel若©=1,则转移(PC)←(PC)+rel ; 否则顺序执行JC NEXT
JNC rel若©=0,则转移(PC)←(PC)+rel; 否则顺序执行JNC NEXT
JB bit , rel若(bit)=1,则转移(PC)←(PC)+rel; 否则顺序执行JB F0,NEXT
JNB bit , rel若(bit)=0,则转移(PC)←(PC)+rel; 否则顺序执行JNB F0,NEXT
JBC bit , rel若(bit)=1,则转移(PC)←(PC)+rel,且(bit )←0; 否则顺序执行JBC F0,NEXT

例3.26 求出内RAM30H单元中的数据含1的个数,并将结果存入31H单元。

解:
	CLR	C		;C清零
	MOV	R2,#8		;设置循环次数
	MOV	R1,#00		;计数单元清零
	MOV	A,30H		;30H单元内容读入A
LOOP:RRC	A	       	; (ACC.0)循环移入Cy中
	JNC	NEXT		;Cy中不为1则转至NEXT
	INC	R1		;若Cy为1,R1内容加1
NEXT:DJNZ	R2,LOOP	; 8不够则继续执行移位
	MOV	31H,R1	;将计数结果送入31H单元
	SJMP	$		;停机(原地踏步)
	END			;结束
posted @ 2022-02-07 21:18  subeiLY  阅读(1990)  评论(0编辑  收藏  举报