MCS-51单片机指令系统与编程

更新时间:2023-03-15 13:51:02 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第二章 MCS—51单片机指令系统与编程

单片机系统的设计包括硬件设计与软件编程两部分。在硬件电路设计合理的的条件下,

还要在编制程序正确的基础上,单片机才能按照设计者的要求来完成各种工作。本章在第一章MCS—51单片机硬件的结构基础上,主要介绍MCS—51指令系统与编程。

第一节 指令系统概述

一、 指令概念

指令是指挥计算机工作的命令,是计算机软件的基本单元。指令有两种表达形式。 1.机器码指令

用二进制代码(或十六进制数)表示的指令称为机器码指令或目标代码指令。这种形式的指令能够直接被计算机硬件识别执行,但不便于记忆。

例如指令MOV A, #00H 执行的操作是将立即数00H送到累加器A中,它的机器码指令为74H 00H。

2.汇编语言指令

为了便于记忆,利于程序的编写和阅读,用助记符来表示每一条指令的功能,称作汇编语言指令。该指令不能被计算机硬件直接识别和执行,必须通过汇编把它翻译成机器码指令才能被计算机执行。如上面的指令MOV A, #00H即为汇编语言指令。

计算机的所有指令被称为计算机的指令系统,对于不同型号的计算机,其指令系统也是不同的,在很大度上决定了其相应的使用功能。 二、 指令格式

汇编语言的指令格式由以下几部分组成:

[标号]:操作码助记符 [目的操作数],[源操作数];[注释]

标号:是该指令所在的符号地址,由字母打头的字母数字串组成,可以根据需要设置。例如;

CD76 QB4 WAB DB745 为允许格式 46A 896A +BC5 -BCE05C 为不允许格式 操作码助记符:规定了指令操作功能,它是由助记符表示的字符串。

操作数:指参加操作的对象,此为指令的核心。对于操作数段的组成有的指令可以没有,也可以只有一个操作数,如:

CPL A ;只有一个操作数 RETI ; 没有操作数。

注释:为了用户阅读程序方便,在程序后加注的中文或者英文的说明。

当用机器语言表示的指令格式以8位二进制数(或字节)为基数时,可分为单字节、 双字节和三字节指令,其相应格式如下: 单字节: 操作码 数据或寻址方式 双字节: 操作码 三字节: 操作码 数据或寻址方式 数据或寻址方式 三 、符号说明 MCS—51单片机的111条指令按照功能可分成如下五大类: (1)数据传送类指令29条

1

(2)算术传送类指令24条

(3)位操作类指令12条 (4)逻辑运算类指令24条 (5)控制转移类指令22条

在MCS—51指令系统中,对常用符号进行说明如下: (1)#data——8位立即数 (2)#data16——16位立即数

(3)Rn——工作寄存器,R0~R7,n为0~7。 (4)Ri——工作寄存器,0或1,i=0或1。

(5)@Ri——寄存器Ri间接寻址8位存储单元00H~FFH

(6)direct——8位直接寻址,可以是特殊功能寄存器SFR的80H~FFH或内部存储单元

00H~7FH。

(7)addr11——11位目的地址。用于AJMP和ACALL指令,均在2KB地址内转移或调用。 (8)addr16——16位目的地址。用于LJMP和LCALL指令,可在64KB地址内转移或调用。

(9)rel——带符号的8位偏移地址,主要应用于所有的条件转移指令和SJMP。其范围是相对于下一条指令的第一字节地址-128~+127字节。

(10)bit——位地址。片内RAM中的可寻址位和专用寄存器中的可寻址位。 (11)DPTR——数据指针,可用于16位的地址寄存器。 (12)@——间接寄存器或者是基址寄存器的前缀。

如:@DPTR,@Ri,@A+PC,@A+DPTR

(A)——累加器ACC。

(14)B——通用寄存器,常用于乘法MUL和除法DIV的指令。 (15)Cy——进位标志位或者布尔处理器中的累加器。

第二节 寻址方式

计算机传送数据,执行算术操作,逻辑操作等等都要涉及到操作数。一条指令的运行,

先从操作数所在地址寻找到本指令有关的操作数,这就是寻址。计算机的指令系统各不相同,其相应的寻址方式也不尽相同。MCS—51系列单片机的指令系统有立即寻址,寄存器寻址,间接寻址,直接寻址,变址寻址,相对寻址,位寻址等七种寻址方式。 一、 立即寻址

立即寻址是指操作数就跟在操作码后面,立即参与指令所规定的操作,该操作数称为立即数。为了方便辨识,在它的前面加#号。

例如: MOV A,#20H; 将立即数20H传送到A中,如图2—1所示: 立即数 20H

A

图2-1 MOV A,#20H 指令示意图

二 、直接寻址

直接给出操作数所在的存储器地址,供寻址取数或存放的寻址方式称为直接寻址。在MCS—51系列单片机中,可访问三种地址空间:

(1) 特殊功能寄存器SFR:直接寻址是唯一的访问形式; (2) 内部数据RAM128个字节单元;

2

(3) 221个位地址空间。

例1: MOV A,70H; 把70单元内容送入累加器A中,如图2—2所示。 直接地址 70H 70H

A

图2-2 MOV A,70H 指令执行图

三、寄存器寻址

寄存器寻址是指定某一可寻址的寄存器的内容为操作数,对选定的8个工作寄存器R7~R0、累加器ACC、通用寄存器B、数据指针DPTR和Cy(布尔处理机的累加器,也编址为一个寄存器)中的数进行操作寻址的方式。一般来说,对于四个工作寄存器组的编码如下:

第0组 00H~07H 第2组 10H~17H

第1组 08H~0FH 第3组 18H~1FH

例2: INC A ;将寄存器A中的内容加1送回累加器A。

ADD A,R2 ;将工作寄存器R2中的内容取出,与累加器A中的内容相加,

其和送回累加器A。

MOV R3,A ;将累加器A中的内容传送到工作寄存器R3。 四、 间接寻址

间接寻址又称为寄存器间址,是将指定寄存器的内容作为该操作数的地址,再从该地址找到操作数的寻址方式。其实,寄存器寻址真正定义是可访问数据存储器的某一单元。在MCS—51单片机中可用来间接寻址的寄存器有:工作寄存器区的R0、R1,堆栈指针SP和16位的数据指针DPTR,在使用时为了容易辨识,在寄存器前面加@来表示。通常用间接地址寄存器的情况如下:

(1)如果访问片内RAM或片外低256B(00H~FFH)空间时,可以用R0或R1作为间址寄存器。

(2)如果访问片外64KB RAM空间时,可以用DPTR作为间址寄存器。 (3)如果执行PUSH或POP的指令时,可以用SP作为间址寄存器。

例3: MOV A,@R0 ;将R0的内容作为地址的存储单元中的内容传送至累加器A

中,如图2—3所示。

RO A(运行前50H) 60H内RAM 60H

A 7EH (运行后)7EH

图2-3 MOV A,@R0指令执行图

MOVX @DPTR, A ;将累加器A中的内容传送到外RAM DPTR所示的存储

单元中。

五 、变址寻址

该寻址方式用于访问程序存储器。它只能用于读取,不能存放,它主要应用于查表性质

的访问。

3

变址寻址的概念是将指令中指定的变址寄存器的内容加上基址寄存器的内容形成操作数地址的寻址方式。在该寻址方式中,以程序计数器PC或数据指针DPTR作为基址寄存器,用累加器A作为变址寄存器。 例4: MOVC A,@A+DPTR

把累加器A的内容与DPTR内容相加得到一个新地址,并通过该地址得到的操作数送入累加器A中,如图2—4所示。

DPTR ROM 2000H + 2050H 7EH A(运行前) 50H

A(运行后) 7EH

图2-4 MOVC A,@A+DPTR 指令执行图 MOV A,@A+PC

A为偏移量寄存器,PC为变址寄存器,A中内容为无符号数和PC相加,得到新的操作数地址,并通过该地址所得操作数送入累加器A中。 六、相对寻址

相对寻址是将给定的相对偏移量rel与当前的PC值相加所得到真正的程序转移地址。

它与变址方式不同,相对偏移rel是一个带符号的八位二进制数,必须用补码形式表示其范围-128~+127。该寻址方式常用于相对跳转指令。

例5:SJMP 08H

该指令是相对于当前PC值进行偏移量为08H的短跳转,如图2—5所示。

假设该指令存放于3000H起起始的单元,由于SJMP为双字节指令,故PC当前值为3000H+2=3002H,在加上偏移量08H,得到转移的目标地址为3002+08H=300AH,所以执行完该条指令后,程序就跳转到300AH了。

JC 80H

该指令为若C=0时,则PC值不变,若C=1时,则将现行的PC为基地址加上80H得到转向地址。如果指令存放在1005H,与JC为双字节指令,所以PC当前值为1005H+2=1007H,在加上偏移量-80H(这里80H必须以补码形式给出0,执行完该指令后,程序就此转到0F87H。如图2—5所示。 ROM 3000H 3001H rel=08(偏移量) PC=3002H(当前值) 3002H ?? 300AH 300AH转移目标地

+ = 4

图 2-5 SJMP 08H 指令执行图

七 、位寻址

位寻址是对片内数据RAM中的128位和特殊功能寄存器的93位进行操作。该寻址方式同直接寻址方式的形式和执行过程基本相同,但是参与操作的数据是1位不是8位。

例6:MOV 20H, A ;将累加器A中内容送到内RAM20H单元中。

MOV 20H,C ;将进位位Cy内容送到位地址20H指示的位中。 MCS—51型单片机的寻址方式与作用域的关系示于表2—1:

表2-1 寻址方式与作用域

序号 1 2 3 4 寻址方式 立即寻址 直接寻址 寄存器寻址 间接寻址 所用变量 所用空间 程序存储器 片内RAM低128B和特殊功能寄存器SFR R0~R7,A,B,CY,所涉及寄存器 DPTR @R0、@R1、SP 片内RAM @R0、@R1、@DPTR 片外RAM 5 6 7 变址寻址 相对寻址 位寻址 DPTR+A PC+A PC+rel (-128~+127) 片内RAM的20H~2FHB地址中的所有位和特殊功能寄存器SFR中字节地址能被8整除单元的位

程序存储器 程序存储器 第三节 MCS—51指令系统

MCS—51型单片机的指令系统共有111条指令。如果按指令字节长度分,有单字节指令49条,双字节指令47条,三字节指令15条。若按指令执行的时间分,可分为单机器周期指令64条,双机器周期指令条,伪机器周期指令2条。另外按指令的功能分为五类,可分为数据传送类有29条,算术指令24条,逻辑指令24条,转移指令22条,布尔指令12条。本节中将着重讲解这五类指令的功能。 一 传送指令

传送指令是MCS—51型单片机指令系统中数量最多使用最多的一类指令,它主要用于数据的保存和交换等场合。若按其操作方式又可以把它们分为三种:数据传送、数据交换和栈操作。数据传送操作又可分为内部数据存储器各部分之间及其与累加器A之间的数据传送;程序存储器送数到累加器A的传送操作,这三类操作码的助计符用MOV、MOVX、MOC表示。

1 、片内RAM之间的数据传送指令 格式: MOV 〈目的字节〉,〈源字节〉 功能:传送字节变量

说明:把源字节的内容传给目的字节,而源字节的内容不变,也不影响标志位。但当执

5

行结果改变累加器A的值时,会使奇偶标志变化。 (1) 如果目的字节是累加器A,有四条传送指令。 MOV A,Rn ;A←Rn

MOV A, derect ;A←(derect) MOV A ,#data ;A←#data

MOV A,@Ri ;A←(Ri)

例7:MOV A,R0 ;把寄存器R0中的数据传给A,即A←R0。

MOV A,20H ;把直接地址20H存储单元中的数据传给A,即A←(20H)。 MOV A,#20H ;把立即数20H传给A,即A←20H

MOV A,@R0 ;以R0中的数为地址的存储单元中的内容传送给A,

即A←(R0)

(2) 如果目的字节是Rn,则有三条传送指令

MOV Rn,#data ;Rn←data。 MOV Rn,A ;Rn←A

MOV Rn,direct ;Rn←direct

例8: MOV R6,#60H ;把立即数60H传给R6即R6←60H

MOV R0,A ;把A的内容传送给R0,即R0←A

MOV R2,40H ;把40H单元的内容传给R2,即R2←(40H)

(3) 如果目的字节是直接地址,则有5条指令。 MOV direct ,#data ;(direct)←data MOV direct ,A ;(direct)←A

MOV direct , Rn ;(direct)←Rn

MOV direct, direct 1 ;(direct) ←(direct1) MOV direct, @Ri ;(direct)←(Ri)

例9:MOV 3FH,#3FH ;把立即数3FH传送内RAM3FH单元。

MOV 3FH,A ;把A中的内容传送3FH中。

MOV 3FH,R0 ;把工作寄存器R0中的内容传送3FH中。

MOV 3FH,3EH ;将内部RAM中3EH单元的内容传送内RAM 3FH单元中。 MOV 3FH,@R0 ;把以R0中的数为地址的存储单元的内容送入3FH中。 (4) 目的字节是寄存器间接地址,则有三条信号指令。 MOV @Ri,#data ;(Ri)←data MOV @Ri,A ;(Ri)←A

MOV @Ri,direct ;(Ri)←(direct); 例10: 设内RAM(30H)=40H,(40H)=20H,当P1口为输入口,输入数据为CDH,试分析一下程序运行的结果。

MOV R0,#30H ;R0=30H MOV A,@R0 ;A=(30H)=40H MOV R1,A ;R1=40H

MOV B,@R1 ;B=(40H)=20H MOV @R1,P1 ;(R1)=(40H)=CDH MOV P2,P1 ;P2=P1=CDH

执行程序结果:R0=30H,A=R1=40H,B=20H,(40H)=CDH,P2=CDH。 例11: 假设内RAM中(20H)=50H,试分析以下程序运行的结果。 MOV 60H,#20H ;60H)=20H

6

MOV R0,#60H ;R0=60H

MOV A,@R0 ;A=(R0)=(60H)=20H MOV R1,A ;R1=A=20H

MOV 40H,@R1 ;(40H)=(R1)=(20H)=50H 2、16位数据传送指令

格式: MOV DPTR,#data16 功能:把16位数据送入DPTR。

说明:数据高8位送入DPH中,低8位送入DPL中。用作16位间址,当用MOVX指令时,则一定用外RAM地址。 3、 片外RAM传送指令

片外RAM传送指令用于CPU与外部数据存储之间的数据传送。对外部数据存储的访问都要采用间接寻址方式。在这里访问片外RAM用MOVX指令。该指令主要用于CPU与外部数据存储器间的数据传送。MOVX类指令共有四条。两条通过工作寄存器间址R0~R1对RAM进行操作,寻址范围256个字节(00H~FFH)。另二条通过数据指针间址(DPTR)对RAM进行操作,寻址范围为64KB(0000H~FFFFH)。

格式: MOVX 〈目的字节〉,〈源字节〉。

功能:外部数据传送

MOVX A,@DPTR ; A←(DPTR) MOVX A,@Ri ; A←(Ri) MOVX @DPTR,A ; (DPTR)←A MOVX @Ri,A ; (Ri)←A

上式中,前两条指令为外部数据存储器读指令,后两条指令为外部数据存储器写指令。这四条指令共同特点都要经过累加器A,外RAM的低8位地址均由P0传送,高8位地址均由P2传送,其中8位数据也需P0传送。

例12:把外部RAM 2000H单元的内容读入累加器A中,设RAM(2000H)=64H。

MOV DPTR,#2000H ;DPTR←2000H

MOVX A,@DPTR ;A←(DPTR),A=(2000H)=64H. 例 13:把外部RAM 2000H单元的数读出,写到外部RAM 2010H单元中。 MOV P2,#20H ;输出高8位地址

MOV R0,#00H ;读出单元低8位间接地址 MOV A,@R0 ;读外RAM2000H单元的数据; MOV R1,#10H ;写入单元低8位间接地址; MOVX @R1,A ;写入外RAM2010H单元 4、查表指令

MCS-51单片机的程序存储器除了存放程序外,还可存放一些常数,被称为表格。在单片机指令系统提供了两条访问程序存储器的指令,称为查表指令,该指令也就是程序存储器向累加器A传送指令。

格式: MOVC A,@A+PC ; PC←(PC)+1

A←(A)+PC

MOVC A,@A+DPTR ;A (A+(DPTR)

功能:把累加器A中内容加上基址寄存器(PC,DPTR)内容,求得程序存储器某单元地址,再将该单元内容送到累加器A中。

说明:(1)前一条指令由PC作为基址寄存器,它虽然提供16位地址,但其基址值是固定的,A+PC中的PC是程序计数器的当前内容(查表指令的地址加1),所以它的查表范

7

围是查表指令后256B的地址空间。

(2) 后一条指令采用DPTR作为基址寄存器,它的寻址范围为整个程序存储器的64KB空间,所以表格可以放在程序存储器的任何位置。缺点是若DPTR已有它用,在上式表首地址之前必须保护现场,执行完查表后再执行恢复。

例14: 若在ROM 2010H单元开始已存放有0~9的平方值,根据累加器A中的值0~9来查找对应的平方值。

MOV DPTR,#2010H

MOVC A,@A+DPTR ;A+DPTR的值就是所查平方值存放的地址。

当采用PC作为基址寄存器,由于表格地址空间分配受到限制,在编程时还需进行偏移量的计算,其公式为: DIS = 表首地址—(该指令所在地址+1) 5、堆栈操作指令

堆栈操作指令共2条,分别用于保存及恢复现场。压栈指令用于保存某片内RAM单元(低128字节)或某专用寄存器的内容,出栈指令用于恢复某片内RAM单元(低128字节)或某专用寄存器的内容。

格式: PUSH direct; ??SP?SP?1?(SP)?(direct)

POP direct;??(direct)?(SP)?SP?SP?1

功能:(1)PUSH称为压栈指令,将指定的直接寻址单元的内容压入堆栈。先将堆栈指针SP的内容+1,指向栈顶的一个单元,然后把指令指定的直接寻址单元内容送入该单元。 (2)POP称为出栈指令,它是将当前栈指针SP所指示的单元内容弹出到指定的内RAM单元中,然后再将SP减1。

以上这两条指令均为双字节指令,并且PUSH和POP是两种传送指令,具有程序执行迅捷,书写简练的优点,在编写程序时一定要遵循“后进先出”的原则。

例15: PUSH A ;保护A中的内容

PUSH PSW ;保护标志寄存器内容

POP PSW ;恢复标志寄存器内容

POP A ;恢复A中内容 上述程序执行完毕后,A和PSW寄存器中的内容得到正确的恢复。

例16: 假设SP=32H,内RAM的30H~32H单元的内容分别为20H,23H,01H,执行下列指令后DPTR,SP应为多少? 解: POP DPH ;(SP)=(32H)=01H→DPH,SP-1→SP,SP=31H

POP DPL ;(SP)=(31H)=23H→DPL,SP-1→SP,SP=30H

例17: 当SP=06H,DPTR的内容为1234H,求执行指令的结果是什么? 解:PUSH DPH ;SP←SP+1,SP=07H,(SP)←(DPH), (SP)=(07H)=12H

PUSH DPL ;SP←SP+1,SP=08H,(SP)←(DPL),

(SP)=(08H)=34H 结果为:(07H)=12H,(08H)=34H,SP=08H,DPTR=1234H

执行程序后:DPTR=0123H,SP=30H

6、交换指令

交换指令是将操作数自源地地址送到目的地。该指令共有五条,它在数据传送任务上更

8

为出色而且不易丢失信息。

(1) 字节交换指令

格式: XCH A,Rn ;A Rn

XCH A,@Ri ;A (Ri) XCH A,direct ;A (direct) 功能:将A的内容与源字节中的内容互换。 例18: 设(R0)=20H,(A)=3FH,(20H)=74H

XCH A,@R0 ; (A)=74H,(20H)=3FH

执行程序后:实现了累加器A和内部数据RAM中的20H单元内容互换。

(2) 半字节交换指令

格式: XCHD A,@Ri ; A3~0 (Ri)3~0,高四位不变。

功能:将累加器A中的内容的低四位与Ri所指的片内RAM单元中的低四位互换,但 它们的高四位均不变。

(3) 累加器高低四位互换指令

格式: SWAP A ;A7~4 A3~0 功能:把累加器A中的内容的高、低四位互相交换。

例19: 如果要使内RAM 30H单元与50H单元中的内容互换,该怎样编制程序。 解法一: 用交换换类指令。

XCH A,30H ;A ←(30H) XCH A,50H ;A ←(50H) XCH A,30H ;A ←(30H) 解法二:用栈操作指令。 PUSH 30H

MOV 30H,50H POP 50H 解法三:用传送指令。 MOV A,30H MOV 30H,50H MOV 50H,A 7、数据的传送指令汇总一览表

9

表2—2 MCS—51型单片机数据传送类指令 类 型 MOV A, 助记符 Rn direct @Ri #data 片内 RAM 传送 指令 MOV direct1, MOV Rn, A direct #data A Rn direct2 @Ri #data MOV @Ri, A direct #data MOV DPTR,#data16 片外 RAM 传送 指令 ROM 传送 指令 MOVC A,@A+DPTR XCH A,Rn 交换 指令 XCH A,@Ri XCH A,direct XCHD A,@Ri SWAP A PUSH direct 堆栈 指令 POP direct A←(A+DPTR) A Rn A (Ri) A (direct) A3~0 (Ri)3~0 A3~0 A7~4 SP←SP+1 (SP)←(direct) (direct) ←(SP) SP ←SP-1 D0 direct 2 2 93 11001rrr 1100011i C5 direct 1101011i C4 C0 direct 1 1 1 2 1 1 2 2 1 1 1 1 1 2 MOVX A,@Ri MOVX A,@DPTR MOVX @Ri,A MOVX@DPTR, A MOVC A,@A+PC 功能 A ← Rn A←(direct) A ←(Ri) A ← data Rn← A Rn←(direct) Rn←data (direct1)←A (direct1)←Rn (direct1)←(direct2) (direct1)←(Ri) (direct1)←data (Ri)←A (Ri)←(direct) (Ri)←data DPTR←data16 A←(Ri) A←(DPTR) (Ri)←A (DPTR)←A A←(A+PC) 机器码 11101rrr E5 direct 1110011i 74data 11111rrr 10101rrr direct 01111rrr data F5 direct1 10001rrr direct1 85 direct2 direct1 1000011i direct1 75direct1 data 11110111 1010011i direct 0111011i data 90dataH dataL 1110001i E0 1111001i F0 83 字节数 1 2 1 2 1 2 2 2 2 3 2 3 1 2 2 3 1 1 1 1 1 周期数 1 1 1 1 1 2 1 1 2 2 2 2 1 2 1 2 1 2 2 2 2

二、算术指令

MCS-51单片机的算术运算类指令共计24条,它主要完成加、减、乘、除四则运算,以及加1指令、减1指令、二—十进制调整操作,这些指令一般都影响标志位。 1、加法指令

加法指令共有8条,都是以累加器内容作为相加的一方,相加后的和被送回累加器中,影响标志AC、CY、OV、P。

10

(1) 不带进位加法指令(4条)

格式: ADD A,#data ;A←A+data

ADD A,direct ;A←A+(direct) ADD A,@Ri ; A←A+(Ri) ADD A,Rn ;A←A+Rn 功能:将两个操作数相加,再送回累加器中。

例20:某程序执行指令为:MOV A, #OC3H ADD A, #OAAH 求执行结果,并说明对状态字的影响。

解: 11000011(OC3H)

+) 10101010(OAAH)

1 01101101 结果为A=6DH Cy=1,OV=1 AC=0,P=1 例21:8位数加法的两个程序如下:

(1)MOV A,#ACH; (2)MOV A,#54H ADD A,#85H; ADD A,#27H

给出程序执行结果,并说明对状态标志的影响。

(1) 1 0 1 0 1 1 0 0 (ACH) (2)0 1 0 1 0 1 0 0 (54H) + 1 0 0 0 0 1 0 1 (85H) + 0 0 1 0 0 1 1 1 (27H) 1 0 0 1 1 0 0 0 1 0 1 1 1 1 0 1 1 无进位AC=0 1⊕0=1 0⊕0=0,OV=0 有进位C=1 无进位C=0 结果:CY=1,OV=1,AC=1,P=1 结果:Cy=0,OV=0,AC=0,P=1

A=31H A=7BH

说明:OV—带符号数运算时和的第6、7位中有一位产生进位而另一位不产生进位,则使OV置1,否则被清0。

例22: 求执行指令ADDC A ,R0的结果,设R0=55H,A=OAAH,Cy=1。 解: 10101010 (0AAH) 01010101 (55H) +) 1 (Cy)

1 00000000

结果: A=00H, Cy=0, AC=0, OV=0, P=0

例23:设A=85,(30H)=6DH,Cy=1,执行指令ADDC A ,30H 解: 10000101(85H) 01101101(6DH) +) 1 (Cy)

11110011

结果:A=F3H,Cy=0,OV=0,AC=1,P=0 例24:编写程序计算4455H+22FFH的结果。

11

编程说明:由于两个加数均为16位数,应分二步编程计算,①先将二数低8位相加,若有进位存入Cy中。②再将二数高8位同Cy相加后,结果分别存入40H,41H单元中。 解:MOV A ,#55H ;取第一个加数的低8位

ADD A ,#0FFH ;两个加数低8位相加 MOV 40H ,A ;存入低8位和

MOV A ,#44H ;取第一个加数的高8位 ADDC A, #22H ;两个加数高8位和Cy相加

MOV 41H ,A ;存入高8位和

2、带借位减法指令

该指令有4条,以累加器内容作为被减数,减后的差被送回累加器。 格式:SUBB A ,#data ;A←A-data—Cy

SUBB A ,Rn ;A←A-Rn—Cy SUBB A ,direct ;A←A-(direct)—Cy SUBB A ,@Ri ;A←A-(Ri)—Cy

功能:累加器A中的内容减去原操作数中的内容及进位位Cy,差再存入累加器A中。 例25:当执行程序指令SUBB A ,#64H的结果,设A=49H,Cy=1。 解: 01001001(49H) 01100100(64H) —) 1

1 11100100 结果:A=E4H,Cy=1,P=0,AC=0,OV=0 减法运算对PSW中的影响:

(1) 减法运算的最高位有借位时,进位位Cy置位为1,否则Cy为0。

(2) 减法运算时低4位向高4位有借位时,辅助进位位AC置位为1,否则AC为0。 (3) 减法运算过程中,位6和位7同时借位时溢出标志位OV为1,否则OV为0。 (4) 运算结果中“1”的个数为奇数时(注意:不计借CY中的1),奇偶校验位P置1,否则P为0。

(5) 由于减法只有带借位减法一条指令,所以在单字节相减时,须先清借位位(CLR C)。 (6) 加法运算与上述减法运算类似,这里不缀述了。

例26:设A=D9H,R0=87H,求执行减法指令后的结果。 程序为:CLR C

SUBB A,R0

解: 11011001(D9H)

10000111(87H) - 0(Cy)

01010010

结果:A=52H,CY=0,AC=0,P=1,OV=0

例27:设计程序为两字节数相减,设被减数放30H、31H中,减数放40H、41H中,得到差放入50H、51H中,如果在高字节有借位则转OVER做处理。 设计程序为:

AUN1:MOV A,30H; 把被减数放到A中

CLR C; 低字节减无借位CY被清0 SUBB A,40H;低字节相减

12

MOV 50H,A; 存结果

MOV A ,31H;被减数字节送A SUBB A,41H;高字节相减 MOV 51H,A;存结果

JC OVER;高字节若有借位Cy=1,转入OVER执行

. .

OVER…………

3、乘除法指令 (1) 乘法指令

格式:MUL AB;

(A)0~7???(A)?(B)

(B)8~15?功能:把累加器A和寄存器B中的8位无符号整数相乘,乘积为16位,积低8位存于A中,积高位存于B中。如果积大于255(0FFH),则OV 置1,否则清0,运算结果总使进位位Cy清0。

例28:设A=80H,B=32H,执行指令

MUL AB

执行结果:乘积1900H,A=00H,B=19H OV=1,CY=0

例29:编写程序33H55H×44H—〉R5R4R3。

编程要点说明:16位数乘以8位数,先将16位数分为两个8位数,先乘低8位,后乘高8位,再相加,假设J=33H,K=55H,L=44H。 图示为

J K ? L

KL高 KL低

+ JL高 JL低

R5 R4 R3

编制程序为:MOV A,#55H

MOV B,#44H

MUL AB

MOV R3,A ; R4R3 MOV R4,B ; MOV A,#33H MOV B,#44H

MUL AB ;J?L ADD A,R4

MOV R4,A ;R4←KL高+JL低 MOV A,B

ADDC A,#00H ;R5←JL高+进位 MOV R5,A

(2)除法指令

K?L

13

(A)商?格式:DIV AB;??(A)/(B)(B)余数?

功能:把累加器A中的8位无符号整数除以寄存器B中8位无符号整数,商放在A中,余数放在B中,标志位Cy和OV均清0。若除数(B)为00H,则执行后果为不确定值`,OV置1,在任何情况下,进位位Cy清0。

例30:设累加器A=87H,B=0CH,执行指令DIV AB

结果:A=0BH,B=03H,OV=0,CY=0

例31:试编写程序,要求:把A中的二进制数转换为3位BCD码。百位数放在30H,十位、个位数放在31H中。

编程要点说明:(1)将要转换的二进制数除以100,商即为百位数,余数再除以10,商和余数分别为十位和个位数。(2)通过SWAP、ADD指令组成一个压缩的BCD数,其中十位数放在A7~4,个位数放在A3~0。程序编写如下:

MOV B,#100 ;置除数为100 DIV AB ;除以100 MOV 30H,A ;商放入30H

MOV A,B ;余数放A MOV B,#10 ;置除数为10

DIV AB ;除以10,个位数放入B,十位放入A SWAP A ;十位数放入A7~4 ADD A,B ;组合BCD码 MOV 31H,A ;存十位和个位数

SJMP $

乘除法指令说明:

(1) 乘法指令和除法指令需要4个机器周期,也是指令系统中执行时间最长的指令。 (2) 在进行8位数乘除法运算时,必须将相应的被乘数和乘数、被除数和除数分别放入

累加器A和寄存器B中,才能进行计算。 (3) 在MCS-51型单片机中乘法和除法指令仅适用于8位数乘法和除法运算。如果被乘

数、被除数和除数中有一个是16位数时,不能用两个指令。

4.加1、减1指令

该指令是把所指定的变量加1,结果仍送回原地址单元,这类指令不影响标志位,加1指令共有五条。

(1)加1指令

格式: INC A ;A←A+1

INC Rn ;Rn←Rn+1 INC @Ri ;(Ri)←(Ri)+1 INC direct ;(direct)+1

INC DPTR ; DPTR←DPTR+1

例32:设(Ro)=7EH,片内数据RAM中(7EH)=0FFH,(7FH)=40H,执行下列指令: INC @R0 ;(R0)←(R0)+1=00H INC R0 ;R0←R0+1=7FH INC @R0 ;(7FH)←41H 执行结果:(R0)=7FH,(7EH)=00H,(7FH)=41H (2)减1指令

14

该指令是将指定变量减1,结果仍存在原指定单元。这类指令不影响标志位,减1指令共有四条。

格式: DEC A ;A←A-1

DEC Rn ;Rn←Rn-1

DEC direct ;(direct)←(direct)-1 DEC @Ri ;(Ri)←(Ri)-1

例33:执行下列指令序列:

MOV R1,#7FH ; R1←7FH MOV 7EH,#00H ;(7EH)←00H MOV 7EH,#40H ;(7EH)←40H DEC @R1 ;(7FH)←3FH DEC R1 ;R1←7EH

DEC @R1 ;(7EH)←0FFH 执行结果:(R1)=7EH,(7EH)=0FFH,(7EH)=3FH

加1减1指令说明:

(1)该指令与加、减法指令中加1减1运算的区别是加1减1指令不影响标志位,即加1大于256时不向CY进位,CY保持不变;减1不够减时不向CY借位,CY始终保持不变。 (2)没有16位减一指令。

例34:试编制两个三字节数相减程序。设被减数放在10H起始的连续3个单元中(低位在前),减数放在30H起始的连续3个单元(低位在前),相减的结果仍放在10H起始的单元。

CLR C ;CY清0

MOV R0,#10H ;置被减数首地址 MOV R1,#30H ;置减数首地址 MOV A,@R0 ;取低8位被减数 SUBB A,@R1 ;低8位相减 MOV @R0,A ;存低8位差

INC R0 ;指向中8位被减数 INC R1 ;指向中8位减数 MOV A,@R0 ;取中8位被减数 SUBB A,@R1 ;中8位相减 MOV @R0,A ;存中8位差

INC R0 ;指向高8位被减数 INC R1 ;指向高8位减数 MOV A,@R0 ;高8位被减数 SUBB A,@R1 ;高8位相减 MOV @R0,A ;存高8位差

从上述程序可以看出,有些指令为重复操作,若采取循环操作,则可将程序简化:

CLR C

MOV R0,#10H

MOV R1,#30H

MOV R2,#03H ;置循环数

LOOP:MOV A,@R0

SUBB A,@R1 MOV @R0,A

15

INC R0

INC R1

DJNZ R2,LOOP ;循环未结束,继续

SJMP $

5、二—十进制调整指令

该指令又称BCD码调整指令,它主要是对加法运算结果进行BCD码调整。由于BCD码按二进制运算法进行加减后,有可能出错,利用二—十进制调整指令可对运算结果进行调整。

格式:DA A

说明:进行BCD码加法运算时,需在加法指令后加入该指令,可以对BCD进行调整。 例35:利用十进制加法调整指令作十进制减法调整。编程的思路:必须采用补码相加的方法,用9AH(100)减去减数即得以10为模的减数补码。

设被减数存30单元,减数存40H单元,结果存50H单元,编写程序如下: BCDSUB1: CLR C ;清进位位 MOV A,#9AH ; SUBB A, 40H ;

减数补码 ADD A,30H ;进行补码相加

DA A

MOV 50H,A ;结果(差)存50H单元

例36:已知两个BCD码分别存在31H、30H和43H、42H中,试编程求其和,并存入R4R3R2。

程序如下:

MOV A,30H

ADD A,42H ;低16位相加

DA A ;低16位BCD码调整 MOV R2,A ;低位存入R2

MOV A,31H

ADDC A,43H ;高16位相加 DA A ;高16位BCD码调整 MOV R3,A ;高位存入R3 CLR A

RLC A ;进位位移入A中 MOV R4,A ;进位存入R4 6、算术运算类指令汇总表见表2-3

表2-3 单片机算术运算类指令

类型 助 记 符 功 能 机 器 码 对PSW的影响 字节数 周期数 不 带 Cy 加 带 Cy 加 法 ADDC A, ADD A, Rn @Ri Direct #data Rn @Ri Direct #data A←A+Rn A←A+(Ri) A←A+(direct) A←A+data A←A+Rn+Cy A←A+(Ri)+Cy A←A+(direct)+Cy A←A+data+Cy 16

00101rrr 0010011i 25direct 24data 00111rrr 0011011i 35 direct 34 data Cy OV AC Cy OV AC Cy OV AC Cy OV AC Cy OV AC Cy OV AC Cy OV AC Cy OV AC 1 1 2 2 1 1 2 2 1 1 1 1 1 1 1 1

带Cy 加 法 SUBB A, Rn @Ri Direct #data A←A-Rn-Cy A←A-(Ri)-Cy A←A-(direct)-Cy A←A-data-Cy A←A+1 Rn←Rn+1 (Ri)←(Ri)+1 (direct)←(direct)+1 DPTR←DPTR+1 A←A-1 Rn←Rn-1 (Ri)←(Ri)-1 (diret)←(diret)-1 10011 rrr 1001011i 95 direct 94 data 04 00001rrr 0000011i 05 direct A3 04 00001rrr 000011i 05direct A4 84 D4 Cy OV AC Cy OV AC Cy OV AC Cy OV AC P 无影响 无影响 无影响 无影响 P 无影响 无影响 无影响 1 1 2 2 1 1 1 2 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 4 4 1 INC A Rn @Ri Direct DPTR 减 1 DEC A Rn @Ri Direct 乘法 除法 MUL AB DIV AB BA←AXB A←A/B(商),B←余数 十进制调整 0 OV P 0 OV P Cy AC 调整 DA A

三、逻辑运算指令

逻辑运算指令共24条,包括与、或、异或、清零、求反和左右移位等逻辑指令。按操作数也可分为单、双操作数两种。逻辑运算指令涉及寄存器A时,影响P,但对AC、OV及CY没有影响。

1、“与”指令

本指令共有六条,逻辑与的结果大部分送回累加器A,只有最后两条指令送入直接地址单元中。

格式:

ANL A,#data ; A←A∧data ANL A,Rn ;A←A∧Rn ANL A,@Ri ;A←A∧(Ri) ANL A,direct ;A←A∧(direct) ANL direct,#data ;A←∧data

ANL direct,A ;A ←∧A

功能:前四条将A中内容与源操作数所指内容进行按位与运算,并将结果送入A中,且影响奇偶标志位。后两条将直接地址单元中内容与操作数所指内容进行按位与运算,将结果送入直接寻址地址单元中。

例37:如果A=00001111B,(40H)=10001111B,当执行指令ANL A,40H时,A的内容。 解:A=00001111B=0FH

例38:将寄存器A中的压缩BCD码拆分为2个字节,将寄存器A中的低4位送到P1口的低4位,寄存器A中的高4位送到P2口的低4位,P1、P2口的高4位清0。

根据题意得,可编程如下:

MOV B,A ;A的内容暂存于B中 ANL A,# 00001111B ;清高4位,保留低4位

17

MOV P1,A ;A低4位→P1口

MOV A,B ;取原数据

ANL A,# 11110000B ;保留高4位,低4位清0 SWAP A ;A7~4→A3~0 MOV P2,A ;A高4位→P2口

2、或运算指令

或指令共有六条,执行指令后的结果存入累加器或直接地址单元中。 格式:ORL A,# data ;A←A∨d

ORL A,Rn ;A←A∨Rn

ORL A,@Ri ;A←A ∨Ri) ORL A,direct ; A←A∨(direct)

ORL direct,#data ;(direct) ←(direct) ∨ data

ORL direct,A ;( direct) ← (direct)∨A

或指令也常用于修改某工作寄存器、某片内RAM单元、某直接寻址(包括P0、P1、P2、P3端口)或累加器本身的内容,控制修改的数或累加器中内容等。 例 39:如果(A)=12H,(R0)=71H,(71H)=60H,当执行下列指令后,求A中的内容。 (1)ORL A,R ;A=73H ( 2 ) ORL A,@R0 ;A=72H 3、异或指令

同与、或指令一样,异或指令有六条,其操作方式与“与、或”指令一样。 格式: XRL A,# data ;A ←A ? data

XRL XRL XRL XRL

A,Rn ;A ← A ?Rn A,@Ri ;A ←A? (Ri) A,direct,# data ;A←A? (direct)

direct,#data ;(direct) ← (direct) ?data

XRL direct,A ;(direct) ← (direct) ?A

异或指令也常用于修改某工作寄存器、某片内RAM单元、某直接寻址字节(包括P0、P1、P2、P3端口)或累加器本身的内容。

例40:执行指令XRL P1,# 00110001B P1=01111001B,则执行结果:

P1=01001000B 4、A操作指令

A操作指令共有六条,可以实现将累加器A中的内容进行取反,清零,循环左、右移,带Cy循环左右移。

格式及功能(详见表2-4示意图):

CLR A ;A → 0 CPL A ;A → A

RL A ;循环左移

RLC A ;带Cy循环左右移 RR A ;循环右移

RRC A ;带Cy循环右移

例41:假设 A=5AH、C=1,执行下面指令。

(1) CPL A ;A=0A5H

18

(2) CLR A ;A=0 (3) RLA A ;A=0B4H (4) RLC A ;A=0B5H (5) RR A ;A=2DH (6) RRC A ;A=0ADH

对执行RL指令来说,相当于把原内容乘以2;对执行RC指令,相当于把原内容除以2。

例42:编程实现16位数的算术左移。设16位数存放在内RAM 40H、41H 单元,低位在前。 算数左移是指将操作数整体左移一位,最低位补充0。相当于完成对16位数的乘2操作。程序如下:

CLR C ;Cy清0

MOV A,40H ;取操作数低8位送A RLC A ;低8位左移一位 MOV 40H,A ;送回 MOV A ,41H ;指向高8位 RLC A ;高8位左移

MOV 41H,A ;送回

例43:设在外RAM 2000H中存放有两个BCD码,试编一程序将这两个BCD码分别存到2000H和2001H的低4位。

程序如下:

MOV DPTR ,# 2000H

MOVX A ,@DPTR ;读外RAM 2000H单元中的BCD码 MOV B , A ;暂存

ANL A , # 0FH ;屏蔽高4位,保留低4位 MOVX @DPTR ;回存外RAM2000H单元

INC DPTR ;指向外RAM2001H单元 MOV A , B ;读原BCD码

ANL A, #0F0H ;屏蔽低4位,保留高4位 SWAP A ;高4位→低4位

MOVX @DPTR ,A ;回存外RAM 2001H单元

例44:在30H与31H单元有两个BCD码,现要将它们合并到30H单元以节省内存空间。

程序如下:

MOV A ,30H

SWAP A ;(20H)3~0→A7~4 ORL A ,31H ;合并 MOV 30H ,A ;回存

5、 逻辑运算类指令汇总表(见表2-4)

表2—4 MCS—51型单片机逻辑运算类指令 类 型 助 记 符 功 能 机 器 码 字节数 周期数 ANL A, # data Rn @ Ri A←A∧data A←A∧Rn A←A∧(Ri) 55 direct 01011 54 data 2 1 2 1 1 1 19

与 ANL direct, direct # data A A←A∧(direct) (direct)←(direct)∧data (direct)←(direct)∧A A←A∨data A←A∨Rn A←A∨(Ri) A←A∨(direct) (direct)←(direct)∨data (direct)←(direct)∨A A←A⊕data A←A⊕Rn A←A⊕(Ri) A←A⊕(direct) (direct)←(direct)⊕data (direct)←(direct)⊕A 0101011i 53 direct data 52 direct 45 direct 01001rrr 44 data 0100011i 43 direct data 42 direct 65 direct 01101rrr 64 data 0110011i 63 direct data 62 direct 23 1 3 2 2 1 2 1 3 2 2 1 2 1 3 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 或 ORL A, # data Rn @ Ri direct ORL direct, # data A 异或 XRL A, # data Rn @ Ri direct XRL direct, 循 环 移 位 RLC A # data A RL A ←←←←←←←←← ← c ←←←←←←←← 33 1 1 RR A →→→→→→→→ 03 1 1 RRC A ← c →→→→→→→→ 13 1 1 求反 清0 CPL A CLR A A←A A←0 F4 E4 1 1 1 1 四 、转移指令

在MCS—51型单片机中,它具有一定的智能作用,这主要是由于存在控制转移类指令。程序转移类指令共计有16条,另还有一条NOP指令。除NOP指令执行时间为1个机器周期外,其它转移指令的执行时间都是两个机器周期。该指令通常包括无条件转移指令、条件转移指令、比较转移指令、循环转移指令以及调用和返回指令。该指令通过修改PC的内容来控制程序的执行,提高效率,它一般不影响标志位。 1、无条件转移指令

无条件转移指令有4条。由于指令执行的结果,程序的执行顺序是必须转移的,所以称该指令为无条件转移指令。 (1)短转移指令

格式: AJMP addr11 ;

PC(PC+2,PC10~0(addr10~0,PC15~11不变)

20

ADD A,R1 ;完成a+b

MOV AD,A ;存a+b→c SJMP $ ;暂停

SQR:INC A ;查表位置调整

MOVC A,@A+PC ;查平方表 RET ;返回

TAB:AC 0,1,4,9,16,25,36,64,81

END

22

说明:通过两次调用查平方表子程序来得到a、b的值。

例81 求两个无符号数数据块的最大值。数据块的首地址分别为BLOCK1和BLOCK2,每个数据块的第一个字节都存放数据块的长度。设长度都不为0,结果存入MAX单元。

源程序如下:

MOV R1,#BLOCK1 ;取第一数据块首址

LCALL FMAX ;第一次调用

MOV TEM,A ;暂存第一数据块最大值 MOV R1,#BLOCK2 ;取第二数据块首址

LCALL FMAX ;第二次调用

CJNE A,TEM,NEXT ;比较两个数据块的最大值 NEXT:JNC NEXT1 ;最大值2≥最大值1 MOV A,TEM ;最大值2<最大值1 NEXT1:MOV MAX,A ;存最大值 SJMP $ TEM DATA 20H

FMAX:MOV A,@R1 ;取数据块长度 MOV R2,A ;R2作计数器 CLR C ;准备作比较 LOOP:INC R1 ;指向下一个数据 CLR A ;准备作减法 SUBB A,@R1 ;用减法作比较 JNC LP1 ;A≥(R1)

MOV A,@R1 ;A<(R1),A←(R1) SJMP LP2

LP1:ADD A,@R1 ;恢复A LP2:DJNE R2,LOOP ;循环 RET 7.查表程序

在MCS—51型单片机应用系统中,查表程序用来完成数据计算及转换等功能,查表程序具有程序简单,使用便捷,执行速度快等特点。通常数据表格被存放在程序存贮器ROM中,所以在编制程序时,可以用DB伪指令将表格中内容存入ROM。常用查表指令使用方法有以下二种:

(1)MOVC A,@ A+PC

说明:用PC作为基地寄存器时,由于PC是一个程序计数器,所以查表时操作可分三步: ①变址值存于累加器A中;

②偏移量加上累加器A→累加器A中.

2

2

22

46

③执行指令 MOVC A ,@ A+PC

(2)MOVC A,@ A+DPTR

说明:该指令用DPTR作基址寄存器,查表时分以下三点进行: ①基址值赋给DPTR;

②变址值存于累加器A中;

③执行指令 MOVC A,@ A+DPTR。

例82 将1位十六进制数转换为ASCII码。设1位十六进制数存放在R0的低4位,转换后的ASCII码仍送回R0中。 方法1:

ORG 0200H

MOV A,R0 ;读数据 ANL A,#0FH ;屏蔽高4位 MOV DPTR,#TAB ;置表格首地址 MOVC A,@A+DPTR ;查表

MOV R0,A ;回存

SJMP $

TAB:DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H ;0~9 ASCII码 DB 41H,42H,43H,44H,45H,46H ;A~F ASCII码

方法2:

MOV A,R0 ;读数据 ANL A,#0FH ;屏蔽高4位

CJNE A,#0AH,BS ;与10比较,在C中产生<10或≥10标志 BS: JC BS1 ;C=1,<10

ADD A,#37H ;C=0,≥10,则加37H SJMP BS2

BS1:ADD A,#30H ;若<10,则加30H BS2:MOV R0,A ;回存

SJMP $

说明:通过上述两种程序的比较,用查表程序显得更简单、直观。

本章小结

MCS-51单片机的指令有数据传送、算术运算、逻辑运算和控制转移等四种类型,每条指令都有各自的格式、功能及使用说明。

指令的基本格式由标号、操作码、操作书及注释组成。为方便寻找操作数,单片机有七种寻址方式:立即寻址、直接寻址、寄存器间接寻址、寄存器寻址、变址寻址、相对寻址及位寻址。寻址方式的不同主要表现在取操作数的方法不同和寻址范围的不同上。单片机共有111条指令,指令如果按长度可分为:1字节、2字节及3字节指令。如果按时间可分为:1机器周期、2机器周期及4机器周期指令。如果按功能可分为:数据传送类、算术运算类、逻辑运算类、位操作类及控制转移类指令。

汇编语言的语句的格式为:标号、操作码、操作数及注释。

伪指令能对汇编程序其说明和控制的作用,其本身不产生机器代码,由于它不属于指令系统。汇编语言程序有六种基本结构:顺序程序、分支程序、循环程序、查表程序、散转程序及子程序结构。

本章给出一些典型程序设计的例子,针对这些读者可以自行编制一些程序。

习题二

47

1、简述MCS-51单片机指令的基本格式?

2、Rn与Ri有什么区别?n与i值的范围是多少?@Ri表示什么含义? 3、30H与#30H有什么区别?

4、说明下列符号的意义,并指出它们之间的区别。

(1)R0与@R0;(2)A←R1与A←(R1);(3)DPTR与@DPTR。

5、什么是寻址方式?80C51单片机指令系统有几种寻址方式?试述各种寻址方式所能访问的存储空间。

6、指出下列指令中的操作数的寻址方式。

(1)MOV R0,#30H (2)MOV A,30H (3)MOV A,@R0 (4)MOV @R0,A (5)MOVC A,@A+DPTR (6)CJNE A,#00H,30H (7)MOV C,30H (8)MUL AB (9)MOV DPTR,#1234H (10)POP ACC 7、访问内部RAM时,可采用哪些寻址方式?

8、80C51指令中,常用字符代表立即数或存储单元,试判断下列字符ABC的含义。 (1)MOV A,#ABC (2)MOV A,ABC (3)MOV C,ABC (4)MOV DPTR,#ABC 9、若R0=11H,(11H)=22H,(33H)=44H,写出执行下列指令后的结果。 (1)MOV A,R0 (2)MOV A,@R0 (3)MOV A,33H

(4)MOV A,#33H 10、若A=11H,(11H)=22H,B=44H,写出执行下列指令后的结果。 (1)MOV R1,A (2)MOV R3,11H (3)MOV R3,#11H (4)MOV R3,B

11、若A=11H,R0=33H,(22H)=66H,(33H)=44H,写出执行下列指令后的结果。 (1)MOV 40H,A (2)MOV 40H,R0 (3)MOV 40H,@R0 (4)MOV 40H,22H

(5)MOV 40H,#22H 12、若A=11H,R0=33H,(22H)=66H,(33H)=44H,写出执行下列指令后的结果。 (1)MOV @R0,A (2)MOV @R0,22H (3)MOV @R0,#22H

13、若 A=11H,R0=33H,B=44H,(11H)=22H,(22H)=66H,(33H)=44H,分别写出执行下列指令后的结果。 (1)MOV A,R0 (2)MOV B,#55H (3)MOV 40H,@R0 (5)MOV 11H,22H (6)MOV @R0,22H

48

14、请按下列要求传送数据。

(1)将R0中的数据传送到30H。 (2)将R0中的数据传送到R7。 (3)将R0的数据传送到B。 (4)将40H中的数据传送到50H。 (5)将40H中的数据传送到R2。 (6)将40H中数据传送到50H。 (7)将立即书40H传送到R5。 (8)将立即数40H传送到40H。 (9)将立即数40H传送到以R1中内容为地址的存储单元中。 (10)将R6中的数据传送到以R2中内容为地址的存储单元中。

15、已知(30H)=11H、(11H)=22H、(40H)=33H,试求下列程序依次连续运行A、R0和30H、40H、50H、60H单元的内容。

MOV 50H,30H MOV R0,#40H MOV A,11H MOV 60H,@R0 MOV @R0,A

MOV 30H,R0

16、设内RAM(40H)=FFH,分析以下程序运行结果。

MOV 50H,#40H MOV R1,#50H MOV A,@R1 MOV R0,A MOV 60H,@R0

MOV 30H,60H

17、设A=11H,(44H)=22H,R0=33H,写出下列程序依次运行后有关单元的内容。

MOV A,R0 MOV R0,#44H

MOV 33H,@R0 MOV @R0,A

MOV A,R0 MOVX @R0,A

18、试按下列要求传送数据

(1)内RAM 50H单元数据送外RAM 50H单元;设内RAM(50H)=11H。 (2)R0中数据送外RAM 50H单元;设R0=FFH。

(3)外RAM 50H单元数据送内RAM 50H单元;设外RAM(50H)=22H。 (4)外RAM 50H单元数据送R0;设外RAM(50H)=22H。

(5)外RAM 2000H单元数据送内RAM 50H单元;设外RAM(2000H)=33H (6)外RAM 2000H单元数据送外RAM 3000H单元;设外RAM(2000H)=33H 19、按下列要求传送数据:设ROM(4000H)=44H (1)ROM 4000H单元数据送内RAM 20H单元。 (2)ROM 4000H单元数据送P1口。

(3)ROM 4000H单元数据送R0。

(4)ROM 4000H单元数据送外RAM 20H单元。

(5)ROM 4000H单元数据送外RAM 2000H单元。

20、试将0H、R7、B、A、PSW、DPTR中的数据依次压入堆栈。并指出每次堆栈操作后,SP=?、(SP)=?设原SP=60H,当前工作寄存器区为0区,(30H)=11H,R7=22H,B=33H,

49

A=44H,PSW=55H,DPTR=6677H。

21、若A=ABH,R0=34H,(34H)=CDH,(56H)=EFH,分别写出执行下列指令后的结果。 (1)XCH A,R0 (2)XCH A,@R0 (3)XCH A,56H (4)XCHD A,@R0 (5)SWAP A

22、试分别用三种方法编程实现数据互换:R0 23、说明下列指令的作用,执行后R0=?

MOV R0,#72H XCH A,R0

SWAP A XCH A,R0

24、若A=78H,R0=34H,(34H)=DCH,(56H)=ABH,求分别执行下列指令后A和Cy中的数据。

(1)ADD A,R0 (2)ADDC A,@R0

(3)ADD A,56H (4)ADD A,#56H 25、若A=96H,R0=47H,(47H)=CBH,(69H)=34H,(95H)=96H,Cy=1,求分别执行下列命令后A和Cy中的数据。

(1)ADDC A,,R0 (2)ADDC A,@R0 (3)ADDC A,69H (4)ADDC A,#69H

(5)SUBB A,R0 (6)SUBB A,@R0 (7)SUBB A,95H (8)SUBB A,#95H 26、被减数存在31H30H中(高位在前),减数存在33H32H中,试编写其减法程序,差值存入31H30H单元,借位存入32H单元。

27、已知两乘数分别存在R0和R1,试编程求其积,并存入R3R2。

28、已知被除数和除数分别存在31H和30H,试编程求其商,商存入33H,余数存入32H。 29、已知某数大于100,小于256,存于R7中,试编程将其转换为3位BCD码。依次存在R7、R6、R5中。

30、对下面一段程序加上注释,并说明运行结果。 MOV A,#11H MOV B,A ADD A,B MOV 20H,A INC A MOV 21H,A ADDC A,20H SUBB A,B MOV R0,20H DEC R0 ADD A,@R0

31、若A=B7H=10110111B,R0=5EH=0101110B,(5EH)=D9H=11011001B,(D6H)=ABH=10101011B,分别写出执行下列各条指令的结果。 (1)ANL A,R0

50H。(设当前工作寄存区为0区)

50

双字节指令,是11位地址的无条件转移指令,它的机器码为:a10 a9 a8 0 0 0 0 1 a7??a0,a10a0为转移目标地址中的低11位,00001是这条指令特有的操作码,其转移范围为PC+2后的同一2KB内,也就是高5位地址相同。

由于AJMP是双字节指令,当程序真正转移时PC的内容加2,即PC+2→PC,因此转移的目标地址应与AJMP下相邻指令第一字节地址在同一双字节范围,本指令不影响标志位。 例45:若某程序中指令AJMP LOOP所在的地址为2455H,已知该指令的机器码为C188H,那么目标地址LOOP是多少?

解:①PC+2=2455H+2=2457H→PC,则得高5位,即PC15~11=00100

②机器码C188H=11000001 10001000 B a10a9a8 a7 a0 可知11位地址为11010001000 B。

a10??a0

③目标地址LOOP:PC15—11—a10—a0=0010011010001000B=2688H (2)长转移指令

格式:LJMP addr16 ; PC(addr15~0,转移范围为64KB)

此为三字节指令,机器码的第一字节为02H,第二字节为地址高8位,第三字节为地址的低8位即02 addr 15~8 addr 7~0。 该指令可使程序执行在64KB地址范围内无条件转移,但比AJMP指令多占1个字节, 不可多用该指令。 (3)相对转移指令

格式:SJMP rel ;PC←PC+2,PC←PC+rel

此为双字节指令,机器码的第一字节为80H;第二字节为相对地址值,也称相对偏移量,是一个8位带符号的数。

该指令的转移范围为+127B~ -128B。

转移的地址=源地址+2+rel ↓ ↓

SJMP所在地址 +127~ -128 (执行程序前的PC)

在手工汇编时,常需计算地址的相对偏移量,设相对转移指令第一个字节为源地址,要转去执行指令的第一字节地址为目的地址,则其相对偏移量为: 向下转移:rel=(源、目的地址差的绝对值)-2

向上转移:rel=FE-(源、目的地址差的绝对值)

PC地址由大到小转移,用向上转移公式;反之,用向下转移公式。

例46:设PC=2100H,转向2123H去执行程序,则其偏移量:red=(2123-2100)-2=21H 所以在2100处存放的指令SJMP rel的机器码为8021H。

假设PC=2110H,转向2100H去执行程序,则其偏移量:rel=FE-(2110-2100)=FE-10=EE 所以在2110H处开始存放的指令SJMP rel的机器码为80EEH。 LJMP、AJMP、SJMP三条无条件转移指令的区别:

(a) 这三个指令的字节不同。LJMP是3字节指令,AJMP、SJMP是2字节指令。 (b) 转移范围不同。LJMP转移范围是64KB,AJMP与PC值在同一2KB范围内,SJMP转移范围是PC(-128B~+127B)。AJMP和SJMP指令应注意转移目标地址是否在转移的范围内,不能超出其转移的范围。

(c) SJMP只给出了相对转移地址,不具体指出地址值,这样当程序修改时,只要相对

21

地址不发生变化,本指令不需改动,而LJMP、AJMP当程序修改时就有可能需要修

改该地址,SJMP常用于子程序编制。

(4)间接转移指令

格式:JMP @A+DPTR ;PC←A+DPTR ,单字节指令,.机器码为73H。 该指令以DPTR寄存器内容为基址,以累加器内容为相对偏移量,在64KB地址范围内无条件转移。指令的执行结果不会改变DPTR及A中原来的内容。本指令的特点是转移地址可以在程序运行中加以改变,这也是和前三条指令的主要区别。

2.条件转移指令

本指令有7条。它们在满足条件的情况下才进行程序转移,条件若不满足,仍按原程序继续执行,故称为条件转移指令或者称判跳指令。 (1)判A转移指令

〈a〉 A=0转移指令

格式:JZ rel ;PC←PC+2,若A=0,则PC←PC+rel转移,若A≠0,按顺序执行。

此为双字节指令,机器码的第一字节为60H,第二字节为相对地址。 〈b〉 判A不等于0转移指令

格式:JNZ rel ;PC←PC+2,若A≠0,则PC PC←+rel转移。若A=0 ,按顺序执行。 此为双字节指令,机器码的第一字节为70H,第二字节为相对地址。判A转移指令不改变原累加器内容,不影响标志位。其执行过程如图2—7所示。

(PC)←(PC)+2 (PC)←(PC)+2

=0 ≠0 A ≠ 0? A≠0? ≠0 =0 (PC)←(PC)+rel (PC)←(PC)+rel

(a)JZ rel指令 (b)JNZ rel指令 图2-7 JZ和JNZ指令执行示意图

例47:编制程序:如果A=0时,则寄存器A的内容减1,否则寄存器A的内容加上1。 方法1:JZ ADB ;若A=0,则跳转到ADB。 INC A ;若A≠0,则A ←A+1 SJMP $

ADB:DEC A ;若A≠0,则A ←A-1 SJMP $

方法2:JNZ ABC ;若A≠0,则跳转ABC。

DEC A ;若A=0,则A←A-1

SJMP $

ABC:INC A ;若A≠0,A←A+1 SJMP $

(2)判bit转移指令 bit=1转移指令

22

格式:JB bit ,rel ; PC←PC+3,若(bit)=1,则PC←PC+rel转移

若(bit)=1,则按顺序执行。 此为三字节指令。机器码的第一字节为20H,第二字节为位地址,第三字节为相对地址。 bit=0转移指令

格式: JNB bit ,rel ;PC←PC+3,若(bit)=0,则PC←PC+rel转移

若(bit)=1,则按顺序执行。 此为三字节指令。机器码的第一字节为30H,第二字节为位地址,第三字节为相对地址。 例48:设P1口上的数据为11001010B,A的内容为56H(01010110B),求执行下列指令后的结果。

JB P1.2,LOOP1 ;P1.2=0,不满足条件,顺序执行 JNB ACC.3,LOOP2 ;ACC.3=0,满足条件,转移到LOOP2 执行结果:程序转移到LOOP2去执行。

bit=1转移和清0指令

格式:JBC bit,red ;PC←PC+3,若(bit)=1,则(bit)←0,PC←PC+red转移,

若(bit)=0,按顺序执行

此为三字节指令。机器码的第一字节为10H,第二字节为位地址,第三字节为相对地址。 例49:设A的值为56H(01010110B),求执行下列指令后的结果。 JBC ACC.3,LOOP1 ;ACC.3=0, 不满足条件,顺序执行

JBC ACC.2 ,LOOP2 ;ACC.3=1, 满足条件,转移到LOOP2,且ACC.2←0 执行结果:程序转向LOOP2去执行,且使A=01010010B=52H (3)判C转移指令

C=0转移指令

格式: JNC bit ,rel ;PC←PC+2,若Cy=0,则PC←PC+rel转移,

若Cy=1,按顺序执行。

此为双字节指令。机器码的第一字节为50H,第二字节为相对地址值。 C=1转移指令

格式:JC rel ;PC←PC+2, 若Cy=1,则PC←PC+rel转移,

若Cy=0,按顺序执行。

此为双字节指令。机器码的第一字节为40H,第二字节为相对地址值。 3、 比较转移指令

格式:CJNE 目的操作数),(源操作数),rel

比较转移指令的功能是目的操作数与原操作数进行比较。 (1) 目的操作数=源操作数,则PC←PC+3程序顺序执行Cy=0 (2) 目的操作数 ? 原操作数,则PC←PC+3+rel转移 具体的比较转移指令有4条:

(a) CJNE A,#data,rel ;PC←PC+3,

若A=data,按顺序执行,且Cy=0

若Adata ,则Cy=0且PC←PC+rel,转移

此为三字节指令。机器码的第一个字节为B4H,第二个字节为立即数,第三字节为相对地址。

(b) CJNE Rn,#data,rel ;PC←PC+3

若Rn=data,按顺序执行,且Cy=0

若Rn

23

若Rn>data,则Cy=0且PC←PC+rel,转移

此为三字节指令。机器码的第一字节因n值不同而为B8H~BFH,第二字节为立即数,第三字节为相对地址。

(c) CJNE @Ri,#data ,rel ;PC←PC+3

若(Ri)=data,按顺序执行,且Cy=0

若(Ri)data,则Cy=0且PC←PC+rel,转移

此为三字节指令。机器码的第一个字因i值不同为B6H~B7H ,第二字节为立即数,第三字节为相对地址。

(d) CJNE A,dire,rel ;PC←PC+3

若A=(direct),按顺序执行,且Cy=0 若A<(direct),且Cy=1,且PC←PC+rel,转移

若A>(direct),则Cy=0,切PC←PC+rel,转移

此为三字节指令。机器码的第一字节为B5H,第二字节为直接地址,第三字节为相对地址。

例50:P1口P1.0~P1.3为准备就绪信号输入端,当该4位输入全为“1”时,说明各项工作已准备好,单片机可以顺序执行主程序,否则程序等待。部分程序如下:

D1:MOV A,P1 ;P1口内容送A ANL A,#0FH ;屏蔽高4位

CJNE A,#0FH,D1 ;该4位不全1,返回D1,否则继续执行

4、循环转移指令

(1)DJNZ Rn,rel ;PC←PC+2,Rn←Rn-1

若Rn=0,按顺序执行;若Rn不等于0,则PC←PC+rel,转移。

此为双字节指令。机器码的第一字节因n值不同为D8H~DFH,第二字节为相对地址 (2)DJNZ direct,rel ;PC←PC+3,(direct)← (direct)-1

若(direct)=0,按顺序执行;若(direct)≠0,则PC←PC+rel ,转移。

此为三字节指令。机器码的第一字节为D5H,第二个字节为直接地址,第三字节为相对地址。

例51:设数组长度放R0中,数组存放首地址在R1中,将数组之和则存在20H单元中,因为是8位字长,所以其和不应大于256。可编程序如下:

CLR A ;A清0

LOOP: ADD A,@R1 ;相加

INC R1 ;地址指针增1

DJNZ R0 ;字节书减1不为0继续加 MOV 20H,A ;结果存20H单元

END

5、调用指令和返回指令

调用指令共有4条,其中有两条调用指令LCALL及ACALL和一条与之配对的子程序返回指令RET。LCALL与ACLL指令与LJMP和AJMP指令相类似,不同的是他们在转移前,要把执行后PC的内容自动压入堆栈,返回时按后进先出原则把地址弹出PC中。 (1)短调用指令

格式:ACALL addr11 ;(PC)+2→PC,(SP)+1→SP,(PC)0~7→(SP)

(SP)=1→SP ,(PC)8~15→(SP),addr0~11 →PC0~11

24

此为双字节指令。该指令可在2KB地址范围内寻址,用来调用子程序。它与AJMP指

令转移范围相同,取决于指令中的11位地址值,所不同的是执行该指令后需返回,所以在送入地址前,先将原PC值压栈保护起来。指令机器码为:a10a9a810001a7……a0,其中10001是该指令所特有的操作码。a10~a0即为调用目标地址中的低11位addr11,其调用范围为PC+2后的同一2KB内。再执行指令时,先将PC值加上2,此值为所需保存的返回地址,把PC的低8位和高8位依次压栈,11位地址值addr11送PC的低11位,其PC值的15~11位不变。这样PC就转到子程序起始地址,执行子程序。

(2)长调用指令

格式:LCALL addr16 ;(PC)+3→PC,(SP)+1→SP,(PC)0~7→(SP)

(SP)+1→SP,(PC)8~15→(SP),addr16→PC

此为三字节指令,机器码的第一字节为12H,第二字节为地址的高八位,第三字节为地址的低8位。同上条指令ACALL相比,执行LCALL指令后的PC值完全由指令中的16位地址值提供。在执行该指令时先将PC值加上3,既得到下一条指令地址PC值的低8位和高8位依次压栈,再将16位地址值addr16送入PC。这样便能执行所调用的子程序,其调用范围为64KB,并且不影响标志位。

例52:设(SP)= 54H,标号LO2=105DH,LO1=3000H,求执行LO2:LCALL LO1指令后的结果。

执行结果:(SP)=56H,(55H)=60H,(56H)=10H,(PC)=3000H。 (3)返回指令

返回指令有子程序返回和中断返回两种: 格式:RET ;子程序返回(PC15~8)←((SP)), (SP)←(SP)﹣1,

PC7~0)←((SP))

RETI ;中断返回

此为单字节指令,机器码为32H,该指令与中断有关。计算机响应中断,程序转移到中断服务程序继续执行,可以理解为一种特殊的调用过程。中断服务程序的最后一条指令一定是返回指令,但必须用中断返回指令RETI。 6、空操作指令

格式:NOP ;PC←PC+1

空操作并没有使程序转移,执行该指令只是PC加1外,计算机不做任何操作,而继续执行下一条指令。不影响任何寄存器和标志。NOP为单周期指令,所以时间上只用一个机器周期,在延时或等待程序中常用于时间“微调”。

例53: CLR P2.7 ;P2.7清0输出

NOP

NOP ;空操做

NOP

SETB P2.7 ;置位P2.7高电平输出

7、控制转移指令汇总表(见表2-5)

表2-5 控制转移指令总表 类型 助记符 功能 无 条 件 转 AJMP addr11 PC←addr11 机器码 a10a9a800001 a7-a0 02 addr15-8 addr7-0 字节数 2 周期数 2 LJMP addr16 PC←addr16 3 2 25

移 间转 条 件 转 移 SJMP rel JMP @A+DPTR JNZ rel JZ rel PC←PC+2+rel PC←A+DPTR A≠0转 PC←PC+2+rel A=0转 PC←PC+2+rel (bit)=1转 PC←PC+2+rel (bit)=0转 PC←PC+2+rel (bit)=1转 PC←PC+2+rel 且(bit)←0 Cy=0转 PC←PC+2+rel Cy=1转 PC←PC+2+rel A≠data转 PC(PC+3+rel) Rn≠data转 PC(PC+3+rel) (Ri)≠data转 PC(PC+3+rel) A≠(direct)转 PC(PC+3+rel) Rn←Rn-1 若Rn≠0转 PC(PC+2+rel) (direct)←(direct)-1 若direct≠0转 PC(PC+2+rel) 断点入栈 PC←addr11 断点入栈 PC←addr16 子程序返回 中断返回 PC←PC+1 00 80 rel 73 70 rel 60 rel 20 bit rel 30 bit rel 10 bit rel 3 2 1 2 2 3 3 2 2 2 2 2 2 2 JB bit,rel JNB bit rel JBC bit rel JNC rel JC rel 条 件 转 移 DJNZ direct,rel CJNE A,#data,rel CJNE Rn,#data,rel CJNE @Ri,#data,rel CJNE A,direct,rel DJNZ Rn,rel 50 rel 40 rel B4 data rel 3 2 2 2 2 2 10110rrr data rel 1011011I data rel B5 data rel 11011rrr rel 3 3 3 2 2 2 2 2 D5 direct rel 3 2 无条 件调 用及 返回 空操作 ACALL addr11 LCALL addr16 RET RETI NOP a10a9a810001 a7-a0 12 addr16 22 32 1 2 3 1 1 1 2 2 2 2 五、 布尔指令 布尔指令又称为位操作指令。在MCS—51系列单片机的硬件结构除了8位CPU,还附有一个布尔处理机(或称位处理机),可以进行位寻址,进位位C具有一般CPU中累加器

26

的作用。布尔指令可以分为位传送指令,位修改及逻辑操作等等。该指令一般不影响标志位。 1.位传送指令

位传送指令有互逆的2条,可实现进位位C与某直接寻址位bit间内容的传送。 (1)MOV C,bit ;Cy←bit

双字节指令,机器码的第一字节为A2H,第二字节为直接寻址位的位寻址。 (2)MOV bit,C ;bit←Cy

双字节指令,机器码的第一字节为92H,第二字节为直接寻址位的位寻址。

上述指令中C为进位位Cy,bit为内部RAM 20H~2FH中的128个可寻址位和特殊功能寄存器中的可寻址位。 例54:将20H.0传送到22H.0。

MOV C,20H.0 MOV 22H.0,C

也可写成:

MOV C,00H ;C←20H.0

MOV 10H,C ;22H.0←C

值得注意的是:后两个指令中的00H和10H分别为20H.0和22H.0位地址,它不是字节地址。

2.位修正指令

位修正指令共有6条,指针对位清0、位置1指令、位取反指令。 (1)位清0指令

CLR C ;C←0,单字节指令,机器码为C3H。

CLR bit ;bit←0,双字节指令,机器码的第一字节为C2H,第二字节为位地址。 (2)位置1指令

SETB C ;C←1,单字节指令,机器码为D3H。

SETB bit ;bit←1,双字节指令,机器码的第一字节为D2H,第二字节为位地址。 (3)位取反指令

CPL C ;C←C,单字节指令。机器码为B3H。

CPL bit ;bit←bit,双字节指令,机器码第一字节为B2H,第二字节为位地址。 3.位逻辑运算指令

位逻辑运算指令分逻辑“与”和逻辑“或”共有4条指令。

(1) 位逻辑“与”运算指令: ANL C,bit ;C←C ?bit

双字节指令,机器码的第一字节为82H,第二字节为位地址。 ANL C,bit ;C←C ?bit

双字节指令,机器码的第一字节为B0H,第二字节为位地址。 (2) 位逻辑“或”运算指令

ORL C,bit ;C←C?bit

双字节指令,机器码的第一个字节为72H,第二个字节为位地址。 ORL C,bit ;C←C?bit

双字节指令,机器码的第一个字节为A0H,第二个字节为位地址。

对于MCS—51型单片机中无位异或指令,可以用若干条位操作指令来实现。 例55:D,E,Y都代表位地址,试编程实现D,E内容异或操作,结果送入Y中。

27

解:可直接按Y?DE?DE来编写,程序如下:

MOV C,D

ANL C,E ;C←D ?E MOV Y,C ;暂存 MOV C,E

ANL C,D ;C←E ?D ORL C,Y ;DE?DE

MOV Y,C ;结果存入Y中

例56:下列程序段可满足只在P1.0为1、A.7为1和OV为0时置位P3.1的逻辑控制。(其硬件电路见图2-9所示)

程序为: MOV C,P1.0

ANL C,A.7 ANL C,OV MOV P3.1,C

P1.0 A.7 OV P3.1 & 1 图2-9 硬件逻辑电路

5、布尔操作类指令表(见表2-6)

表2-6 MCS-51单片机布尔操作指令

类型 位传送 助记符 MOV C,bit MOV bit,C 位修正 清0 CLR C CLR bit 取反 CPL C CPL bit 置位 位逻辑运或 与 SETB C C←0 bit←0 C←C bit←bit C←1 C3 C2 bit B3 B2 bit D3 D2 bit 82 bit B0 bit 72 bit 1 2 1 2 1 2 2 2 2 1 1 1 1 1 1 2 2 2 功能 C←bit 机器码 A2 bit 字节数 2 周期数 1 bit←C 92 bit 2 1 bit←1 SETB bit ANL C,bit C←C ?bit ANL C,/bit ORL C,bit C←C?bit C←C?bit 28

ORL C,/bit C←C?bit A0 bit 2 2 第四节 汇编语言程序设计基础

在前三节中,我们已经学习了MCS-51型单片机的汇编语言和它的组成、格式等指令方式。在本节中,我们将详细介绍MCS-51型单片机常用的汇编语言程序设计方法,并列举相应的程序示例,以使读者能够掌握基本的汇编语言程序设计方法。 一、汇编语言基本概念

把用汇编语言编写的程序称为汇编语言源程序,而把在计算机上直接运行的机器语言程序称为目标程序,由汇编语言源程序“翻译”为机器语言目标程序的过程称为“汇编”。如果翻译过程由人工完成称为“手工汇编”;如果翻译过程由计算机系统软件完成,称为“机器汇编”。 一.汇编语言

一般来说,在汇编语言源程序中用MCS—51指令助记符编写的程序,可以产生目标程序。但还有一些指令并不产生目标程序,不影响程序的执行,仅产生供汇编用的某些命令,以便在汇编时执行一些特殊的操作,这种指令称为伪指令。 (一)伪指令介绍 1.ORG指令

格式:ORG 16位地址

ORG为起始伪指令,它规定其下面的目标程序的起始地址。指令中16位地址(4位十六进制数)便是起始地址。

例57: 读下列程序。

ORG 2000H ;表示后续目标程序从2000H单元开始存放。

MOV A ,20H ORG 3000H MOV A ,20H ORG 2700H MOV A,21H

END

注意:ORG定义空间地址由小到大,且不能重叠。如果空间地址有重叠,汇编将拒绝执行,并给相应的出错信息。 2.END指令

格式:END

END为结束伪指令,表明汇编语言源程序的结束标志。汇编程序对该指令后面的内容将不再进行汇编。如果源程序是主程序,则写标号,所写标号就是该主程序第一条指令的符号地址。如果源程序是一般子程序,END之后不再写标号。 3.EQU指令

格式:字符名称 EQU 数据或汇编符号

EQU为等值伪指令,是将数据或汇编符号赋于字符名称。需注意的是在同一程序中,用EQU伪指令在赋值后,其字符名称的值在整个程序中不能再改变。 例58:某程序为:PPB EQU R0 ;PPB = R0

MOV A,PPB ;A ← PPB

说明:将PPB等值于汇编符号R0,在指令中PPB可以代替R0来使用。 4.DB指令

29

格式:〈标号:〉DB〈项或项表〉

DB为定义字节指令,项或项表指所定义一个字节或用逗号分开的字符串。汇编程序把DB指令中项或项表所指字符的内容(数据或ASCII码)依次存入从标号开始的存储器单元。 例59: ORG 1000H

FIRST:DB 73,01,01,90,38,00,01,00

SECOND:DB 02,00,34,10,32,96,00,00

其中伪指令ORG 1000H指明了标号FIRST的地址1000H,伪指令DB定义了1000H~1007H单元的内容应依次为73,01,01,90,38,00,01,00。标号SECOND 因与前面8个字节紧靠,所以它的地址顺次应为1008H,而第二条DB指令则定义了1008H~100FH单元的内容依次为02H,00H,34H,10H,32H,96H,00H,00H。 5.DATA指令

格式:字符名称 DATA 表达式

DATA为数据地址赋值伪指令,其功能将数据地址赋给字符名称。DATA与EQU指令既相似又有区别:

(1) EQU指令可以把一个汇编符号赋给一个字符名称,而DATA指令不能; (2) EQU指令应先定义后使用,而DATA指令先使用后定义; (3) DATA指令能将一个表达式的值赋予一个字符名称; (4) DATA指令在程序中用来定义数据地址。 6.DW指令

格式:〈标号:〉 DW <项或项表>

DW指令为定义字伪指令,从指定的地址单元开始,定义若干个16位数据。先存入高8位,低8位后存入,不足16位者,可用0填充。DW与DB指令基本相同,不同之处DB用于8位数据。DW指令常用来表示地址表。 例60: ORG 2000H

HTA :DW 8856H, 76H,32 汇编后: (2000H)=88H, (2001H)=56H

(2002H)=00H, (2003H)=76H

(2004H)=00H, (2005H)=20H

7.DS指令

格式:〈标号:〉 DS 表达式

DS指令为定义空间伪指令,该指令功能是由指定单元开始,定义一个存储区,以备源程序使用。

例61: ORG 1000H

DS 07H

MOV A,#7AH

END

汇编以后,从1000H单元开始,保留7个字节的内存单元,然后从1007H开始,放置“MOV A, #7AH”的机器码74H7AH,即:(1007H)=74H,(1008H)=7AH。 8.bit指令

格式: 字符名称 bit 位地址

bit指令为定义位地址伪指令,主要用于定义某指定位的标号,其功能是将位地址赋给所规定的字符名称。 例62: FLG bit F0

说明:经这条伪指令定义后,可允许指令中用FLG代替F0。

30

MOV R1,#01H ;C=0,则1→R1 LJMP MP3

MP2:MOV R1,#0FFH ;R0<0,则-1→R1 MP3:SJMP $

注意:-1的补码为FFH。

亦可如下编写程序:

STARY:MOV A,R0 ;读X JZ SS2 ;若A=0,跳转 JNB ACC.7,SS1 ;R0

MOV A,#0FFH ;R0为负数,-1→A SJMP SS2

SS1:MOV A,#1 ;R0为正数,1→A

SS2:MOV R1,A ;存入R1 SJMP $

例69 两个带符号分别存在于ONE和TWO单元,试比较它们的大小,较大者存入MAX单元,若两数相等,则存任意一个。

解决本题时,需要利用两数相加减后的正负和溢出标志结合起来判断:

(1) 当X-Y>0,OV=0,,则X>Y; OV=1,则X

(2) 当X-Y>0,OV=0,则XY。

流程图见图2-13。

Y 开始 Y X-Y=0? N X-Y<0? OV=1? N Y Y OV=1? N X

图2-13 例76流程图 程序如下:

CLR C

MOV A,ONE ;A ←X

36

SUBB A,TWO ;X-Y

JZ XMAX ;X = Y,则转置XMAX JB ACC.7,NFG ;X-Y<0

JB OV,YMAX ;X-Y>0,OV=1,Y>X SJMP XMAX ;X-Y>0,OV=0,则X>Y

NFG:JB OV,XMAX ;X-Y<0,OV=1, 则X>Y YMAX:MOV A,TWO ;Y>X SJMP RMAX

XMAX:MOV A,ONE ;X>Y

RMAX:MOV MAX,A ;MAX←最大值END

例70 将ASCII码转换为十六进制数,将ASCII码放在累加器A中,转换结果放到B中。分析:由ASCII码可知30H~39H为0~9的ASCII码,41H~46H为A~F的ASCII码,将ASCII码减30H(0~9)或37H(A~F)就可获得对应的十六进制数。程序如下:

START:CLR C

SUBB A,#30H ;A-30H

CJNE A,#0AH,SS ;差值与10比较,在C中产生<10或≥10标志 SS:JC SS1 ;﹤10,已变换为ASCII码 SUBB A,#07H ;≥10,再减7

SS1:MOV B,A ;存转换结果 SJMP $ 3. 循环程序

在计算机应用中,当程序处理的对象具有某种重复性的规律时,需要用到循环程序。在MCS-51型系统中的汇编语言没有设置专门的循环语句,完成循环任务实质上是由“反转”结构的分支程序来完成。另外,循环程序可以缩短程序句段,减少其所占有的内存。循环程序一般由以下四个部分组成:

(1) 置循环初值。在进入循环之前,要对循环中需要使用的寄存器和存储器赋予其规定

的初使值,如循环次数,循环中工作单元的初值等。 (2) 置循环体。循环体是程序中需要重复执行的部分,是循环结构中的主要部分。 (3) 循环修改。每执行一次循环,就对有关参数进行相应的修改,使指针指向下一数据

所在的位置,为进入下一轮循环做准备。 (4) 循环控制。在程序执行中需要根据循环计数器的值或其他条件,来判断控制循环是

否该结束。 以上四部分有两种组织方式,其结构如图2-14所示。

置初值 置初值

循环体 循环控制 N Y

循环修改 退出循环 循环体

Y

循环控制 循环修改

N 37

2-14循环程序组织形式

例71 内部RAM 30H单元开始存有8个数,找出其中的最大的数,送入MAX单元。分析:假定在比较过程中,以A存放大数,与之逐个比较的另一个数放在3AH单元, 比较结束后,把查找到的最大数送MAX单元。 程序如下:

MOV R0,#30H ;置数据区首地址 MOV R7,#08H ;置数据区长度 MOV A,@R0 ;读出第一个数 DEC R7

LOOP:INC R0 ;指向下一个数

MOV 3AH,@R0 ;读出下一个数

CJNE A,3AH,CHK ;数值比较,在C中产生大小标志 CHK:JNC LOOP1 ;C=0,表明A值大,转移

MOV A,@R0 ;C=1,表明A值小,大数送A LOOP1:DJNZ R7,LOOP ;循环

MOV MAX,A ;最大值送MAX单元 HERE:AJMP HERE ;停止

例72 设多字节数低位字节存放于R1,字节数存于R7,试编制多字节乘10程序。 程序如下:

ORG 2000H

MUL10:PUSH PSW ;保护现场 PUSH A ;A压栈 PUSH B ;B压栈

CLR C ;清进位位C MOV R2,#00H ;将R2清0

GH10:MOV A,@R1 ;低位字节送入A中 MOV B,#0AH ;将10送入B中 PUSH PSW

MUL AB ;字节乘以10

POP PSW ;标志寄存器PSW

ADDC A,R2 ;上次积高八位与本次积低八位加得本次积 MOV @R1,A ;送原存贮单元中。 MOV R2,B ;将B中内容送R2中

INC R1 ;R1←R1+1

DJNZ R7,GH10 ;未乘完去GH10,否则向下执行。 MOV @R1,B ;(R1)←B POP B ;B出栈 POP A ;A出栈

POP PSW ;PSW出栈 RET

38

说明:因为低位字节乘10,其积可能会超过8位,所以把本次乘积之低八位与上次(低位的字节)乘积的高八位相加作为本次之积存入。在进行相加时,有可能产生进位,因此使用ADDC指令,这就要求进位入循环之前C必须清0(第一次相加无进位),在循环体内未执行ADDC之前C必须保持。由于执行MUL指令总是清除C,所在该指令前后安排了保护和恢复标志寄存器PSW的指令。程序中实际是逐字节进行这种相乘相加运算,直到整个字节完毕,结束循环。

例73 设Xi为单字节数,并按顺序存放在RAM以60H为首地址的存储单元中,数据长度(个数)n存在R2中,求S= X1+X2+?Xn,并将和S(双字节)存放在R3R4中,假设和小于65536,试编制程序。

程序流程如图2-15所示。程序如下: MOV R2,#n ; MOV R3,#00H ; 置循环初值 MOV R4,#00H ; MOV R0,#60H ;

LOOP:MOV A,R4 ; ADD A,@R0 ; MOV R4,A ; CLR A ; 循环体 ADDC A,R3 ; MOV R3,A ; INC R0 ;循环修改 DJNZ R2,LOOP ;循环控制 SJMP $ ;退出循环

开始

R3,R4←0

R0←50H

R4←A+(R0) R3←Cy+R3 R0←R0+1 39 Y R2-1?0

图2-15 例80流程图

例74 在内部RAM 40H开始的存储区有若干个字符和数字,已知最后一个字符"$"采用GJNE指令与关键字符作比较,比较时用关键字符"$"的ASCII码24H。 程序如下:

ORG 3000H

STATR:MOV R1,#40H ;R1作为地址指针 CLR A ;A作为计数器

LOOP: CJNE @R1,#24H,NEXT ;与“$”号比较,不等转移 SJMP NEXT1 ;找到“$”,结束循环

NEXT: INC A ;计数器加1

INC R1 ;指针加1

SJMP LOOP ;循环

NEXT1: INC A ;再加入“$”这个字符 MOV 50H,A ;存结果

END 在本例中,循环结束的条件是否已查到关键字“$”,所以循环次数是不确定的。 例75 编制程序,采用冒泡排序法,将8031片内RAM 50H-57H的内容,以无符号数的形式从小到大进行排序。即程序运行后,50H单元的内容为最小,57H的内容为最大。 (1) 算法说明 数据排序的方法很多,常用的算法有插入排序法、快速排序法、选择

排序法等,本例以冒泡排序法为例。 冒泡排序法是一种相邻数互换的排序方法,由于其过程类似水中的气泡上浮,故称之为冒泡法。执行时从前向后进行相邻数比较,若数据的大小次序与要求的顺序不符(也就是逆序),就将这两个数交换,否则为正序不互换。如果是升序排列,则通过这种相邻数互换的排序方法使小的数向前移,大的数向后移,如此从前向后进行一次冒泡,就会把最大的数换到最后,再进行一次冒泡,会把次大的数排到倒数第二的位置上。如此下去,直到排序完成。

若原始数据有顺序为:50、38、7、13、59、44、78、22,第一次冒泡的过程是:

50、38、7、 13、 59、 44、 78、 22(逆序、互换)

(并且只有一个),试统计这些字符数字的个数,结果存入50H单元。

38、50、 7、13、 59、 44、 78、 22(逆序、互换) 38、 7、 50、13、59、 44、 78、 22(逆序、互换) 38、 7、 13、 50、59、44、 78、 22(正序、不互换) 38、 7、 13、 50、 59、44、 78、 22(逆序、互换) 38、 7、 13、 50、 44、 59、78、 22(正序、不互换) 38、 7、 13、 50、 44、 59、78、 22(逆序、互换)

38、 7、 13、 50、 44、 59、 22、 78、(第一次冒泡结束)

40

本文来源:https://www.bwwdw.com/article/rg7v.html

Top