1、第四章 汇编语言程序设计,高级语言如C+,汇编语言如MCS-51指令,汇编,目标文件,按照语法格式编写源程序*.ASM *.C,按照语法格式将源程序翻译成机器代码,计算机识别的二进制代码*.OBJ,编译,目标文件,本章结构,4.1 单片机程序设计语言概述 4.5 单片机汇编语言伪指令 4.4 汇编语言编辑和汇编 4.2 汇编语言程序的基本结构形式 顺序程序结构 分支程序结构 循环程序结构 4.3 汇编语言程序设计举例,一、 程序设计语言及语言处理程序,程序设计语言分:机器语言、汇编语言和中高级语言1.机器语言:(上KEIL仿真器,看反汇编界面) 硬件识别,二进制,无需翻译、直接执行,面向机器;
2、 速度快,效率高,难以辨认和记忆,易错,难修改。,4.1 概述,地址 机器码 源程序 ORG 2000H 2000H 78 30 MAIN: MOV R0,#30H2002H E6 MOV A,R0,2.汇编语言:由字母,数字符号组成,翻译成机器语言再由CPU执行,面向机器,编译后执行速度接近机器语言,易读,不易错,但必须熟悉指令系统,移植性差;程序精细、具体,结构紧凑,运行时间精确,高效。运算量大,实时性要求高时常用汇编。,地址 机器码 源程序 ORG 2000H 2000H 78 30 MAIN: MOV R0,#30H2002H E6 MOV A,R0,3.中高级语言: 面向过程和面向对
3、象。参照数学语言又类似日常会话语言。高级语言中,一条高级语言指令,代替几上百条汇编指令。直观,易学,便于移植(由编译器负责),也需经过编译、解释成机器代码后执行。C、BASIC、C,4.1.3、汇编语言特点及其格式 P77,1、汇编语言的语句格式标 号:操作码 操作数 ;注释BEGIN:MOV A,#50H ;将立即数50H给A1)标 号:用户定义的符号地址,便于查询和修改程序,在汇编时自动生成与该语句翻译成机器码存放在ROM单元地址相对应的16bit数。ORG 0000H ;伪指令定义起始地址LJMP MAIN ;跳转至主程序ORG 0030H MAIN: MOV A,#0F0H ;主程序入
4、口 ,4.1.3、汇编语言特点及其格式 P77,1、汇编语言的语句格式标 号:操作码 操作数 ;注释BEGIN:MOV A,#50H ;将立即数50H给A 1) 标号命名规定: 18个ASCII码,首字符为字母; 不可用已经定义的符号作为标号,如助记符等; 标号后跟着冒号“:”; 同标号在一个程序只能定义一次; 标号可以省略不用,指令前是否有标号取决于本程序其他语句是否要访问此指令。,4.1.3、汇编语言特点及其格式 P77,1、汇编语言的语句格式标 号:操作码 操作数 ;注释BEGIN:MOV A,#50H ;将立即数50H给A 1) 标号举例:错误的标号 正确的标号1BT: LooP2:B
5、EGIN STAB:TB+5T: TAB_CE:ADD: Q: 2) 操作码:规定指令所执行的操作,汇编指令中不可缺少的部分,在汇编时自动生成机器码。,4.1.3、汇编语言特点及其格式 P77,1、汇编语言的语句格式标 号:操作码 操作数 ;注释BEGIN:MOV A,#50H ;将立即数50H给A3)操作数:是参加运算的数据或者数据的地址。通常有单操作数、双操作数和无操作数三种情况。如果是双操作数,则操作数之间,要以逗号隔开。(1)十六进制、二进制和十进制形式的操作数表示(注意后缀)十六进制,后缀“H” ;二进制,后缀“B”;十进制,后缀“D”,也可省略。若十六进制的操作数以字符AF中的某个
6、开头时,则需在它前面加一个 “0”,以便在汇编时把它和字符AF区别开来。,4.1.3、汇编语言特点及其格式 P77,1、汇编语言的语句格式标 号:操作码 操作数 ;注释BEGIN:MOV A,#50H ;将立即数50H给A3)操作数: (2)工作寄存器和特殊功能寄存器的表示采用工作寄存器和特殊功能寄存器的代号来表示,也可用其地址来表示。 例如,累加器可用A(或ACC)表示。也可用0E0H来表示,0E0H为累加器A的地址。 (3)美元符号$的使用用于表示该转移指令操作码所在的地址。例如,如下指令:JNB F0, $与如下指令是等价的:HERE:JNB F0,HERE,4.1.3、汇编语言特点及其
7、格式 P77,1、汇编语言的语句格式标 号:操作码 操作数 ;注释BEGIN:MOV A,#50H ;将立即数50H给A4)注 释:解释说明,增加可读性,汇编时不产生任何机器码 5)分界符:冒号“:”:用于标号之后。空格“ ”:用于操作码和操作数之间。逗号“,”:用于操作数之间。分号“;”:用于注释之前。,一、 汇编语言语句的种类和格式,汇编语言语句包含两种基本类型:指令语句 和 伪指令语句 1.指令语句: (前面已经讲解) 每一条指令语句在汇编时都产生一个指令代码机器代码 2.伪指令语句: (后面讲解) 是为汇编服务的。在汇编时没有机器代码与之对应。,4.5 单片机汇编语言伪指令 P93页,
8、地址 机器码 源程序 无代码对应 ORG 2000H 2000H 78 30 MAIN: MOV R0,#30H2002H E6 MOV A,R0,二、汇编语言伪指令1、ORG:起始伪指令Origin,指明程序和数据块起始地址。指令地址 机器码 源程序 ORG 2000H 2000H 78 30 MAIN:MOV R0,#30H2002H E6 MOV A,R0ORG 3000H3000H 23 DB 23H,100,A 3001H 643002H 41,2、END 汇编结束伪指令。 P94例:START: END 3、EQU 赋值伪指令。为标号或标识符赋值Equate X1 EQU 2000
9、H X2 EQU 0FH MAIN: MOV DPTR,#X1 ADD A,#X2,P95 4、 DB 定义字节伪指令。Define Byte 8bit 例 : DB 12H,100,A存储: 00010010,01100100,010000015、 DW 定义双字节伪指令。Define Word 16bit 例 : DW 2030H,8CH ,“AB”存储:00100000 00110000 00000000 1000110001000001 01000010,P95 6、DS 定义存储区伪指令 DEFINE STORAGE从指定地址开始保留指定数目的字节单元备用。7、BIT 位定义伪指令把
10、一个可位寻址的位单元赋值给所规定的字符名称,一、 什么叫编辑和汇编,1.编辑:编写程序的过程叫编辑,编写完的程序存成的文件叫源文件。用汇编语言编写的程序,叫汇编语言源程序,存成“.ASM”类型的文件汇编源文件。2.汇编:汇编语言源程序“翻译”成机器代码的过程,称为“汇编” 。需要汇编的原因汇编语言无法被单片机识别并运行。,4.4 汇编语言源程序的 编辑和汇编 P91,二、 手工汇编,人工查表翻译指令。但遇到的相对转移指令的偏移量的计算,要根据转移的目标地址计算偏移量,不但麻烦,且容易出错。,4.4 汇编语言源程序的 编辑和汇编 P91,用编辑软件进行源程序的编辑。编辑完成后,生成一个ASCII
11、码文件,扩展名为“.ASM”。然后在微计算机上运行汇编程序,把汇编语言源程序翻译成机器代码。 交叉汇编汇编后的机器代码是在另一台计算机(这里是单片机)上运行。,三、 机器汇编与交叉汇编,四、 单片机软件设计,MCS-51单片机的应用程序的完成,应经过三个步骤; (1)在微计算机上,运行编辑程序进行源程序的输入和编辑; (2)对源程序进行交叉汇编得到机器代码; (3)通过微计算机的串行口(或并行口)把机器代码传送到用户样机(或在线仿真器)进行程序的调试和运行。,4.4 汇编语言源程序的 编辑和汇编 P91,单片机软件设计三步曲: 机器编辑交叉汇编串行传送(过程图见教材92页),单片机的开发过程,
12、程序设计基本方法,在能完成规定的功能任务基础上还要求:执行速度快、占用内存少、条理清晰、阅读方便、便于移植、巧妙而实用。 步骤: 1分析问题、确定算法、分配存储单元 2画出程序流程图 3编写汇编语言源程序 4汇编并调试程序,流程图符号和说明:,4.2 汇编程序的基本结构,顺序程序结构 分支程序结构 单分支程序结构 多分支程序结构 循环程序结构 另外,再加上广泛使用的子程序和中断服务子程序。,汇编程序基本结构流程,4.2.1 顺序程序结构,是汇编语言程序的最简单也是最基本的程序结构。程序执行时一条接一条地按顺序执行指令,无分支、循环以及调用子程序。ORG 0000HLJMP MAINORG 00
13、30H MAIN: MOV A , #30HADD A , #58HMOV 30H , ASJMP $,顺序程序结构分析:找出关键的执行实际功能操作的指令,然后将其前面与该指令相关的指令规类为该指令的前期配置指令来分析。需要对指令占用的资源和操作的影响有全局的把握。 MOV R0,#52H DEC R1 MOV A,R0 MOV R1,#55H MOV A,R0 ADDC A,R1 MOV A,R0 ADDC A,R1 MOV R0,A ADD A,R1 MOV R0,A MOV 20H,C MOV R0,A DEC R0 DEC R0 DEC R1,4.2.2 分支程序结构,程序分支是通过转
14、移指令实现的,也称为选择结构。可分为单分支和多分支两类。 单分支程序结构,通过条件转移指令实现,即根据条件对程序的执行进行判断、满足条件则进行程序转移,不满足条件就顺序执行程序。可用指令JZ、JNZ、CJNE、DJNZ;JC、JNC、JB、JNB、JBC。,图4-2-2 分支程序结构流程图,多分支程序是首先把分支程序按序号排列,然后按序号值进行转移。指令:JMP A+DPTR,1、单分支程序结构,在MCS-51指令系统中,通过条件判断实现单分支程序转移的指令有:JZ、JNZ、CJNE、DJNZ等。此外还有以位状态作为条件进行程序分支的指令,如JC、JNC、JB、JNB、JBC等。使用这些指令可
15、以完成0、1、正、负,以及相等、不相等作为各种条件判断依据的程序转移。多重单分支结构是单分支的扩展形式,通过一系列条件判断,进行逐级分支。,程序分析题:书P80页例子,先不看题意分析功能。 START: CLR C ;9.为实现无借位减法MOV DPTR ,#ST1;4.DPTR初值为ST1MOVX A , DPTR ;8.A从DPTR得到,(ST1)MOV R2 , A ;7.R2为A复制INC DPTR ;3.DPTR+1后的值 5.为ST2MOVX A , DPTR ;2.A从DPTR得到 6.A=(ST2) SUBB A , R2 ;1.看到减法 A-R2;10.为(ST2)-(ST1
16、)JNC BIG1 ;11.判转分支(条件C!=0)XCH A , R2 ;A1. C=0,A放大数(ST1) BIG0: INC DPTR ;A2.B3. DPTR+1,为ST3MOVX DPTR , A ;A3.B4. 存A(大数)入ST3RET ; 子程序返回 BIG1: MOVX A , DPTR ;B1. C!=0,A放大数(ST2)SJMP BIG0 ;B2. 转至BIG0,例题:已知X、Y均为8位二进制有符号数,分别存在30H31H中,试编制能实现下列符号函数的程序:,有符号数(补码形式): 1000 0000b为128 1111 1111b为1 0000 0001b为1 011
17、1 1111b为127,实现程序如下:,2.多分支程序结构,常使用JMP A+DPTR指令 1.JMP A+DPTR 与数据表配合:数据表存相对地址,范围有限,256字节。 2.JMP A+DPTR 与转移指令配合:A中值为序号与转移指令字节数的乘积。 3.利用RET指令,通过堆栈操作实现:将分支地址从入口地址表取出后,压入堆栈,利用RET指令赋予PC分支地址。,1.JMP A+DPTR 与数据表配合,执行完JMP指令,直接就跳转至分支程序。 MOV A , #n;n为分支程序序号MOV DPTR , # JMPTABMOVC A , A+DPTRJMP A+DPTR JMPTAB: DB R
18、OUT00JMPTABDB ROUT01JMPTAB DB ROUTn JMPTAB,2.JMP A+DPTR 与转移指令配合 例: 128种分支转移程序。 功能:根据入口条件转移到128个目的地址。 入口:(R3)=转移目的地址的序号00H7FH。 出口:转移到相应子程序入口。执行完JMP指令,程序跳转至分支入口表后再次跳转。,说明:此程序要求128个转移目的地址(ROUT00 ROUT7FH)必须驻留在与绝对转移指令AJMP相同的一个2KB存储区内。 RL指令对变址部分乘以2,因为每条AJMP指令占两个字节。,结构示意图,散转指令,转向0分支,转向1分支,转向n-1分支,转向n分支,K=0
19、,K=1,K=n-1,K=n,3.利用RET指令,通过堆栈操作实现,MOV DPTR , #BRTAB BRTAB: MOV A , R0 DW ROUT00 RL A DW ROUT01 MOV R1,A INC A DW ROUT127 MOVC A,A+DPTR PUSH ACC MOV A,R1 MOVC A,A+DPTR PUSH ACC RET分支程序入口地址压入堆栈,再利用返回指令将存入堆栈中的地址赋给PC,从而实现分支程序跳转。,4.2.3 循环程序,在程序运行时,有时需要连续重复执行某段程序,可以使用循环程序。其结构包括四部分:1、置循环初值2、循环体(循环工作部分)3、修改
20、循环参数4、循环控制部分(循环判断)循环程序按结构形式,有单重循环与多重循环。在多重循环中,只允许外重循环嵌套内重循环。不允许循环相互交叉,也不允许从循环程序的外部跳入循环程序的内部。,(b)嵌套正确,(c)交叉不正确,多重循环示意图,循环结构程序流程图,循环结构各部分功能说明,初始化:建立循环初始值,如初始化地址指针,设置循环次数计数器及其他循环参数的起始值等。 循环体:程序中反复要执行的部分。 循环修改:对参加运算的数据或地址指针进行恰当的修改。 循环控制:保证循环程序按规定的循环次数或控制循环的条件进行循环。常用条件转移语句组成,如DJNZ。 结束:处理循环结果,储存结果。,循环程序设计
21、举例 例:有一数据块从片内RAM的30H单元开始存入,设数据块长度为10个单元。根据下式:X+2 X0 Y= 100 X=0 求出Y值,并将Y值放回原处。X-2 X0 解:设置一个计数器控制循环次数,每处理完一个数据,计数器减1。程序流程如图4-8所示。,读程序题: ENTR:MOV R0,#data ;3.初值配置MOV DPTR,#buffer ;3.初值配置MOV R1,#20H ;3.初值配置 LOOP:MOV A,R0 ;4.取数到ACLR C ;4.无借位减法SUBB A,#24H ;4.R024HJZ LOOP1 ;4.条件分支,A=0跳转退出循环。MOV A,R0 ;4.A!=
22、0,操作为R0存入bufferMOVX DPTR,A;4.循环体主操作INC DPTR ;2.控制变量修改INC R0 ;2.控制变量修改DJNZ R1,LOOP;1.找出循环控制语句,确定范围 LOOP1:RET,4.2.4 子程序设计,一、子程序设计原则和应注意的问题一种能完成某一特定任务的程序段。其资源要为所有调用程序共享。因此,子程序在结构上应具有独立性和通用性,在编写子程序时应注意以下问题:1子程序的第一条指令的地址称为子程序的入口地址。该指令前必须有标号。2主程序调用子程序两条子程序调用指令:(1)绝对调用指令:ACALL addr11(2)长调用指令:LCALL addr16(后
23、续),4.2.4 子程序设计,3注意设置堆栈指针和现场保护 (接上) 4最后一条指令必须是RET指令 5子程序可以嵌套,即子程序可以调用子程序 6在子程序调用时,还要注意参数传递的问题 子程序的基本结构MAIN: ;MAIN为主程序或调用程序标号 SUB:PUSH PSW ;现场保护LCALL SUB ;调用子程序 PUSH ACC ; 子程序处理程序段POP ACC ;现场恢复 POP PSW ;RET ;最后一条指令必须为RET,4.3 应用程序设计举例,一、运算类程序在MCS-51 指令系统中,给出了单字节的加、减、乘、除算术运算指令。但实际应用中还常用到双字节及多字节的算术运算程序。下
24、面通过例子分析多字节算术运算程序的编写方法。(均是以子程序形式给出),(1)多字节无符号数加法程序例题:设被加数低位地址由R0指出,加数低位地址由R1指出,字节数在R2中,运算结果的和数依次存入原被加数单元,最高进位位存入用户标志F0解题思路:抽象简化题目为,R0取被加数,R1取加数,结果存回R0,R2次进位相加后,F0存放最终进位CY。从低位开始,每个字节执行带进位相加,直到循环完R2个字节(用循环程序编写)。 入口:R0,R1,R2 出口:从R0开始的R2 个字节 核心指令: ADDC 循环控制 DJNZ R2,rel,MBADD: PUSH 02HPUSH ACCCLR C ADD1:
25、MOV A,R0ADDC A,R1MOV R0,AINC R0INC R1DJNZ R2,ADD1MOV F0,C POP ACCPOP 02HRET,;保留被加数地址,;清进位标志CY,;做带进位加法 ;存入部分和,;修改指针,;恢复和数的低位地址,;保存,(2)多字节十进制加法程序条件同上例 解题思路:与多字节无符号数加法子程序一样,从低位字节开始,每个字节执行带进位相加,直到执行完R2个字节。不同的是,执行完加法后还要进行十进制调整。 程序参上,(3)多字节二进制乘法程序例 见书P85页解题思路:MUL只是单字节乘法,多字节乘法就要按照乘法式子来做,分解成多个单字节的乘加运算。但要注意处
26、理部分积相加产生的进位。 (4)多字节二进制除法程序 (思考)例 见书P86页解题思路:DIV只是单字节除法,多字节除法就利用移位相减来实现。,二、定时程序 (1)单循环定时程序 (单片机频率为6MHz) 例 MOV R5,#TIME LOOP: NOP ;单周期指令NOPDJNZ R5,LOOP ;双周期指令分析,循环体程序(包括判转指令)共4机器周期。假设单片机频率为6MHz,则可算出1个机器周期为12/6=2s,所以一次循环时间为8s,总共则为TIME*8s。,二、定时程序 (2)多重循环定时程序(单片机频率为6MHz) 例 MOV R5,#TIME1LOOP2: MOV R4,#TIM
27、E2 ;单周期指令LOOP1: NOP ;单周期指令NOPDJNZ R4,LOOP1 ;双周期指令DJNZ R5,LOOP2 ;双周期指令RET 公式: 循环体时间=(TIME2*4+2+1)*TIME1*2s总时间=循环体时间+4s,三、查表程序 (1)查表指令MOVC A,A+DPTR ;变址寻址MOVC A,A+PC 对比记忆:相同点:访问程序空间仅有的2个指令。A为变址寄存器,又为目的操作数。不同点:DPTR可以预先赋初始值,并可以修改。但PC值为当前指令下一条指令的地址值。所以两者范围不同,前者为64K,后者256。,三、查表程序 (2)查表程序设计 查表程序具有数据补偿、修正、计算
28、、转换等各种功能,具有程序简单、执行速度快等优点。查表就是根据自变量x,在表格中寻找y,使y=f(x)。对于单片机程序而言,自变量x放在A中,表格存放在程序空间里,DPTR指向表格首字节,使用MOVC语句来找寻Y。,三、查表程序 (3)查表例程例:子程序的功能为:根据累加器A中的数x(09之间)查x的平方表y,根据x的值查出相应的平方y。x和y均为单字节数。地 址 子程序2000h SQR: ADD A,#01H2002h MOVC A,A+PC2003h RET2004h DB 00H,01H,04H,09H,10H DB 19H,24H,31H,40H,51H关键在表格,注意表格内每个数据
29、占的字节数。(思考:用MOVC A,A+DPTR改写),三、查表程序 (3)查表例程例:子程序的功能为:根据累加器A中的数x(09之间)查x的平方表y,根据x的值查出相应的平方y。x和y均为单字节数。地 址 子程序2000h SQR: ADD A,#01H2002h MOVC A,A+PC2003h RET2004h DB 00H,01H,04H,09H,10H DB 19H,24H,31H,40H,51H关键在表格,注意表格内每个数据占的字节数。(思考:用MOVC A,A+DPTR改写),三、查表程序例:根据存放在A中的按键码,跳至键处理子程序入口。P91MOV DPTR,#BS BS:DB
30、 RK0LRL A DB RK0HMOV R2,A DB RK1LMOVC A,A+DPTR DB RK1HPUSH ACC DB RK2LMOV A,R2 DB RK2HINC A DB RK3LMOVC A,A+DPTR DB RK3HMOV DPH,ACC 子程序入口地址表POP DPLCLR AJMP A+DPTR,四、代码转换类程序 (1)二进制数与BCD码之间的转换根据定义,采用“除十留余”的方法。或者采用“DA A”方式处理,“9”就“+6”。 (2)二进制码与ASCII码之间的转换多采用查表法实现。,例 单字节二进制数(0FFH)转换为双字节BCD数(0255) 入口:A二 进
31、 制 数 出口:存入R0所指定的单元 占用资源:A、B、R0 BINBCD: MOV B,#100 DIV AB ;A=百位数MOV R0,A ;INC R0 ;MOV A,#10 ;XCH A,B ;DIV AB ;A=十位数;B=个位数SWAP A ;十位移到高半字节ADD A,B ;形成十位和个位压缩的BCD码MOV R0,A RET,例 ASCII码转换为十六进制数解:小于等于9的数的ASCII码减去30H得到这个十六进制数,大于9的数的ASCII码减去37H得到对应的十六进制数 ASCHIN:MOV A,R2 ;取操作数CLR C ;清进位标志位CSUBB A,#30H ;ASCII
32、码减去30H,实现0-9的转换MOV R2,A ;暂存结果SUBB A,#0AH ;结果是否9?JC LOOP ;若9则转换正确MOV A,R2SUBB A,#07H ;若9则减37HMOV R2,A LOOP: RET,五、数据排序检索类程序 (1)数据极值查找简单的循环程序。 CJNE 配合JNC指令。 (2)数据检索类循环结构中搭配分支结构。 (3)数据排序类采用冒泡法。,数据极值查找程序 例 内部RAM 20H单元开始存放8个数,找出其中的最大值。 假定在比较过程中,以A存放大数,与之逐个比较的另一个数放在2AH单元中。比较结束后,把查找到的最大数送到2BH单元中。ORG 0000HL
33、JMP STARTORG 0030H START: MOV R0,#20HMOV R7,#07HMOV A,R0 LOOP: INC R0MOV 2AH,R0CJNE A,2AH,CHK CHK: JNC LOOP1MOV A,R0 LOOP1: DJNZ R7,LOOPMOV 2BH,ASJMP $,数据检索程序 例 假定数据区首地址是内部RAM 20H,数据区长度为8,关键字放在2BH单元,把检索成功的数据序号放在2CH单元中。程序运行结束后,如2CH=00H,表示没有检索到关键字;否则即为检索成功。 MOV R0,#20HMOV R7,#08HMOV R2,#00HMOV 2BH,#KE
34、Y NEXT: INC R2CLR CMOV A,2BHSUBB A,R0JZ ENDPINC R0DJNZ R7,NEXTMOV R2,#00H ENDP: MOV 2CH,R2SJMP $,数据排序程序例 假定8个数据连续存放在30H为首地址的内部RAM单元中,使用冒泡法进行升序排序编程。设R 7为比较次数计数器,初始值为07H。F0为冒泡过程中是否有数据互换的状态标志、F00,表明无互换发生,F01表明有互换发生。ORG 0000HLJMP STARTORG 0030H START: MOV R0,#30H MOV R0,20HMOV R7,#07H DEC R0CLR F0 MOV R0,21H LOOP: MOV A,R0 INC R0MOV 20H,A SETB F0INC R0 NEXT: DJNZ R7,LOOPMOV 21H,R0 JB F0, STARTCLR C SJMP $SUBB A,R0JC NEXT,