C51的汇编语言程序设计.ppt_第1页
C51的汇编语言程序设计.ppt_第2页
C51的汇编语言程序设计.ppt_第3页
C51的汇编语言程序设计.ppt_第4页
C51的汇编语言程序设计.ppt_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第4章 80C51的汇编语言程序设计 程序编制的方法和技巧4.1 源程序的编辑和汇编4.2 基本程序结构 4.3 子程序及其调用4.4 简单I/O设备的并口直接驱动示例 4.5 Date 1 v 单片机应用系统由硬件系统和应用程序构成 汇编语言 高级语言 应用程序设计方法 汇编语言,生成的目标程序占内存空间少、运行速 度快,具有效率高、实时性强。 高级语言,对系统的功能描述与实现简单,程序阅 读、修改和移植方便,适合于编写复杂的程序。 Date 2 4.1 程序编制的方法和技巧 4.1.1 程序编制的步骤 明确任务:功能要求、技术指标 运行环境调研 v 任务分析 将实际问题转化为计算机处理的程序算法 算法比较与优化(内存需求与运行速度) 算法设计 Date 3 流程描述 v 流程图符号 “超级循环”框架 Date 4 v 强化模块观念 使程序占用空间减少、结构清晰 循环初值和结束条件,避免“死机”现象 子程序的现场保护(注意栈平衡、寄存器内容) 程序模块(主程序模块、各种子程序模块) 模块化优点:分块设计、便于阅读、调试方便 4.1.2 程序编制的方法和技巧 采用循环和子程序 对中断子程序还有注意保护PSW的内容 Date 5 4.1.3 汇编语言的语句格式 非数字字符开头,后跟字母、数字、“-”、“?” 等 不能用已定义的保留字(指令助记符、伪指令等) 后跟英文冒号“:” Keil的汇编器A51可以识别的语句形式为: v 标号(即符号地址) 标号: 指令助记符 操作数1, 操作数2, 操作数3, ;注释 指令助记符 是指令功能的英文缩写。 Date 6 数据:二进制(B) 十进制(D或省略D) 十六进制(H),注意AF开头时要加“0” ASCII码,如 A,1245 v 符号:符号名、标号或“$”(PC的当前值) v 表达式:由运算符和数据构成(见表4.1) v 操作数 注释 英文分号“;”开头 Date 7 优先级运 算 符功 能表达式及其结果示例 高 低 ()括号 4*(5+6)即44 NOT、HIGH、 LOW 取反、取高字节、取低 字节 NOT 55H 即AAH; HIGH 1234H 即12H 、正号、负号 5、6 *、/、MOD 乘、除(取商)、取余 数 17 / 5 即3; 17 MOD 5 即2 、加、减 54 即 9; 54 =即1 SHL、SHR左移、右移2 SHL 2即8;8 SHR 2 即 2 AND、OR、XOR与、或、异或45H AND 0FH即05H 、=、8; 若X8为真,则为MOV A,01H 若X8为假,则为MOV A,00H 表4.1 Date 8 4.2 源程序的编辑和汇编 目标程序的产生过程如下图: Date 9 4.2.1 源程序的编辑和汇编 源程序的编辑 ORG 0000H LJMP MAIN ORG 0040H MAIN:MOV R7,#16 MOV R0,#60H MOV A,#55H LOOP:MOV R0,A INC R0 DJNZ R7,LOOP SJMP $ END 依据汇编语言规则 用好伪指令 符号不用中文 SJMP $ 用于调试 以 .ASM存盘 Date 10 源程序的汇编 汇编源程序转为目标程序的过程叫汇编 汇编通常在Windows下的集成开发环境完成 用A51.EXE汇编生成.OBJ、.LIB及.LST 目标程序的连接 .OBJ、.LIB经BL51.EXE生成无扩展名的绝对地址目标文件 绝对地址目标文件可以用于仿真器调试 调试无误的目标文件用OH51.EXE转换为.HEX文件 .HEX文件经编程器写入单片机存储器 Date 11 4.2.2 伪指令 伪指令,也叫汇编命令。仅对汇编过程进行指示 伪指令无对应的单片机可执行代码 起始地址设定伪指令ORG ORG 表达式 表达式通常为十六进制地址,例: ORG 8000H START:MOV A,#30H ORG可多次使用,但地址值的顺序要由小到大 结束汇编伪指令END END 该伪指令位于源程序的最后一行。 Date 12 定义字节数据表伪指令DB 定义字数据表伪指令DW 1000H 标号: DB 字节数据表 如: ORG 1000H DB -2,-4,-6,8,10,18 FEH FCH FAH 08H 0AH 12H 1001H 标号: DW 字数据表 ORG 1400H DATA1:DW 324AH,3CH 1400H 32H 4AH 00H 3CH 1401H 1402H 1403H 大端模式 Date 13 定义常值为符号名伪指令EQU 符号名 EQU 常值表达式 LEN EQU 10 SUM EQU 21H BLOCK EQU 22H CLR A MOV R7,LEN MOV R0,BLOCK LOOP:ADD A,R0 INC R0 DJNZ R7,LOOP MOV SUM,A 符号名为: v地址 v常数 v段名 v字符串 v寄存器名 v位名 比较:标号只能是地址 Date 14 定义位地址为符号名伪指令BIT 符号名 BIT 位地址表达式 如: ST BIT P1.0 ;将P1.0的位地址赋给符号名ST CF BIT 0D7H ;将位地址为D7H的位定义为符号名 用BIT定义的“符号名”一经定义便不能重 新定义和改变 其它一些伪指令参见教材表4.2 Date 15 4.3 基本程序结构 v一般不影响标志寄存器PSW的状态。 传送类指令有两大类 一般传送( MOV ) 特殊传送,如: MOVC MOVX PUSH、POP XCH、XCHD SWAP Date 16 4.3.1 顺序程序(无分支、无循环) 4.3 基本程序结构 【例4-1】片内RAM的21H单 元存放一个十进制数据十 位的ASCII码,22H单元存 放该数据个位的ASCII码。 编写程序将该数据转换成 压缩BCD码存放在20H单元 。 Date 17 ORG 0040H START:MOV A,21H ;取十位ASCII码 ANL A,#0FH ;保留低半字节 SWAP A ;移至高半字节 MOV 20H,A ;存于20H单元 MOV A,22H ;取个位ASCII码 ANL A,#0FH ;保留低半字节 ORL 20H,A ;合并到结果单元 SJMP $ END Date 18 4.3.2 分支程序(单分支、双分支、多分支) 【例4-2】设变量x以补码 的形式存放在片内RAM的 30H单元,变量y与x的关 系是:当x大于0时,y=x;当 x=0时,y=20H;当x小于0时 ,y=x+5。编制程序,根据x 的大小求y并送回原单元 。 Date 19 ORG 0040H START:MOV A,30H ;取x至累加器 JZ NEXT ;x = 0,转NEXT ANL A,#80H ;否,保留符号位 JZ DONE ;x 0,转结束 MOV A,#05H ;x 0处理 ADD A,30H MOV 30H,A ;X+05H送Y SJMP DONE NEXT:MOV 30H,#20H ;x = 0,20H送Y DONE:SJMP DONE END Date 20 【例4-3】根据R7的内容x(转移序号)转向相应的处理程序。 设R7内容为04,对应的处理程序入口地址分别为PP0PP4。 Date 21 START:MOV R7,#3 ;以转移序号3为例 ACALL JPNUM AJMP START JPNUM:MOV DPTR,#TAB ;置分支入口地址表首址 MOV A,R7 ADD A,R7 ;乘2,调整偏移量 MOV R3,A MOVC A,A+DPTR ;取地址高字节,暂存于R3 XCH A,R3 INC A MOVC A,A+DPTR ;取地址低字节 MOV DPL,A ;处理程序入口地址低8位送DPL MOV DPH,R3 ;处理程序入口地址高8位送DPH CLR A JMP A+DPTR Date 22 TAB:DW PP0 DW PP1 DW PP2 DW PP3 DW PP4 PP0:MOV 30H,#0 ;转移序号为0时,置功能号“0”于30H单 元 RET PP1:MOV 30H,#1 ;转移序号为1时,置功能号“1”于30H单 元 RET PP2:MOV 30H,#2 ;转移序号为2时,置功能号“2”于30H单 元 RET PP3:MOV 30H,#3 ;转移序号为3时,置功能号“3”于30H单 元 RET PP4:MOV 30H,#4 ;转移序号为4时,置功能号“4”于30H单 元 RET Date 23 4.3.3 循环程序(2种:先执行,后判断;先判断,后执行 ) 【例4-4】将内部RAM的30H至3FH单元初始化为00H。 MAIN:MOV R0,#30H ;置初值 MOV A,#00H ; MOV R7,#16 ; LOOP:MOV R0,A ;循环处理 INC R0 ; DJNZ R7,LOOP ;循环修改,判结束 SJMP $ ;结束处理 Date 24 【例4-5】将内部RAM起始地址为60H的数据串传送到外部RAM中 起始地址为1000H的存储区域,直到发现$ 字符停止传送。 MAIN:MOV R0,#60H ;置初值 MOV DPTR,#1000H LOOP0:MOV A,R0 ;取数据 CJNE A,#24H,LOOP1 ;循环结束? SJMP DONE ;是 LOOP1:MOVX DPTR,A ;循环处理 INC R0 ;循环修改 INC DPTR SJMP LOOP0 ;继续循环 DONE:SJMP DONE ;结束处理 Date 25 4.4 子程序及其调用 完成通用功能、反复使用的程序设计成子程序。使应用 程序结构清晰紧凑,便于阅读和调试 执行要由其它程序来调用,执行完后要返回到调用程序 结构上仍然采用一般程序的3种结构 调用时注意: 一是现场的保护和恢复; 二是主程序与子程序间的参数传递。 Date 26 4.4.1 现场保护与恢复 在主程序中实现(结构灵活) PUSH PSW ;保护现场( 含当前工作寄存器组号 ) PUSH ACC ; PUSH B ; MOV PSW,#10H ;切换当前工作寄存器组 LCALL addr16 ;子程序调用, POP B ;恢复现场 POP ACC ; POP PSW ;含当前工作寄存器组切换 Date 27 在子程序中实现(程序规范、清晰) SUB1:PUSH PSW ;保护现场( 含当前工作寄存器组 号) PUSH ACC ; PUSH B ; MOV PSW,#10H ;切换当前工作寄存器组 POP B ;恢复现场 POP ACC ; POP PSW ;内含当前工作寄存器组切换 RET Date 28 4.4.2 参数传递 利用累加器或寄存器(简单、快速,但参数个数不多) 【例4-6】实现两个8位的十六进制无符号数求和的子程序。 SADD:MOV A,R3 ;取加数(在R3中) CLR C ADD A,R4 ;被加数(在R4中)加A JC PP1 MOV R3,#00H ;结果小于255时,高字节R3内容为00H SJMP PP2 PP1:MOV R3,#01H ;结果大于255时,高字节R3内容为01H PP2:MOV R4,A ;结果的低字节在R4中 RET 入口:(R3)=加数; (R4)=被加数 出口:(R3)=和的高字节; (R4)=和的低字节。 Date 29 利用存储器(个数多,用R0或R1及DPTR为参数表指针) 【例4-7】将内部RAM 中两个4字节无符号整数相加,和的高 字节由R0指向。数据采用大端模式存储。 入口:(R0)=加数低字节地址; (R1)=被加数低字节地址。 出口:(R0)=和的高字节起始地址。 NADD:MOV R7,#4 ;字节数4送计数器 CLR C ; NADD1:MOV A,R0 ;利用指针,取加数低字节 ADDC A,R1 ;利用指针,被加数低字节加A MOV R0,A ; DEC R0 DEC R1 DJNZ R7,NADD1 INC R0 ;调整指针,指向出口 RET Date 30 利用堆栈 【例4-8】 将内部RAM中20H单元中的1个字节十六进制数转换为2 位ASCII码,存放在R0指示的两个单元中。 入口:预转换数据(低半字节)在栈顶 出口:转换结果(ASCII码)在栈顶 HEASC:MOV R1,SP ;借用R1为堆栈指针 DEC R1 DEC R1 ;R1指向被转换数据 XCH A,R1 ;取被转换数据 ANL A,#0FH ;取一位十六进制数 ADD A,#2 ;偏移调整,所加值为MOVC与DB间总字节数 MOVC A,A+PC ;查表 XCH A,R1 ;1字节指令,存结果于堆栈中 RET ;1字节指令 ASCTAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H Date 31 验证程序段 MAIN:MOV A,20H ; SWAP A PUSH ACC ;预转换的数据(在低半字节)入栈 ACALL HEASC POP ACC ;弹出栈顶结果于ACC中 MOV R0,A ;存转换结果高字节 INC R0 ;修改指针 PUSH 20H ;预转换的数据(在低半字节)入栈 ACALL HEASC POP ACC ;弹出栈顶结果于ACC中 MOV R0,A ;存转换结果低字节 SJMP $ Date 32 4.4.3 常用子程序示例 算数运算子程序 查表子程序 数制与码的转换子程序 延时子程序 Date 33 减法子程序 v编写多字节无符号数的减法子程序 设2个多字节无符号数的低字节地址分别存于R0R1中, 低字节在高地址单元。相减后的差存放在减数原来的位置 子程序入口:(R0)=被减数低字节地址 (R1)=减数低字节地址 (R7)=字节数 子程序出口: (R1)=差的高字节地址(起始地址) Date 34 NSUB: CLR C NSUB1:MOV A, R0 SUBB A,R1 MOV R1,A DEC R0 DEC R1 DJNZ R7,NSUB1 INC R1 RET Date 35 乘法子程序 v 编写双字节无符号数的乘法子程序 设双字节的无符号被乘数存放在R2、R3中,乘数存放在 R4、R5中,R0指向积的高字节 子程序入口:( R2、R3)=被乘数 (R4、R5)=乘数 (R0)=预存放积的低字节的单元地址 子程序出口: (R0)=积的高字节的单元地址 Date 36 R2R3 R4R5 R3R5LR3R5H R3R4LR3R4H R2R5H R2R4HR2R4L R2R5L Date 37 MOV A, R2 MOV B, R5 MUL AB INC R0 INC R0 ACALL RADD MOV A, R2 MOV B, R4 MUL AB INC R0 ACALL RADD INC R0 RET MOV A, R3 MOV B, R5 MUL AB ACALL RADD MOV A, R3 MOV B, R4 MUL AB INC R0 ACALL RADD ADD A,R0 MOV R0,A MOV A,B DEC R0 ADDC A ,R0 MOV R0,A DEC R0 MOV A,R0 ADDC A,#00H MOV R0,A RET RADD: 部分积累加子程序: Date 38 查表子程序 v利用子程序实现c=a2+b2 设a、b、c分别存放于内部RAM的30H、31H 、32H单元中 子程序入口:(A)=预平方数 子程序出口:(A)=平方值 Date 39 SQR: MOV DPTR, #TAB MOVC A, A+DPTR RET TAB:DB 0,1,4,9,16,25,36,49,64,81 Date 40 十六进制数转换为ASCII码 v将1位十六进制数(即四位二进制数)转换为相 应 的ASCII码。设十六进制数存放在R0中,转换 后的ASCII码存放在R2中 子程序入口:(R0)=十六进制数 子程序出口:(R2)=ASCII码 Date 41 十六进制数转换为ASCII码 v多十六进制数转换为ASCII码。 子程序入口:(R0)=十六进制数低字节地址 (R2)=字节数 子程序出口:(R0)=十六进制数高字节地址 (R1)=ASCII码的高位地址 Date 42 MOV A,R0 ANL A,#0FH ADDC A,#16 MOVC A,A+PC MOV R1,A INC R1 MOV A,R0 SWAP A ANL A#07H ADD A,#7 MOVC A,A+PC MOV R1,A INC R0 INC R1 DJNZ R2,LP DEC R1 RET ASC:DB 30H,31H,32H- LP: ASCTAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H MOV A,R0 ANL A,#0FH MOV DPTR,#ASCTAB MOVC A,A+DPTR MOV R1,A INC R1 MOV A,R0 SWAP A ANL A#07H MOVC A,A+DPTR MOV R1,A INC R0 INC R1 DJNZ R2,LP DEC R1 RET LP: Date 43 二进制数与十进制数之间的转换 v双字节二进制数转换为BCD码 设(R2R3)为双字节二进制数,(R4R5R6)为转 换完的压缩型BCD码 子程序入口:(R2R3)=十六位二进制数 子程序出口:(R4R5R6)=转换完的压缩型BCD 码 Date 44 D=b15*215+b14*214+b1*2+b0 =(b15*2)+b14)*2+b1)*2+b0 =(0*2+b15)*2)+b14)*2+b1)*2+b0 D4=b3*23+b2*22+b1*2+b0 =(b3*2)+b2)*2+b1)*2+b0 =(0*2+b3)*2)+b2)*2+b1)*2+b0 Date 45 CLR A MOV R4,A MOV R5,A MOV R6,A MOV R7,#16 CLR C MOV A,R3 RLC A MOV R3,A MOV A,R2 RLC A MOV R2,A DCD : LOOP : MOV A,R6 ADDC A,R6 DA A MOV R6,A MOV A,R5 ADDC A,R5 DA A MOV R5,A MOV A,R4 ADDC A,R6 DA A MOV R4,A DJNZ R7,LOOP Date 46 延时子程序 v 1m延时子程序 D1ms:MOV R6,#249 DL:NOP NOP DJNZ R6,DL RET D10ms:MOV R5,#10 D1ms:MOV R4,#249 DL:NOP NOP DJNZ R4,DL DJNZ R5,D10ms RET 10ms延时子程序 (1+1+2)*249*T=996 *T(1+996+2)*10*T=9990* T Date 47 4.5 简单I/O设备的并口直接驱动示例 4.5.1 独立式键盘与LED显示示例 【例4-17】数据端与P0口正序连接。编写程序,分别实现 功能:上电后数码管显示“P”,按下任何键后,显示从 “0”开始每隔1秒加1,加至“F”后,数码管显示“P”, 进入等待按键状态。 Date 48 TEMP EQU 30H ORG 0000H JMP START ORG 0100H START:MOV SP,#5FH MOV P0,#8CH ;显示“P“ MOV P3,#0FFH NOKEY:MOV A,P3 CPL A JZ NOKEY ;无键按下 MOV TEMP,P3 ;有键按下 ACALL D10ms MOV A,P3 CJNE A,TEMP,NOKEY;去抖 MOV R7,#16 MOV R2,#0 LOOP:MOV A,R2 MOV DPTR,#CODE_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论