1、,单片机原理及应用,主讲:禹定臣,信息工程系,4.1 汇编语言程序设计概述,汇编语言的特点及其语句格式 汇编语言程序设计的特点,汇编语言的特点及其语句格式,以助记符表示的指令称为汇编语言 1.汇编语言的特点 *占用存储空间小,运行速度快。 *汇编语言是面向计算机的,程序设计人员必须对计算机硬件有相当的了解。 *能直接管理和控制硬件设备。 *缺乏通用性,不易移植,编写较困难。 2.汇编语言的语句格式 : ; 1)标号:语句地址的标志符号,标号由18个ASCII字符组成,第一个字符必须是字母。 不能使用本汇编语言已经定义了的符号作为标号,如指令助记符、伪指令以及寄存器的名称等。 标号后面必须跟冒号
2、。 同一标号在一个程序中只能定义一次,不能重复定义。 没有其它语句访问时,标号可以省略。2)操作码:规定语句执行的操作是汇编指令中唯一不能空缺的 3)操作数:给指令的操作提供数据或数据所在的地址 操作数的数量03个。多于一个时,操作数之间用逗号分隔。,4)注释:不属于语句的功能部分,便于阅读程序。 以分号开始,长度不限,另起一行时也必须以分号开始。 5)分隔符 *冒号(:) 用于标号后 *空格( ) 用于操作码和操作数之间 *逗号(,) 用于操作数之间 *分号(;) 用于注释前,数据的存放、寄存器和工作单元的使用等要由设计者安排。 要求设计人员对所使用计算机的硬件结构有较详细的了解,特别是对各
3、类寄存器、端口、定时器/计数器、中断等内容能熟练掌握,以便在程序设计中使用。 程序设计的技巧性较高,需要软件与硬件的结合。,汇编语言程序设计的特点,顺序程序 分支程序 循环程序,4.2 单片机汇编语言程序的基本结构形式,程序执行时一条一条按顺序执行指令 例 三字节无符号数字节加法 被加数在内部 RAM 52H、51H、50H中(低字节在低地址中),加数在内部RAM 55H、54H、53H中,要求把相加结果存放在52H、51H、50H中,进位存放在位地址区的00H中。 ORG 0000H MOV R0 ,#50H ;被加数首址 MOV R1 ,#53H ;加数首址 MOV A,R0 ;取被加数低
4、字节 ADD A ,R1 ;被加数与加数相加 MOV R0,A ;存低字节相加结果 INC R0 ;调整地址指针,指向中间字节 INC R1,顺序程序,MOV A,R0 ;取被加数中间字节 ADDC A ,R1;被加数与加数带进位(低字节的进位)加 MOV R0,A ;存中间字节相加结果 INC R0 ;调整地址指针,指向高字节 INC R1 MOV A,R0 ;取被加数高字节 ADDC A ,R1 ;被加数与加数带进位相加 MOV R0,A ;存高字节相加结果 MOV 00H,C ;高字节相加的进位位送00H SJMP $ END,1.单分支程序 用条件转移指令实现JZ、JNZ、CJNE、D
5、JNZ ,或用位寻址指令实现:JC、JNC、JB、JNB、JBC 例4.2 假定在外部RAM 中有ST1、ST2和 ST3共3个连续单元,其中ST1和ST2单元分别存放着两个8位无符号二进制数,要求找出其中的大数并存入ST3单元中。,分支程序,ST1 EQU 0050H ORG 0000H START:MOV DPTR,#ST1 ;设置数据指针 MOVX A,DPTR ;取第一个数 MOV R2 ,A ;第一个数存R2 INC DPTR ;指向第二个数 MOVX A,DPTR ;取第二个数 CLR C ;清进位标志 SUBB A,R2 ;第二个数-第一个数,A 中是差JNC BIG1 ;第二个
6、数大转移 XCH A ,R2 ;第一个数大,A 中为第一个数 BIG0:INC DPTR ;指向ST3 MOVX DPTR,A ;存大数 HERE:SJMP HERE BIG1:MOVX A,DPTR ;第二个数大,取第二个数 SJMP BIG0 END,2.多分支程序 MCS-51没有多分支转移指令,不能用一条指令实现分支。 1)使用CJNE指令逐次比较,例4.3 某温度控制系统,采集的温度值(Ta )放在累加器A 中。在内部RAM 54H单元存放控制温度下限值(T54 ),在55H单元存放控制温度上限值(T55 )。 若Ta T55 ,程序转向JW(降温处理程序);若Ta T54 ,程序转
7、向SW(升温处理程序);若T55TaT54,则程序转向FH(返回主程序)。 ; 如果转升温程序,出口R0=2;如果转降温程序,出口R0=0;温度在设定范围内,出口R0=1。 TA EQU 43 ;采集的温度值 T54 EQU 42 ;控制温度下限值 T55 EQU 45 ;控制温度上限值 ORG 0000H MOV SP,#60H ;设置堆栈指针,MOV R0,#01H ;温度控制程序出口标志初值 MOV A,#TA ;采集的温度值送A MOV 54H,#T54 ;取控制温度下限值 MOV 55H,#T55 ;取控制温度上限值 LCALL TEMPR ;调用温度控制子程序 HERE:SJMP
8、HERE ;温度控制子程序 TEMPR:CJNE A,55H,LOOP1;与上限值比,不相等转移 AJMP FH ;采集的温度值与温度上限值相等,返回 LOOP1:JNC JW ;采集的温度值大于温度上限值,转降温程序JW CJNE A,54H,LOOP2;与温度下限值比,不等转移 AJMP FH ;采集的温度值与温度下限值相等,返回 LOOP2:JC SW ;采集的温度值小于温度下限值,转升温程序SW FH:RET,JW: DEC R0 ;温度控制程序出口标志值减1 RET SW:INC R0 ;温度控制程序出口标志值加1 RET END,2 )使用查地址表方法实现多分支程序转移 在程序中建
9、立一个差值表,将各分支入口地址与该表首地址的差值按顺序排列其中。 差值表的首地址送DPTR,分支序号值送A 中。 查表后用转移指令JMP A+DPTR 进行分支。例4.4 有四个分支程序段 BR0分支程序段:从内部RAM 取数 BR1分支程序段:从外部RAM 低256字节范围取数 BR2分支程序段:从外部RAM 4K字节范围取数 BR3分支程序段:从外部RAM 64K字节范围取数 R0 中存放取数地址低8位,R1 中存放高8位地址。 R3 中存放分支序号值, BRTAB为差值表首址。 BR0-BRTAB BR3-BRTAB 为差值,;用查地址表方法实现多分支程序转移 ORG 0000H MOV
10、 A,R3 ;取分支值 MOV DPTR,#BRTAB ;差值表的首址 MOVC A,A+DPTR ;查表 JMP A+DPTR ;转分支程序 BRTAB:DB 04H ;BR0-BRTAB DB 07H ;BR1-BRTAB DB 0AH ;BR2-BRTAB DB 15H ;BR3-BRTAB BR0: MOV A,R0 ;从内部RAM取数 SJMP BRE,BR1:MOVX A,R0 ;从外部RAM低256B取数 SJMP BRE BR2: MOV A ,R1 ;取高8位地址 ANL A ,#0FH ;屏蔽最高4位 ANL P2,#0F0H ;屏蔽P2的低4位 ORL P2,A ;更新P
11、2的低4位 MOVX A ,R0 ;从外部RAM 4KB取数 SJMP BRE BR3:MOV DPL,R0 ;取低8位地址 MOV DPH,R1 ;取高8位地址 MOVX A,DPTR ;从外部RAM 64KB取数 BRE:SJMP $ END,3) 使用查转移指令表的方法实现多分支程序转移 用转移指令构成一个表 ORG 0000H MOV A,R3 ;分支序号值 RL A ;分支序号乘2 MOV DPTR,#BRTAB ;转移指令表首址 JMP A+DPTR ;查表 BRTAB:AJMP BR0 ;转移指令表,2字节 AJMP BR1 AJMP BR2 AJMP BR3 BR0:MOV A
12、,R0 ;从内部RAM取数 SJMP BRE,BR1:MOVX A,R0 ;从外部RAM低256B取数 SJMP BRE BR2:MOV A,R1 ;取高8位地址 ANL A ,#0FH ;屏蔽最高4位 ANL P2 ,#0F0H ;屏蔽P2的低4位 ORL P2,A ;更新P2的低4位,即12位地址的高4位, ;用P2 口的P2.0P2.3送出 MOVX A,R0 ;指令送出低8位地址, ;从外部RAM 4KB取数 SJMP BRE BR3:MOV DPL,R0 ;取低8位地址 MOV DPH,R1 ;取高8位地址 MOVX A,DPTR ;指令送出16位地址 ;从外部RAM 64KB取数
13、BRE:SJMP $ END,例4.5 假定键盘上有三个操作键,功能说明如下表,键值在A 中。键功能 键值 处理程序 读数据 01 DS 写数据 02 XS 插入 03 CR 有关此键盘的译码程序段: MOV DPTR ,#3000H ;3000H为基址 CLR C ;进位位CY清0 RLC A ;A带进位位循环左移 JMP A+DPTR ;读操作键处理程序,3000H 3001H 3002H AJMP DS ;转读数据程序 3003H 3004H AJMP XS ;转写数据程序 3005H 3006H AJMP CR ;转插入程序,4)通过堆栈操作实现多分支程序转移 通过堆栈操作,把分支程序
14、的入口地址压入堆栈中,然后利用返回指令把分支程序的入口地址装入PC,实现了分支程序的转移。 例 假定分支程序的入口地址表首址为BRTEAB,分支转移序号在R3中 通过堆栈操作实现多分支程序转移 ORG 0000H MOV SP,#60H ;设置堆栈指针 MOV DPTR,#BRTAB ;分支程序入口地址表 MOV A ,R3 ;取分支值 RL A ;分支值乘2 MOV R1,A ;暂存A (分支值乘2 ) INC A ;(分支值乘2 )+1,MOVC A,A+DPTR ;取低位地址(在表高地址) PUSH A ;低8位地址入栈 MOV A ,R1 ;取暂存值(分支值乘2 ) MOVC A,A+
15、DPTR ;取高位地址(在表低地址) PUSH A ;高8位地址入栈 RET ;分支入口地址装入PC BR0: MOV A,R0 ;从内部RAM取数 SJMP BRE BR1: ;略,同前 BR2: ;略,同前 BR3: ;略,同前 BRE: SJMP $ BRTAB:DW BR0,BR1,BR2,BR3 END,*循环初始部分 *循环体 *循环控制部分 *循环结束部分 例4.6 设有一字符串以回车符为结束标志,并存放在内部RAM从40H单元开始的连续存储单元中,编写测试字符串长度的程序。 (回车符的ASCII码为0DH,字符串长度不超过255 ),循环程序,;结果:字符串长度在R2 中(回车
16、符不计入), 回车符地址在R0 中。 ORG 0000H MOV SP,#60H LCALL TEST SJMP $ TEST:MOV R2 ,#00H ;长度计数器初值 MOV R0,#40H ;字符串指针初值 LOOP:CJNE R0,#0DH,GOON;与回车符比,不等转移 RET GOON:INC R2 ;不是回车符,长度计数器加1 INC R0 ;指向下一个字符 LJMP LOOP ;继续比较 END,例4.7 把内部RAM 中起始地址为data1的数据串传送到外部RAM 以buffer为首地址的区域,直到发现“$”字符的ASCII码为止。数据串最大长度为32个字节。 ;“$” 不传
17、送 BUFFER EQU 4000H ;外部RAM 区首址(目标) DATA1 EQU 40H ;内部RAM 区首址(源) ORG 0000H LJMP MAIN ORG 0030H MAIN: MOV SP,#60H ;设置堆栈区 LCALL ROUT1 ;调用子程序 SJMP $ ROUT1:MOV R0,#DATA1 ;子程序,源数据区起始地址 MOV DPTR,#BUFFER;目标数据区起始地址 MOV R1,#20H ;数据串最大长度,LOOP:MOV A,R0 ;取源数据 CJNE A,#24H,LOOP2 ;是“$”符号吗? SJMP LOOP1 ;是,则结束 LOOP2:MOV
18、X DPTR,A ;不是“$”则数据传送 INC DPTR ;指向下一个目标地址 INC R0 ;指向下一个源地址 DJNZ R1 ,LOOP ;数据串长度-1=0?不为0转移 LOOP1:RET ;为0则结束子程序 END,;“$”传送 BUFFER EQU 4000H ;外部RAM 区首址(目标) DATA1 EQU 40H ;内部RAM 区首址(源) ORG 0000H LJMP MAINORG 0030H MAIN: MOV SP,#60H ;设置堆栈区 LCALL ROUT1 ;调用子程序 SJMP $ ROUT1:MOV R0,#DATA1;子程序,源数据区起始地址 MOV DPT
19、R,#BUFFER;目标数据区起始地址 MOV R1,#20H ;数据串最大长度,LOOP: MOV A,R0 ;取源数据 MOVX DPTR,A ;数据传送 CLR C ;清借位 SUBB A,#24H ;A的内容是“$”符号吗? JZ LOOP1 ;是则结束 INC DPTR ;不是“$”,指向下一个目标地址 DJNZ R1,LOOP ;数据串长度-1=0?不为0转移 LOOP1:RET ;为0则结束子程序 END,算术运算程序 数制转换程序 定时程序 查表程序 数据极值查找程序 数据排序程序 数据检索程序,4.3 MCS-51汇编语言程序设计举例,1.加减法运算 1)不带符号的多个单字节
20、数加法 例 有多个单字节的数,依次存放在外部RAM 0020H开始的连续单元中,要求把相加结果存放在R1和R2 中(假定相加的和为二字节数),其中R1为高位,R2为低位。由于仿真软件不支持外部RAM 8位寻址,所以外部RAM的存放地址改为16位地址。N EQU 20 ORG 0000H MOV DPTR,#0020H ;设置数据指针 MOV R3 ,#N ;字节个数 MOV R1 ,#00H ;和的高位清0 MOV R2 ,#00H ;和的低位清0,算术运算程序,LOOP: MOVX A,DPTR ;取一个加数 ADD A ,R2 ;单字节数相加 MOV R2,A ;和的低位送R2 JNC L
21、OOP1;相加有无进位?无进位转移 INC R1 ;有进位,和的高位加1 LOOP1:INC DPTR ;指向下一单元 DJNZ R3,LOOP ;字节数是否加完? HERE:SJMP $ END,2)不带符号的两个多字节数减法 设有两个N字节无符号数分别存放在内部RAM的单元中,低字节在前,高字节在后,由R0指定被减数单元地址,R1指定减数单元地址,差存放在原被减数单元中。;主程序 N EQU 03H ORG 0000H MOV SP,#60H MOV R0,#20H ;被减数地址 MOV R1,#30H ;减数地址 MOV R4,#00H ;溢出标志 LCALL SUB ;调用多字节不带符
22、号数的减法子程序 HERE: SJMP $,SUB: CLR C ;清进位位 MOV R2,#N ;设定字节数 LOOP: MOV A,R0 ;取被减数低字节数 SUBB A,R1 ;两数相减 MOV R0,A ;存差值 INC R0 ;指向下一个被减数地址 INC R1 ;指向下一个减数地址 DJNZ R2,LOOP ;两数相减结束否? JC QAZ ;最高字节是否有借位? RET QAZ:INC R4 ;有借位,置溢出标志 RET,3)带符号数加减运算 对于有符号数的减法运算,只要将减数的符号位取反,即可把减法运算按加法运算的原则处理。 对于有符号数的加法运算,首先判断符号。若两数符号相同
23、,则进行两数相加,以被加数符号为结果的符号。若两数符号不同,应进行两数相减,差为正时,该差数即为最后结果。差为负时,差取补,被减数符号取反作为结果的符号。,例4.8 假定R2、R3和R4、R5分别存放两个16位的带符号的二进制数,其中R2和R4的最高位为两数的符号位。请编写带符号双字节二进制数的加减运算程序,以BSUB为减法程序入口,以BADD为加法程序入 口,以R6、R7保存运算结果。,;两字节带符号数加减运算,DATA1-DATA2, ;DATA1+DATA2,溢出R0为1 DATA1H EQU 32H DATA1L EQU 5DH DATA2H EQU 87H DATA2L EQU 46
24、H ORG 0000H ;主程序 MOV SP,#60H ;设置堆栈指针 MOV R0,#00H ;溢出标志初值ORG 0000H ;主程序 MOV SP,#60H ;设置堆栈指针 MOV R0,#00H ;溢出标志初值 MOV R2,#DATA1H ;送被减数 MOV R3,#DATA1L MOV R4,#DATA2H ;送减数 MOV R5,#DATA2L,LCALL BSUB ;调用减法子程序 MOV R0,#00H ;溢出标志初值 MOV R2,#DATA1H ;送被加数 MOV R3,#DATA1L MOV R4,#DATA2H ;送加数 MOV R5,#DATA2L LCALL B
25、ADD ;调用加法子程序 SJMP $ BSUB: MOV A ,R4 ;减数符号取反 CPL ACC.7 MOV R4,A BADD: MOV A ,R2 ;加法,取被加数符号 MOV C,ACC.7 ;被加数符号位送F0保存 MOV F0,C XRL A ,R4 ;两数异或(符号是否同号),MOV C,ACC.7;同号C=0,异号C=1 MOV A ,R2 ;取被加数去符号位 CLR ACC.7 MOV R2,A MOV A ,R4 ;取加数去符号位 CLR ACC.7 MOV R4,A JC JIAN ;两数异号转JIAN JIA:MOV A ,R3 ;两数同号,低字节加 ADD A ,
26、R5 MOV R7,A ;存低字节和 MOV A ,R2 ;高字节带进位加 ADDC A ,R4 MOV R6,A ;存高字节和 JB ACC.7 ,QAZ;符号位为1转溢出处理 QWE: MOV C,F0 ;结果符号处理 MOV ACC.7 ,C MOV R6,A RET,JIAN: MOV A ,R3 ;取被减数低字节 CLR C ;清进位 SUBB A ,R5 ;低字节相减 MOV R7,A ;存低字节差 MOV A ,R2 ;取被减数高字节 SUBB A ,R4 ;高字节相减 MOV R6,A ;存高字节差 JNB ACC.7 ,QWE;判差的符号,为0则转移 BMP: MOV A ,R7 ;差为负,低字节取补 CPL A ADD A ,#1 MOV R7,A MOV A ,R6 ;高位取补 CPL A ADDC A ,#0,MOV R6,A CPL F0 ;保存在F0 中的符号取反 SJMP QWE ;转结果符号处理 QAZ:INC R0 ;溢出标志处理 RET END,