380 likes | 559 Views
《 单片机原理与接口技术 》 电子教案 重庆工商职业学院. 第四章 MCS-51 汇编语言程序设计. [内容提要] 本章主要讲述 MCS-51 的程序设计方法和程序设计举例。单片机的学习不外乎就是两项内容,一项是学会构建硬件系统,另一项就是学会应用程序设计。本章讲述的程序设计只是最简单的基本程序设计。 [学习要求] 掌握单片机汇编语言程序的基本结构以及加减乘除和数制转换等简单程序设计的方法,理解常用查表等典型程序设计方法。. 4.1 汇编语言程序设计概述. 一、语言的分类. 1 .机器语言:机器语言是用二进制代码 0 和 1 表示指令和数据的最原始的程序设计语言。
E N D
《单片机原理与接口技术》电子教案重庆工商职业学院《单片机原理与接口技术》电子教案重庆工商职业学院
第四章MCS-51 汇编语言程序设计 [内容提要] 本章主要讲述MCS-51的程序设计方法和程序设计举例。单片机的学习不外乎就是两项内容,一项是学会构建硬件系统,另一项就是学会应用程序设计。本章讲述的程序设计只是最简单的基本程序设计。 [学习要求] 掌握单片机汇编语言程序的基本结构以及加减乘除和数制转换等简单程序设计的方法,理解常用查表等典型程序设计方法。
4.1 汇编语言程序设计概述 一、语言的分类 1.机器语言:机器语言是用二进制代码0和1表示指令和数据的最原始的程序设计语言。 2.汇编语言:在汇编语言中,指令用助记符表示,地址、操作数可用标号、符号地址及字符等形式来描述。 3.高级语言:高级语言是接近于人的自然语言,面向过程而独立于机器的通用语言。
4.1 汇编语言程序设计概述 二、汇编语言的指令类型 MCS-51单片机汇编语言,包含两类不同性质的指令。 (1)基本指令:即指令系统中的指令。它们都是机器能够执行的指令,每一条指令都有对应的机器码。 (2)伪指令:汇编时用于控制汇编的指令。它们都是机器不执行的指令,无机器码。
4.1 汇编语言程序设计概述 三、汇编语言的语句格式 汇编语言源程序是由汇编语句(即指令)组成的。 其典型的汇编语句格式如下: [<标号>]: <操作码> [<操作数>] ;[<注释>] 如: START: MOV A,30H ;A←(30H)
4.1 汇编语言程序设计概述 四、MCS-51汇编语言的伪指令 随着单片机的广泛应用和开发以装置功能的不断完善与发展,汇编语言源程序都借助系统机(PC等)进行编辑、汇编和调试。因此,在编制汇编语言源程序时,常需应用伪指令。伪指令又称汇编程序控制译码指令,属说明性汇编指令。“伪”字体现在汇编时不产生机器指令代码,不影响程序的执行,仅产生供汇编时用的某些命令,在汇编时执行某些特殊操作。 1.ORG:汇编起始地址 其含义是指定下面目标程序的起始地址为表达式值。表达式常为一个双字节地址数。 例如: ORG 0100H START: MOV A,#00H 汇编号,从START开始的目标程序,其起始地址从0100H开始。由于表达式0100H是立即型地址码所以隐含地指明该程序段属绝对地址段。 一个源程序中,可能有多处设置程序段起始地址,因此定义地址空间应从低地址端向高地址设置,不能重叠,否则将出错。若程序段前无ORG伪指令,则汇编后的目标程序将从0000H地址开始或紧接前段程序后。若表达式为浮动程序段中定义过的标号,则由该标号定义的目标程序段首地址也将之浮动。
4.1 汇编语言程序设计概述 四、MCS-51汇编语言的伪指令 2.汇编结束伪指令——END END伪指令是汇编语言源程序结束为标志。源程序在汇编过程中执行完END伪指令,即结束伪指令,为调试方便,可根据调试需要而设置。它有两种格式: 格式1:〈标号:〉END〈表达式〉 格式2:〈标号:〉END 或者 END 其中标号不是必需的,有无表达式的区别在于前者在汇编结束后立即转向由表达式指定的起始地址开始执行程序。因此,只需在程序运行的入口处和END后的表达式以同一个标号设置,当汇编完源程序后就自动转向由标号指定的入口处开始执行。表达式也可以入口入的绝对地址,后者则汇编结束后立即停机。
4.1 汇编语言程序设计概述 四、MCS-51汇编语言的伪指令 3.标号赋值伪指令 格式:〈标号:〉EQU〈表达式〉 指令的含义为本语句的标号等值于表达式,亦即将表达式值赋予标号。这里的标号和表达式是必不可少的。 例如: TTY:EQU 1080H 本语句向汇编程序指明,标号TTY已于前句赋值为1080H,则相当于LOOP1=TTY=10802H,在程序中LOOP1和TTY两个标号可以互相使用。用EOU语句给一个标号赋值以后,在整个源程序中该标号的值是固定而不能更改的。
4.1 汇编语言程序设计概述 四、MCS-51汇编语言的伪指令 4.定义字节数据伪指令——DB或DEGB 格式:〈标号:〉DB〈表达式或表达式串〉 式中表达式或表达式串是指一个字节或用逗号隔开的一个字节数据。其含义是将表达式或表达式串所指定的字节数据存入从标号开始的连续存储单元中。标号为可选项,它表示数据存入程序存储器的起始地址。 例如: SECON:DB02H,36H,74H,0B4H,OFFH,… 上述语句表示将字节数据串按顺序存篇幅 标号SECON所指示的地址为起始顺序存储单元中。 作为本语句操作数控部分的表达式或表达式串,可以是数据表达式、ASCII码字符串、字节数据,字节数据串(其字节串长度限制在80B的数据内)。
4.1 汇编语言程序设计概述 四、MCS-51汇编语言的伪指令 5.定义字数据伪指令——DW或DEFW 格式:〈标号:〉DW〈表达式或表达式串〉 本语句的含义是将作为操作部分的字数据(2B)或字数据串存入由标号指定的首地址按顺序连续单元中,定义字为为双字节的数据。在执行汇编时,计算机会自动按高位字节在前、低位字节在后的顺序格式存入程序存储器单元中 例如: ABC:DW 1234H,4567H,0A5C4H,… 汇编执行时第一个字节的12H存入标号ABC所指示的存储单元,34H存入(ABC)+1单元中,其余按此顺序将后续字节数据存入对应的存储单元中,如标号ABC定义为1000H,则上例汇编后:(1000H)=12H,(1001H)=34H,(1002H)=45H,…。
4.1 汇编语言程序设计概述 四、MCS-51汇编语言的伪指令 6.存储区说明伪指令——DS 格式:〈标号:〉DS〈表达式〉 其含义是以标号的值为首地址保留表达式所指定的若干存储单元空间作为备用。 例如: BASE:DS0100H 汇编后,程序存储器从标号BASE为首地址开始,空出256个存储单元,以备另用。 7.定义标号值伪指令——DL 格式:〈标号:〉DL〈表达式〉 其含义是定义该标号的值为表达式值,同样,标号和表达式是不可缺少的。 例如: COUNT1:DL 2300H ;定义COUNT1=2300H COUNT2:DL COUNT1+1 ;定义COUNT2=2300H+1 由上可见,DL和EQU的功能都是将表达成值赋给标叼,但两者有区别,用DL语句可在同一源程序中对同一标号多次赋值,即可更改已定义的标号值;而用EQU语句则只能给标号一次赋值,而后在整个源程序中再不能更改
4.2 单片机汇编语言程序的结构形式 一、程序结构的三种形式 1.三种形式 顺序结构、分支结构、循环结构 2.汇编语言程序设计步骤: ◆分析问题 ◆确定算法 ◆设计程序流程图 ◆分配内存单元 ◆编写汇编语言源程序 ◆调试程序
4.2 单片机汇编语言程序的结构形式 二、顺序程序 简单结构程序又称顺序结构程序,是汇编语言程序设计中最基本、最单纯的程序,在整个程序设计所占比例最大,是程序设计的基础。这里所说的简单结构程序是指一种无分支的直接程序,是按照逻辑操作顺序,从第一条指令开始逐步条顺序执行,直到最后一条指令为止。 特点:程序按编写的顺序依次往下执行每一条指令,直到最后一条。
开始 取数据低4位 转换成ASCII码 存ASCII码 取数据高4位 转换成ASCII码 存ASCII码 结束 4.2 单片机汇编语言程序的结构形式 二、顺序程序 【例4.1】 将30H单元内的两位BCD码拆开并转换成ASCII码,存入RAM两个单元中。 程序流程如图4-1所示。参考程序如下: ORG 2000H MOV A,30H ;取值 ANL A,#0FH ;取低4位 ADD A,#30H ;转换成ASCII码 MOV 32H,A ;保存结果 MOV A,30H ;取值 SWAP A ;高4位与低4位互换 ANL A,#0FH ;取低4位(原来的高4位) ADD A,#30H ;转换成ASCII码 MOV 31H,A ;保存结果 SJMP $ END 图4-1
N N 条件满足? 条件满足? Y Y B A A (b) (a) K=? K=0 K=1 … K=n …… A0 A1 An (c) 4.2 单片机汇编语言程序的结构形式 三、分支程序 1.分支程序有三种基本形式,即单分支、双分支、多分支。流程图如图4-2所示。 2.分支程序的设计要点如下: (1)先建立可供条件转移指令测试的条件。 (2)选用合适的条件转移指令。 (3)在转移的目的地址处设定标号。 图4-2 分支程序结构流程图(a)单分支 (b)双分支 (c)多分支
4.2 单片机汇编语言程序的结构形式 三、分支程序 3. 分支程序设计举例 【例4.2】 设X存在30H单元中,根据下式 X+2 X>0 Y = 100 X=0 求出Y值,将Y值存入31H单元。 ∣X∣ X<0 分析:根据数据的符号位判别该数的正负,若最高位为0,再判别该数是否为0。程序流程如图4-3所示。参考程序如下: ORG 1000H MOV A,30H ;取数 JB ACC7,NEG ;负数,转NEG JZ ZER0 ;为零,转ZER0 ADD A,#02H ;为正数,求X+2 AJMP SAVE ;转到SAVE,保存数据 ZER0:MOV A,# 64H ;数据为零,Y=100 AJMP SAVE ;转到SAVE,保存数据
开始 取数,A←(30H) A为负数? N Y A=0? A←64H N A←|X| A←X+2 存数,(31H)←A(30H) 结束 4.2 单片机汇编语言程序的结构形式 三、分支程序 NEG: DEC A ; CPL A ;求∣X∣ SAVE: MOV 31H,A ;保存数据 SJMP $ ;暂停 END 图4-3
4.2 单片机汇编语言程序的结构形式 三、分支程序 【例4.3】设有两个16位无符号数NA,NB分别存放在8031单片机内部RAM的40H、41H及50H、51H单元中,当NA > NB时,将内部RAM的42H单元清0;否则,将该单元置成全1,试编程。 分析:因为无16位数的比较指令,所以,只能用8位数的比较指令。参考程序如下: ORG 2000H CMP:MOV A,50H CJNE A,40H,CMP1 MOV A,51H CJNE A,41H,CMP1 SJMP NHIGHE CMP1:JC HIGHE NHIGHE:MOV 42H,#0FFH SJMP DONE HIGHE:MOV 42H,#00H DONE:SJMP $ END
4.2 单片机汇编语言程序的结构形式 四、循环程序 顺序程序、分支程序的共同点是每条指令至多执行一次,而实际中有时要求某程序段多次重复执行,就需要采用循环结构。 1.循环程序的结构 循环程序一般由四个主要部分组成: 初始化部分: 为循环程序做准备, 如规定循环次数、 给各变量和地址指针预置初值。 处理部分: 为反复执行的程序段, 是循环程序的实体, 也是循环程序的主体。 循环控制部分: 这部分的作用是修改循环变量和控制变量, 并判断循环是否结束, 直到符合结束条件时, 跳出循环为止。 结束部分: 这部分主要是对循环程序的结果进行分析、 处理和存放。
开始 开始 结束 初始化 初始化 修改循环参数 循环体 Y 循环结束? 修改循环参数 N 循环结束? 循环体 N Y 结束部分 结束部分 结束 (b) 直到型循环结构 (a) 当型循环结构 4.2 单片机汇编语言程序的结构形式 四、循环程序 1.循环程序的结构 图4-4 循环结构程序流程图
4.2 单片机汇编语言程序的结构形式 四、循环程序 2. 循环程序设计举例 【例4.4】已知片外RAM的10H单元存放8位二进制数,要求将其转移成相应的ASCII码,并以高位在前,低位在后的顺序,依次存放到片外RAM以11H为首地址的连续单元中,试编程。 分析:先将中间单元置成30H,然后判欲转换位是否为1,若是,则将中间单元内容加1;否则,中间单元内容保持不变。通过左移指令实现由高到低的顺序进行转换。参考程序如下: ORG 1000H START:MOV R2,#08H ;循环计数初值(循环次数已知) MOV R0,#10H ;地址指针初值 MOVX A,@R0 ;取数 MOV B,A ;暂存B中 LOOP:MOV A,#30H ;将中间单元(A)置成30H
4.2 单片机汇编语言程序的结构形式 四、循环程序 2. 循环程序设计举例 JNB B.7,NA ;判断转换的二进制位为0否?若是转NA INC A ;若为1,则(A)内容加1,成为 ;1的ASCII码“31H” NA:INC R0 ;修改地址指针 MOVX @R0,A ;存放转换的结果 MOV A,B RL A,B ;作好准备,判断下一位 MOV B,A ;暂存 DJNZ R2,LOOP ;判断转换结束否?未完继续 SJMP $ END
4.2 单片机汇编语言程序的结构形式 四、循环程序 2. 循环程序设计举例 【例4.5】设用户用键盘输入长度不超过100字节的字符串放在8031单片机外部RAM以20H为首地址的连续单元,该字符串用回车符CR(‘CR’= 0DH)作为结束标志,要求统计此字符串的长度并存入内部RAM的1FH单元中。 分析:从首单元开始取数,每取一数判断其是否为‘CR’,是则结束。参考程序如下: ORG 1000H STADA DATA 20H SLANG DATA 1FH CMCR2:MOV R0,#STADA-1 MOV B,#0FFH CRLOP:INC R0 INC B MOVX A,@R0 CJNE A,#0DH,CRLOP MOV SLANG,B SJMP $ END
外循环 外循环 外循环 中循环 内循环 内循环 内循环 内循环 (c)交叉不正确 (b)嵌套正确 (a)嵌套正确 4.2 单片机汇编语言程序的结构形式 四、循环程序 3.多重循环结构程序 某些复杂问题或者循环数超过256,则需采用多重循环的程序结构,即循环程序中包含循环程序或一个大循环中包含多个小循环程序,称多重循环程序结构,又称循环嵌套。循环的重数不限,但必须每循环的层次分明,不能有相互交叉! 图4-5 多重循环示意图
4.2 单片机汇编语言程序的结构形式 四、循环程序 【例4.6】设在8031内部RAM中存一无符号数的数组,其长度为100,起始地址是30H,要求将它们从大到小排序,排序后仍存放在原区域中,试编程。 分析: 内RAM 第一次循环 第二次循环 ······ 30H 0 0 0 3 0 6 31H 0 3 0 6 0 3 大 32H 0 6 0 2 8 0 数 33H 0 2 8 0 0 4 向 · · · · 上 100个 · · · · ······ 冒 · · · · 90H 3 5 7 6 2 4 91H 7 6 2 4 6 0 92H 2 4 6 0 0 1 93H 6 0 0 0 0 0 最多99次循环 这就是所谓的“冒泡法”。实际上大多情况,用不到99次循环,排序就结束。为了提高排序速度,程序中可设一交换标志位,如10H位,每次循环中:若有交换则 SETB 10H;若无交换则 CLR 10H。每次循环结束时,测10H位,判断排序是否结束。参考程序如下:
4.2 单片机汇编语言程序的结构形式 四、循环程序 ORG 1000H BUBBLE:MOV R0,#30H MOV B,#64H CLR 10H DEC B ;长度计数 LOOP:MOV A,@R0 MOV 20H,A ;暂存,为交换作准备 INC R0 MOV 21H,@R0 CJNE A,21H,BUEU ;若(20H)≠(21H)转移 BUEU:JNC BUNEXT ;(20H)≥(21H)转移 MOV A,@R0 ;若(20H)< (21H)则交换 MOV @R0,20H DEC R0 ;使R0退格指向小地址 MOV @R0,A INC R0 ;恢复R0指向大地址 SETB 10H ;置交换标志 BUNEXT: DJNZ B,LOOP JB 10H,BUBBLE ;判断标志位为1否?若为1,则继续 END
4.3 MCS-51单片机汇编语言程序设计举例 一、多字节数加法 1.多字节无符号数加法 CLR C MOV R0,#40H ;指向加数最低位 MOV R1,#5OH ;指向另一加数最低位 MOV R2,#04H ;字节数作计数初值 LOOP1:MOV A,@R0 ;取被加数 ADDC A,@R1 ;两数相加,带进位 MOV @R0,A INC R0 ;修改地址 INC R1 DJNZ R2,LOOPl ;未加完转LOOP1 JNC LOOP2 ;无进位转LOOP2 MOV @R0,#01H LOOP2:DEC R0 RET
4.3 MCS-51单片机汇编语言程序设计举例 一、多字节数加法 2.多字节有符号数加法 SDADD:CLR 07H ;标志位清零 MOV A,R0 ;复制保存地址指针 MOV R2,A MOV A,R3 MOV R7,A CLR C LOOP1:MOV A,@R0 ADDC A,@R1 ;相加 MOV @R0 ,A INC R0 INC R1 ;地址指针加1 DJNZ R7,LOOP1 图 4-6 多字节有符号数加法程序流程图
4.3 MCS-51单片机汇编语言程序设计举例 一、多字节数加法 2.多字节有符号数加法 JB OV,ERR ;若溢出,转溢出处理 DEC R0 MOV A,@R0 JNB E7H,LOOP2 SETB 07H ;和值为负,置位标志 LOOP2:MOV A,R2 ;恢复地址指针 MOV R0,A RET ┇ ERR: ┇ ;溢出处理 RET
4.3 MCS-51单片机汇编语言程序设计举例 二、多字节数减法 MOV R0,#40H ;指向被减数最低位 MOV R1,#5OH ;指向减数最低位 MOV R2,#04H ;字节数 CLR C LOOP1:MOV A,@R0 SUBB A,@R1 ;完成一个字节的减法运算 MOV @R0,A INC R0 INC R1 DJNZ R2,LOOP1 RET
4.3 MCS-51单片机汇编语言程序设计举例 三、多字节十进制数(BCD码)加法 BCDADD:MOV 20H,R0 MOV 23H,R3 CLR C LOOP0: MOV A,@R0 ;取被加数 ADDC A,@R1 ;两数相加 DA A ;十进制调整 MOV @R0,A INC R0 ;指针加1 INC R1 DJNZ R3,LOOP0 ;作完加法否 MOV R2. #23H JNC RETURN ;有无进位 MOV@ R0,#01H INC R3 RETURN:MOV R0,#20H RET 图 4-7 BCD码多字节加法程序流程图
4.3 MCS-51单片机汇编语言程序设计举例 四、多字节数乘法 ZHENFA: MOV A,R0 MOV B,R1 MUL AB ;(R1)*(R0) MOV R3,A ;积的低位送到R3 MOV R4,B ;积的高位送到R4 MOV A,R0 MOV B,R2 MUL AB ;(R2)*(R0) ADD A,R4 ;(R1)*(R0)的高位加(R2)*(R0)的低位 MOV R4,A ;结果送R4,进位在CY中 MOV A,B ADDC A,#OOH ;(R2)*(R0)的高位加低位来的进位 MOV R5,A ;结果送R5 RET
4.3 MCS-51单片机汇编语言程序设计举例 五、多字节数除法 DV : MOV R7,#08H ;设计数初值 DVl: CLR C MOV A,R5 RLC A MOV R5,A MOV A,R6 RLC A ;将(R6)、(R5)左移一位 MOV 07H,C ;将移出的一位送07H位保存 CLR C SUBB A,R2 ;余数(高位)减除数 JB O7H,GOU ;若标志位为1,说明够减 JNC GOU ;无借位也说明够减 ADD A,R2 ;否则,恢复余数 AJMP DV2 GOU: INC R5 ;商上1 DV2: MOV R6,A ;保存余数(高位) DJNZ R7,DVl RET 图 4-8 除法程序流程图
4.3 MCS-51单片机汇编语言程序设计举例 六、数据的拼拆 【例4.7】设在30H和31H单元中各有一个8位数据: (30H)=x7x6x5x4x3x2x1x0 ,(31H)=y7y6y5y4y3y2y1y0 现在要从30H单元中取出低5位,并从31H单元中取出低3位完成拼装,拼装结果送40H单元保存,并且规定: (40H)=y2y1y0x4x3x2x1x0 分析:利用逻辑指令ANL、ORL来完成数据的拼拆,参考程序如下: MOV 40H,30H ;将x7~x0传送到40H单元 ANL 40H,#000111llB ;将高3位屏蔽掉 MOV A,31H ;将y7~y0传送到累加器中 SWAP A ;将A的内容左移4次 RL A ;y2~y0移到高3位 ANL A,#111000OOB ;将低5位屏蔽掉 ORL 40H,A ;完成拼装任务
4.3 MCS-51单片机汇编语言程序设计举例 七、数据的转换 1.ASCII码与二进制数的互相转换 【例4.8】编程实现十六进制数表示的ASC1I代码转换成4位二进制数(1位十六进制数)。 分析:对于这种转换,只要注意到下述关系便不难编写出转换程序: “字符0”~“字符9”的ASCII码值为“30H”~“39H”,它们与30H之差恰好为“00H”~“09H”,结果均<0AH。 “字符A”~“字符F”的ASCII码值为“41H”~“46H”,它们各自减去37H后恰好为“0AH”~“0FH”,结果均>0AH。 根据这个关系可以编出转换程序如下,程序以R1作为入口和出口。 ASCHIN: MOV A,R1 ;取操作数 CLR C ;清进位标志位C SUBB A,#30H ;ASCII码减去30H,实现0-9的转换 MOV R1,A ;暂存结果 SUBB A,#0AH ;结果是否>9? JC LOOP ;若≤9则转换正确 XCH A,R1 SUBB A,#07H ;若>9则减37H MOV R1,A LOOP: RET
4.3 MCS-51单片机汇编语言程序设计举例 七、数据的转换 2.BCD码与二进制数的转换 【例4.9】4位BCD码整数转换成二进制整数 入口参数:BCD码字节地址指针R0,位数存于R2中。 出口参数:二进制数存于R3R4中。 算法:A=103a3+102a2+10a1+a0。 参考程序如下: BCDA:PUSH PSW ;现场保护 PUSH A PUSH B MOV PSW,#08H MOV R3,#00H MOV R2,#3 ;BCD码D的位数 MOV A,@R0 ; a0-R4 MOV R4,A BCKB:MOV A,R3 ;(R3R4)×10 MOV B,#10 ;R4 MUL AB MOV R4,A XCH A,B
4.3 MCS-51单片机汇编语言程序设计举例 七、数据的转换 2.BCD码与二进制数的转换 MOV B,#10 XCH A,R3 MUL AB ADD A,R3 XCH A,R4 INC R0 ;(R0)+1-R0 ADD A,@R0 ;( R3R4)- ((R0))-RR3R4 XCH A,R4 ADDC A,#0 MOV R3,A DJNZ R2,BCDB ;循环n-1次 POP B ;恢复现场 PIP A POP PSW RET ;返回 上例中的R2内容是BCD码的位数n,本例中n=4,即两个字节4位BCD码,在程序中作为循环控制寄存器的计数值为n-1=4-1=3,即本例循环3次即完成二次字节的BCD码转换。本例采用乘10运算,也可采用除2运算进行转换。
4.3 MCS-51单片机汇编语言程序设计举例 八、查表程序 使用MOVC A,@A+DPTR指令来查表,程序清单如下: MOV DPTR,#BS ;子程序入口地址表首址 RL A ;键码值乘以2 MOV R2,A ;暂存A MOVC A,@A+DPTR ;取得入口地址低位 PUSH A ;进栈暂存 INC A MOVC A,@A+DPTR ;取得入口地址高位 MOV DPH,A POP DPL CLR A JMP @A+DPTR ;转向键处理子程序 BS: DB RK0L ;处理子程序入口地址表 DB RK0H DB RK1L DB RK1H DB RK2L DB RK2H ┇ ┇