概述伪指令简单程序分支程序循环程序查表程序子程序应用举例.ppt_第1页
概述伪指令简单程序分支程序循环程序查表程序子程序应用举例.ppt_第2页
概述伪指令简单程序分支程序循环程序查表程序子程序应用举例.ppt_第3页
概述伪指令简单程序分支程序循环程序查表程序子程序应用举例.ppt_第4页
概述伪指令简单程序分支程序循环程序查表程序子程序应用举例.ppt_第5页
已阅读5页,还剩99页未读 继续免费阅读

下载本文档

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

文档简介

07:09:03,概述 伪指令 简单程序 分支程序 循环程序 查表程序 子程序 应用举例,第 章 51 程序系统,本章内容,Single Chip Microcomputer,07:09:03,程序设计概述设计语言,最早人们只能用机器语言(二进制)编写程序; 为了方便记忆,人们开始用助记符形式的汇编语言编写程序,称为低级语言。然后再用汇编系统将其翻译成机器语言,该过程称为汇编; 为了用更接近人的语言编写程序,程序设计师们发明了高级语言,如: BASIC、FORTRAN、PASCAL、 C、JAVA 然后再用编译系统将其翻译成机器语言,该过程称为编译; 机器只能识别机器语言。所以必须用编译系统将高级语言编写的源程序编译成机器语言,用汇编系统将用汇编语言编写的源程序汇编成机器语言; 由低级或高级语言构成的程序称为源程序,由机器语言构成的程序称作目标程序;,07:09:03,源程序 目标程序,低级语言,机器语言,汇编,高级语言,机器语言,编译,单片机的任务与设计风格 1)面向控制; 2)途径不一; 目标 周期短、空间小; 掌握方法、学会思维,07:09:03,一、概述,1)机器语言、汇编语言、高级语言 2)机器汇编、手工汇编 文件后缀ASM OBJ HEX 3)程序设计步骤 (1) 分析问题;(分析透) (2) 确定算法; (3) 设计程序流程图,参见P76图4-1 (4) 分配内存单元,确定程序和数据 区的起始地址; (5) 编写汇编语言程序; (6) 仿真、调试程序、优化。 (7) 固化程序。 3)注意方法、本章安排,07:09:03,2伪指令 伪指令不要求计算机做任何操作,也没有对应的机器码,不产生目标程序,不影响程序的执行,仅仅是能够帮助进行汇编的一些指令。它主要用来指定程序或数据的起始位置,给出一些连续存放数据的地址或为中间运算结果保留一部分存储空间以及表示源程序结束等等。不同版本的汇编语言,伪指令的符号和含义可能有所不同,但基本用法是相似的。,07:09:03,二、伪指令,定位伪指令ORG(可多个) 定义字节数据伪指令DB(定义表格,可设标号) 定义字数据伪指令DW(高位在前) 定义空间伪指令DS(预留) 符号定义伪指令EQU或 (可定义寄存器、位、地址(#用法)等,可先使用) 数据赋值伪指令DATA(与EQU等价) 位定义伪指令bit 汇编结束伪指令END(只有一个),07:09:03,1) 设置目标程序起始地址伪指令ORG 格式:符号: ORG 地址(十六进制表示) 该伪指令的功能是规定其后面的目标程序或数据块的起始地址。它放在一段源程序(主程序、子程序)或数据块的前面,说明紧跟在其后的程序段或数据块的起始地址就是ORG后面给出的地址。例如: ORG 2000H START:MOV A,#7FH,07:09:03,2) 结束汇编伪指令END 格式:标号: END END是汇编语言源程序的结束标志,表示汇编结束。在END以后所写的指令,汇编程序都不予处理。一个源程序只能有一个END命令,否则就有一部分指令不能被汇编。如果END前面加标号的话,则应与被结束程序段的起始点的标号一致,以表示结束的是哪一个程序段。,07:09:03,3) 定义字节伪指令DB 格式:标号: DB 项或项表 其中项或项表指一个字节数据,用逗号分开的字节数据串,或以引号括起来的字符串。该伪指令的功能是把项或项表的数据(字符串按字符顺序以ASCII码)存入从标号地址开始的连续存储单元中。例如: ORG 2000H TAB1: DB 30H,8AH,7FH,73 DB 5,A,BCD,07:09:03,由于ORG 2000H,所以TAB1的地址为2000H,因此,以上伪指令经汇编后,将对2000H开始的连续存储单元赋值:,(2000H)=30H (2001H)=8AH (2002H)=7FH (2003H)=49H ;十进制数73以十六进制数存放 (2004H)=35H ;35H是数字5的ASCII码 (2005H)=41H ;41H是字母A的ASCII码 (2006H)=42H ;42H是字符串BCD中B的ASCII码 (2007H)=43H ;43H是字符串BCD中C的ASCII码 (2008H)=44H ;44H是字符串BCD中D的ASCII码,07:09:03,4) 定义字伪指令DW 格式:标号: DW 项或项表 DW伪指令与DB相似,但用于定义字的内容。项或项表指所定义的一个字(两个字节)或用逗号分开的字串。汇编时,机器自动按高8位先存入,低8位在后的格式排列。例如: ORG 1500H TAB2: DW 1234H,80H 汇编以后:(1500H)=12H,(1501H)=34H,(1502H)=00H, (1503H)=80H,07:09:03,5) 预留存储空间伪指令DS 格式:标号: DS 表达式 该伪指令的功能是从标号地址开始,保留若干个字节的内存空间以备存放数据。保留的字节单元数由表达式的值决定。例如: ORG 1000H DS 20H DB 30H,8FH 汇编后从1000H开始,预留32(20H)个字节的内存单元,然后从1020H开始,按照下一条DB指令赋值,即(1020H)=30H,(1021H)=8FH。,07:09:03,6) 等值伪指令EQU 格式:标号: EQU 项 该伪指令的功能是将指令中的项的值赋予EQU前面的标号。项可以是常数、地址标号或表达式。例如: TAB1 EQU 1000H TAB2 EQU 2000H (验证是否需要:?) 汇编后TAB1、TAB2分别具有值1000H、2000H。 用EQU伪指令对某标号赋值后,该标号的值在整个程序中不能再改变。,07:09:03,7) 位地址定义伪指令BIT 格式:标号 BIT 位地址 该伪指令的功能是将位地址赋予BIT前面的标号,经赋值后可用该标号代替BIT后面的位地址。例如: PLG BIT F0 AI BIT P1.0 经以上伪指令定义后,在程序中就可以把FLG和AI作为位地址来使用。,07:09:03,单片机汇编命令与机器指令,07:09:03,1目的 (1) 掌握汇编语言程序的基本结构。 (2) 了解汇编语言程序设计的基本方法和思路。,实例 霓虹灯的控制,2引入,请观察以下几例程序的执行顺序?,07:09:03,霓虹灯的简易原理,P1口满足什么条件点灯吗?,07:09:03,流程图,07:09:03,3实训程序,程序1:所有发光二极管不停地闪动。 ORG 0000H ;程序从地址0000H开始存放 START: MOV P1,#00H ;把立即数00H送P1口,点亮所有发光二极管 ACALL DELAY ;调用延时子程序 MOV P1,#0FFH ;灭掉所有发光二极管 ACALL DELAY ;调用延时子程序 AJMP START ;重复闪动 DELAY: MOV R3,#7FH ;延时子程序 DEL2: MOV R4,#0FFH DEL1: NOP DJNZ R4,DEL1 DJNZ R3,DEL2 RET END ;汇编程序结束,07:09:03,程序2:用开关控制发光二极管的显示方式。 ORG 0000H MOV P3,#00010000B ;使P3口锁存器的P3.4置位 MOV A,P3 ;读P3口引脚线信号 ANL A,#00010000B ;“逻辑与”操作,屏蔽掉无关位 JZ DDPING ;判断P3.4是否接地,若是,跳转到DDPING执行 MOV P1,#00H ;否则,P3.4接高电平,点亮所有发光二极管 SJMP $ DDPING:MOV P1,#55H ;P3.4接地,发光二极管交叉亮灭 SJMP $ END,A=0,A0,07:09:03,程序2流程图,07:09:03,程序3:使8个发光二极管顺序点亮。 ORG 0000H START: MOV R2,#08H ;设置循环次数 MOV A,#0FEH ;送显示模式字 NEXT: MOV P1,A ;点亮连接P1.0的发光二极管 ACALL DELAY RL A ;左移一位,改变显示模式字 DJNZ R2,NEXT ;循环次数减1,不为零,继续点亮下面一个二极管 SJMP START DELAY: MOV R3,#0FFH ;延时子程序开始 DEL2: MOV R4,#0FFH DEL1: NOP DJNZ R4,DEL1 DJNZ R3,DEL2 RET END,R4-10,R4-1=0,R3-10,R3-1=0,R2-10,R3-1=0,07:09:03,程序3流程图,07:09:03,程序设计实例引入,实例 假设一个班有50个人, 共有3门选修课: 计算机算法 服装CAD设计 德语 请找出: 同时选了三门课的同学;,07:09:03,问题的解决,第一步 如何在计算机中表示选修某门课的所有同学,选修这门人数,学生的学号,这个过程实际上是设计数据结构的问题,07:09:03,问题的解决,第二步 设计思路:找出同时选了三门课的同学,这个过程实际上是设计算法的过程,既构建模型。,07:09:03,重复该过程,第三步:设计流程,07:09:03,几点启示,整体构思; 构建整体流程框图; 结构合理,流程清晰,简单明了; 局部模块化;,07:09:03,为什么要用流程图?,符合人进行逻辑思考的习惯 计算机从根本上来说,没有任何逻辑性,所以,你必须告诉它,先做什么,后做什么,遇到什么情况又该做什么,等等 流程图设计本身是一个逐步求精的过程,最终将任务划分为若干能由机器指令实现的小模块,07:09:03,第四章 程序设计,【例4.1.8】(P68)从片内RAM 40H单元开始存放三个无符号数,若40H单元的数等于2BH,则把后面两单元的数相加,若40H单元的数等于2DH,则把后面两单元的数相减,并将计算结果存放到43H单元中。如果40H单元非2BH或2DH,则作出错处理,其出错结果为FFH。试按要求编制源程序,并手工汇编成机器码。,07:09:03,第四章 程序设计,07:09:03,P70 例4.2.3 数据拼拆程序。将内部RAM 20H单元中存放的BCD码十进制数拆开并变成相应的ASCII码,分别存放到21H和22H单元中。,4.2 简单(顺序)程序设计,本题中,首先必须将两个数拆开,然后再拼装成两个ASCII码。数字与ASCII码之间的关系是:高4位为0011H,低4位即为该数字的8421码。,07:09:03,图4.6 例4.2题意分析示意图,什么是BCD码? 什么是ASII码?,数字与ASCII码之间的关系是:高4位为0011H,低4位即为该数字的8421码。,07:09:03,将20H单元的两个压缩BCD码拆开变成ASCII码,存入21H、22H单元。(假设20H中的BCD码为00110100),0011,压缩BCD码,0011,0011,0100,低四位ASII码,高四位ASII码,P78-79 例4.2.3,07:09:03,方法1:利用半字节交换指令来实现。,第四章 程序设计,07:09:03,ORG 0000H MOV R0,#20H MOV A,#30H XCHD A,R0 MOV 22H,A MOV A,R0 SWAP A ORL A , #30H MOV 21H, A SJMP $ END,简单程序例1-方法1,PC,PC,PC,PC,PC,PC,PC,PC,源程序如下:,0011,0010 0000,0011,0100,0000,0100,0011,0100,0011,0000,0011,0000,0011,PC,0011,07:09:03,方法2:将BCD码除以10H,恰好是将BCD码分别移到了A、B的低4位。然后再各自与30H相或,即成为ASCII码。,第四章 程序设计,07:09:03,ORG 0000H MOV A,20H MOV B,#10H DIV AB ORL B,#30H MOV 22H,B ORL A,#30H MOV 21H,A SJMP $ END,简单程序例1-方法2,源程序如下:,0011,0100,PC,PC,0011 0100,0001 0000,PC,0011,0000,0000 0100,PC,0011 0100,PC,PC,PC,0011,PC,07:09:03,基本步骤,题意分析 画出流程图 分配内存及端口 编制源程序 仿真、调试程序 固化程序,07:09:03,例4.2.6相似(p72)有两组BCD码分别存放在23H、22H单元和33H、32H单元,求它们的和并送入43H、42H单元中去。(高位在前,低位在后),分析:,0011,1000,0110,0101,0001,0001,1000,0111,BCD码83H,BCD码11H,BCD码78H,BCD码56H,07:09:03,ORG 0000H MOV A,22H ADD A,32H DA A MOV 42H,A MOV A,23H ADDC A,33H DA A MOV 43H,A SJMP $ END,此条加法指令可否改用带进位的(ADDC)?,07:09:03,ORG 2000H CLR C MOV A,22H ADD A,32H DA A MOV 42H,A MOV A,23H ADDC A,33H DA A MOV 43H,A SJMP $ END,1000 0011,0101 0110,0001 0001,0111 1000,1000 0011,0111 1000,1111 1011,0110 0001,0001 0001,0101 0110,0110 0111,0110 1000,PC,PC,PC,PC,PC,PC,PC,PC,PC,1111 1011,0110 0001,PC,0110 1000,PC,0110 0111,07:09:03,4.3 分支程序设计,结构特点:不一定按指令的先后顺序依次运行程序,程序的流向有两个或两个以上分支,根据指定条件选择程序的流向。,07:09:03,例4.3.2(p74):已知30H单元中有一变量X,要求编写一程序按下述要求给Y赋值,结果存入31H单元。 1 , X0 Y = 0 , X = 0 1 , X0 题意:根据X的不同,程序编写时有三个出口,即有三个分支!,想一想:程序怎么编写?,0000,0011,1000,0011,4.3 分支程序设计,07:09:03,分支程序实例-三分支程序,开始,XA,A= 1,A= A+1,存结果,结束,Y,Y,N,N,程序框图:,A0?,A=0?,07:09:03,分支程序实例-三分支程序,源程序如下: ORG 2000H MOV A,30H JZ LP1 ;X = 0,转LP1处理 JNB ACC.7,LP2 ;X0,转LP2处理 MOV A,#0FFH ;X0,则Y= 1 SJMP LP1 LP2:MOV A,#01 ;X 0,Y=1 LP1:MOV 31H,A ;存结果 SJMP $ ;循环等待,$表示转至 本地址,此方法适用 于一字节的偏移量,最高位为符号位。,本例与P74例4.3.2相似.,07:09:03,P74 例4.3.2,1.理解DPTR、MOVX、DB的用法. 2.本例若采用CJNE A,#0是否可以?,07:09:03,参照例4.3.3 (P75) 设内部RAM20H单元和30H 单元中分别存放了两个8位的无符号数 X、Y, 若XY 则让P1.0管脚连接的LED亮;若XY 则让P1.1管脚连接的LED亮。,方法1:两个数据做减法SUBB,可根据借位CY来判断两个数的大小!,方法2:两个数据做比较CJNE,再根据是否相等和借位CY来判断两个数的大小!,分支程序实例-数据比较大小,无符号数,07:09:03,霓虹灯的简易原理,P1口满足什么条件点灯吗?,07:09:03,X DATA 20H Y DATA 30H ORG 0030H MOV A,X CLR C SUBB A,Y JC L1 CLR P1.0 SJMP FINISH L1: CLR P1.1 FINISH: SJMP $ END,方法一:编程,为什么 CLR C,07:09:03,X DATA 20H Y DATA 30H ORG 0030H MOV A,X CJNE A,Y,L0 SJMP L1 L0: JC L2 L1: CLR P1.0 SJMP FINISH L2: CLR P1.1 FINISH: SJMP $ END,方法二:编程,回顾CJNE命令(P57),07:09:03,分支程序实例-数据比较大小,例4.3.3 两个有符号数的比较。,问题1:如何表示有符号数呢?,问题2:有符号数怎样比较大小?,1.先判断符号位,负数小;正数大. 2.符号相同,则用减法判断是否有借位.,07:09:03,比较20H和30H单元两个有符号数的大小,结果按下述规律显示在实训板上。 (20H)=(30H),P1.0点亮; (20H)(30H),P1.1点亮; (20H)(30H),P1.2点亮;,教材P84 例4.3.3,有符号数,07:09:03,程序框图,07:09:03,程序清单,X DATA 20H Y DATA 30H ;伪指令 ORG 0030H MOV A,X XRL A,Y ;X,Y进行异或 JB ACC.7,NEXT1 ;二者符号不同,跳转到NEXT1 MOV A,X ;符号相同 CJNE A,Y,NEQUAL;X Y,跳转到NEQUAL CLR P1.0 ;X=Y,点亮P1.0 SJMP FINISH NEQUAL: JC XXY ;X Y,转移到XDY NEXT1: MOV A,X JNB ACC.7,XDY ;判断X的正、负,正则转移到XDY XXY: CLR P1.2 ;X Y,点亮P1.1 FINISH: SJMP $ END,07:09:03,数据比较大小的方法,1无符号数 2有符号数 还可以利用溢出标志OV的状态来判断两个有符号数的大小。具体算法如下: 若X-Y为正数,即CY=0 则 OV=0 时 XY OV=1 时XY,07:09:03,4.4 散转程序,散转程序是指通过修改某个参数后,程序可以有三个以上的流向,多用于键盘程序。 常用的指令是JMP A+DPTR,该指令是把16位数据指针DPTR的内容与累加器A中的8位无符号数相加,形成地址,装入程序计数器PC,形成散转的目的地址。,DPTR,+,A,PC,A中内容为8位无符号数,16位地址数,07:09:03,程序清单如下: JUMP1: MOV DPTR,JPTAB1 ;跳转表首送数据指针 MOV A,R6 ADD A,R6 ;R62A (修正变址值) JNC NOAD ;判有否进位 INC DPH ;有进位则加到高字节地址 NOAD: JMP A+DPTR ;转向形成的散转地址人口 JPTAB1: AJMP OPR0 ;直接转移地址表 AJMP OPR1 . AJMP OPRn,例: 根据R6的内容,转向各自对应的操作程序,1.AJMP 与LJMP的适应范围;(与P56比较) 2.若采用LJMP应如何如修改?,07:09:03,图4.11 指令转移表的存储格式,07:09:03,由于无条件转移指令AJMP是两字节指令,因此控制转移方向的A中的数值为 A=0 转向 AJMP ONE A=2 转向 AJMP TWO A=4 转向 AJMP THREE A=6 转向 AJMP FOUR 程序中,从P3口读入的数据分别为0、1、2、3,因此必须乘以2来修正A的值。如果A=2,散转过程如下: JMP A+DPTR PC=TABLE+2 AJMP TWO,07:09:03,三种无条件转移指令LJMP、AJMP和SJMP 的比较。 三种无条件转移指令在应用上的区别有以下三点: 一是转移距离不同,LJMP可在64 KB范围内转移,AJMP指令可以在本指令取出后的2 KB范围内转移,SJMP的转移范围是以本指令为核心的-126+129 B范围内转移; 二是汇编后机器码的字节数不同,LJMP是三字节指令,AJMP和SJMP都是两字节指令。,07:09:03,三是LJMP和AJMP都是绝对转移指令,可以计算得到转移目的地址,而SJMP是相对转移指令,只能通过转移偏移量来进行计算。 选择无条件转移指令的原则是根据跳转的远近,尽可能选择占用字节数少的指令。例如,动态暂停指令一般都选用SJMP $,而不用LJMP $。,07:09:03,结构特点:利用转移指令反复运行需要多次重复的程序段。 实例:前面用到的延时程序:(DELAY) DELAY: MOV R3, #OFFH DEL2: MOV R4,#0FFH DEL1: NOP DJNZ R4,DEL1 DJNZ R3,DEL2 RET 循环程序的组成: 1. 初始化部分(设定循环次数等)。 2. 循环体(重复执行的部分,用于完成实际操作) 3. 循环控制(不断修改和判别循环变量,直至结束)。 4. 循环结束处理。,4.5 循环程序设计(延时程序分析与设计),07:09:03,延时分析,DELAY: MOV R3, #OFFH ;1T DEL2: MOV R4,#0FFH ;1T DEL1: NOP ;1T DJNZ R4,DEL1 ;2T DJNZ R3,DEL2 ;2T RET ;2T,为什么用延时程序?,1)晶振;(设6MHZ) 2)内循环延时;255 X (2+4)=1530 us 3)外循环延时2+(1530+2+4) X 255=392 ms 或 1530X255=390 ms,07:09:03,延时程序设计,源程序: 指令周期 DELAY: MOV R3, #( X )H 1个T机器 DEL2: MOV R4,#( Y )H 1个T机器 DEL1: NOP 1个T机器 NOP 1个T机器 DJNZ R4,DEL1 2 个T机器 DJNZ R3,DEL2 2个T机器 RET,指令周期、机器周期T机器与时钟周期T时钟的关系: T机器=12T时钟=121/fosc=1s (假设晶振频率fosc为12M),延时时间的简化计算结果: (1+1+2) X Y,延时时间怎样计算?,若想延时100ms,只需修改计数初始值,即 (1+1+2) 125200s=100ms,延时程序,07:09:03,延时程序设计,1S延时程序,源程序: DELAY: MOV R2, #10 DEL2: MOV R3, #100 DEL1: MOV R4,#125(7DH) DEL0: NOP NOP DJNZ R4,DEL0 DJNZ R3,DEL1 DJNZ R2, DEL2 RET,1S延时程序,1)如何精确计算参数?2)理解多重循环,07:09:03,延时程序应用,编程实现P1口连接的8个LED显示方式如下:从P1.0到P1.7的顺序,依次点亮其连接的LED。,07:09:03,依次点亮其连接的LED,ORG 0000H START: MOV R2,#08H ;设置循环次数 MOV A,#0FEH ;送显示模式字 NEXT: MOV P1,A ;点亮二极管 ACALL DELAY RL A ;左移一位,改变显示模式字 DJNZ R2,NEXT ;循环次数减1,不为零,继续点亮 SJMP START ;下面一个二极管 DELAY: MOV R3,#0FFH ;延时子程序开始 DEL2: MOV R4,#0FFH DEL1: NOP DJNZ R4,DEL1 DJNZ R3,DEL2 RET END,07:09:03,数据传送程序,书P86例4.4.6:不同存储区域之间的数据传输: 将内部RAM30H单元开始的内容传送到外部RAM0100H单元开始的区域,直到遇到传送的内容是0为止。,地址指针R0赋初值,(R0)A,A(DPTR), 地址指针增1,地址指针DPTR赋初值,A = 0,N,Y,开始,结束,07:09:03,ORG 0000H MOV R0,#30H ;R0指向内部RAM数据区首地址 MOV DPTR,#0100H ;DPTR指向外部RAM数据区首地址 TRANS: MOV A,R0 ;A(R0) MOVX DPTR,A ;(DPTR)A CJNE A,#00H,NEXT SJMP FINISH ;A=0,传送完成 NEXT: INC R0 ;修改地址指针 INC DPTR AJMP TRANS ;继续传送 FINISH: SJMP $ END,程序清单,07:09:03,4.6 查表程序,表格是事先存放在ROM中的,一般为一串有序的常数,例如平方表、字型码表等。 表格可通过伪指令DB来确定。 通过查表指令 MOVC A,A+DPTR MOVC A,A+PC来实现。,在LED显示和键盘处理程序中将会用到。,07:09:03,P98例4.5.1 用查表法计算平方(一) ORG 0000H MOV DPTR,#TABLE ;表首地址送DPTR MOV A,#05 ;被查数字05A MOVC A,A+DPTR ;查表求平方 SJMP $ TABLE:DB 0,1,4,9,16,25,36,49,64,81 END,07:09:03,P98 用查表法计算平方(二) ORG 0000H 0000H MOV A,#05 ;05 A 0002H ADD A,#02 ;修正累加器A 0004H MOVC A,A+PC ;查表求平方 0005H SJMP $ 0007H: DB 0,1,4,9,16,25,36,49,64,81 END,1)为什么修正A?,07:09:03,4.7 子程序设计,在实际问题中,常常会遇到在一个程序中多次用到相同的运算或操作,若每遇到这些运算或操作,都从头编起,将使程序繁琐、浪费内存。因此在实际中,经常把这种多次使用的程序段,按一定结构编好,存放在存储器中,当需要时,可以调用这些独立的程序段。通常将这种可以被调用的程序段称为子程序。,主要内容: 1. 主程序与子程序的关系 2. 子程序嵌套 3. 子程序的调用与返回,07:09:03,(一)短调用指令,1,短调用指令 ACALL addr11 PC+2PC SP+1SP, PC70(SP) SP+1SP, PC158(SP) addr11 PC100,子程序的调用包含两部分内容: a, 实现转入子程序的入口地址;这主要由调用语句中的addr11或addr16 实现。 b,子程序完成后,能够自动的返回;这是由调用语句执行时依靠堆栈操作已经将返回地址压栈保存,带返回时弹出送PC实现的。,07:09:03,PC高5位 (保持不变),PC低11位,操作码(第一字节),操作数(第二字节),11位转移地址的形成示意图,程序计数器PC,(2)绝对转移指令(短),AJMP addr11 ; PC+2PC, addr11 PC.10PC.0,07:09:03,(二)长调用指令,2, 长调用指令 LCALL addr16 PC+3PC SP+1SP, PC70(SP) SP+1SP, PC158(SP) addr16 PC,子程序的调用包含两部分内容: a, 实现转入子程序的入口地址;这主要由调用语句中的addr11或addr16 实现。 b,子程序完成后,能够自动的返回;这是由调用语句执行时依靠堆栈操作已经将返回地址压栈保存,带返回时弹出送PC实现的。,07:09:03,(三)返回指令,格式:RET (子程序返回 操作码:22H) 操作: (SP) PC158 , SP-1SP (SP) PC 70 , SP-1SP 格式:RETI (中断子程序返回 操作码:32H) 操作: (SP) PC158 , SP-1SP (SP) PC 70 , SP-1SP RETI与RET的区别在于返回主程序后,RETI还要清除相应的中断优先级状态位,使系统响应低优先级的中断。,返回,07:09:03,主程序与子程序的关系,主程序MAIN,返回,LCALL SUB,调用子程序,子程序入口地址,RET,07:09:03,ORG 0100H MAIN: MOV A,#0FEH ;送显示初值 LP: MOV R0,#10 ;送闪烁次数 LP0: MOV P1,A ;点亮LED LCALL DELAY ;延时 MOV P1,#0FFH;熄灭灯 LCALL DELAY ;延时 DJNZ R0,LP0 RL A SJMP LP END,实例:LED灯的闪烁点亮(一),07:09:03,子程序嵌套,子程序嵌套(或称多重转子)是指在子程序执行过程中,还可以调用另一个子程序。,子程序SUB1,主程序MAIN,LCALL SUB1,RET,子程序SUB2,RET,LCALL SUB2,07:09:03,ORG 0100H MAIN: MOV A,#0FEH ;送显示初值 COUN: ACALL FLASH ;调闪烁子程序 RL A ;A左移,下一个灯闪烁 SJMP COUN ;循环不止 FLASH: MOV R0,#10 ;送闪烁次数 FLASH1: MOV P1,A ;点亮LED LCALL DELAY ;延时 MOV P1,#0FFH ;熄灭灯 LCALL DELAY ;延时 DJNZ R0,FLASH1 ;闪烁次数不够10次,继续 RET . DELAY: MOV R3,#0FFH ;延时子程序 DEL2: MOV R4,#0FFH DEL1: NOP DJNZ R4,DEL1 DJNZ R3,DEL2 RET END,LED灯的闪烁点亮(二)子程序嵌套范例,07:09:03,图4.14 子程序两次调用、返回过程示意图,07:09:03,子程序的调用与返回,问题:子程序调用、返回到主程序中的正确位置,并接著执行主程序中的后续指令呢? 为了解决这个问题,我们采用了堆栈技术。,子程序SUB1,主程序MAIN,RET,子程序SUB2,RET,2010,2013,2110,2113,2100,2200,20 13,20,13,PC,21 13,13,21,堆栈指针SP,堆栈,LCALL SUB1,LCALL SUB2,21,13,20,13,07:09:03,1. 堆栈概念 堆栈实际上是内部RAM的一部分,堆栈的具体位置由堆栈指针SP确定。SP是一个8位寄存器,用于存放堆栈的栈底(初始化)地址和栈顶地址。 单片机复位或上电时,SP的初值是07H,表示堆栈栈底为07H, SP中的地址值随着加1后,存入数据。SP的值总是指向最后放进堆栈的一个数,此时,SP中的地址称为栈顶地址。堆栈结构示意图如图4.22所示。,堆栈(参见P105-106),07:09:03,图4.22 堆栈结构示意图,07:09:03,2. 堆栈操作 堆栈有两种最基本操作:向堆栈存入数据称为“入栈”或“压入堆栈”(PUSH);从堆栈取出数据称为“出栈”或“弹出堆栈”(POP)。堆栈中数据的存取采用后进先出方式,即后入栈的数据,弹出时先弹出,类似货栈堆放货物的存取方式,“堆栈”一词因此而得名。 由于单片机初始化的堆栈区域同第1组工作寄存器区重合,也就是说,当把堆栈栈底设在07H处时,就不能使用第1组工作寄存器,如果堆栈存入数据量比较大的话,甚至第2组和第3组工作寄存器也不能使用了。因此,在汇编语言程序设计中,通常总是把堆栈区的位置设在用户RAM区。例如,07:09:03,MOV SP,#60H ;将堆栈栈底设在内部RAM的60H处 3. 堆栈的功能 最初,堆栈是为了子程序调用和返回而设计的,执行调用指令(LCALL、ACALL)时,CPU自动把断点地址压栈;执行返回指令RET时,自动从堆栈中弹出断点地址。 由于堆栈操作简单,程序员也经常用堆栈暂存中间结果或数据。只是使用时需要注意堆栈先进后出的特点。恢复现场的顺序就不能弄反,先保护的DPH后恢复出来。 另外,在子程序调用时,CPU会自动利用堆栈进行保护现场和恢复现场。,07:09:03,4. 堆栈操作与RAM操作的比较 堆栈作为内部RAM的一个特殊区域,又有其独特性,为汇编语言程序设计提供了更多的方便。同内部RAM的操作相比较,使用堆栈有以下优点: (1) 使用内部RAM必须知道单元具体地址,而堆栈只需设置好栈底地址,就可放心使用,无需再记住单元具体地址。 (2) 当我们需要重新分配内存工作单元时,程序中使用内部RAM的地方,都要修改单元地址,而堆栈只需修改栈底地址就行了。,07:09:03,(3) 堆栈所特有的先进后出特点,使得数据弹出之后,存储单元自动回收、再次使用,充分提高了内存的利用率;而内部RAM的操作是不可能实现自动回收再利用的,必须通过编程员的重新分配,才能再次使用。,07:09:03,子程序设计注意事项,(1)要给每个子程序起一个名字,也就是入口地址的代号。 (2)要能正确地传递参数。即首先要有入口条件,说明进入子程序时,它所要处理的数据放在何处(如:是放在A中还是放在某个工作寄存器中等)。另外,要有出口条件,即处理的结果存放在何处。 (3)注意保护现场和恢复现场。在子程序使用累加器、工作寄存器等资源时,要先将其原来的内容保存起来,即保护现场。当子程序执行完毕,在返回主程序之前,要将这些内容再取出,送还到累加器、工作寄存器等原单元中,这一过程称为恢复现场。,例4.6.2 查表子程序(p92)。 注意:1.入口参数和出口参数的位置 2.现场的保护与恢复。,07:09:03,子程序的参数传递 范例:计算平方和c=a2+b2 ORG 0000H ;主程序 MOV SP,#3FH ;设置栈底 MOV A,31H ;取数a存放到累加器A中作为入口参数 LCALL SQR ;计算a2 MOV R1,A ;出口参数平方值存放在A中 MOV A,32H ;取数b存放到累加器A中作为出口参数 LCALL SQR ;计算b2 ADD A,R1 ;求和 MOV 33H,A ;存放结果 SJMP $,P103例4.6.2,07:09:03,;子程序:SQR ;功能:通过查表求出平方值y=x2 ;入口参数:x存放在累加器A中 ;出口参数:求得的平方值y存放在A中 ;占用资源:累加器A,数据指针DPTR SQR:PUSH DPH ;保护现场,将主程序中DPTR的高八位放入堆栈 PUSH DPL ;保护现场,将主程序中DPTR的低八位放入堆栈 MOV DPTR,#TABLE ;在子程序中重新使用DPTR,表首地址DPTR MOVC A, A+DPTR ;查表 POP DPL ;恢复现场,将主程序中DPTR的低八位从堆栈中弹出 POP DPH ;恢复现场,将主程序中DPTR的高八位从堆栈中弹出 RET TABLE: DB 0,1,4,9,16,25,36,49,64,81,与P106例比较参数传递地方法,07:09:03,八路彩灯控制程序(最后),要求:(对应的口为1时点亮) (1)D1D8八个彩灯按规定顺序依次点亮(间隔1秒),最后全亮; (2)按规定顺序依次熄灭(间隔1秒),最后全灭; (3)八个灯同时点亮,保持1秒; (4)八个灯同时熄灭,保持0.5秒; 再将第3、4步重复4遍,最后整个程序再重复N遍。,步骤: (1)绘制流程图 (2)编写程序 (3)调试程序,霓虹红灯设计,07:09:03,ORG 0000H LJMP MAIN ORG 0100H MAIN:MOV R7,#7 LOOP: MOV R6,#16 MOV R5,#4 MOV DPTR,#TABL MOV R4,#0 LOOP1:MOV A,R4 MOVC A,A+DPTR MOV P1,A INC R4 LCALL DELAY LCALL DELAY DJNZ R6,LOOP1 LOOP2: MOV P1,#0FFH LCALL DELAY LCALL DELAY MOV P1,#00H LCALL DELAY DJNZ R5,LOOP2 DJNZ R7,LOOP SJMP $ END,霓虹红灯设计,07:09:03,常用汇编子程序(P118),TABL: DB 01H, 03H, 07H, 0FH, 1FH, 3FH, 7FH,0FFH DB 7FH, 3FH, 1FH, 0FH, 07H, 03H, 01H,00H,07:09:03,500us延时程序 (12Mhz),DELAY: MOV R2, #5 ;1T DEL0: MOV R3, #100 ;1T DEL1: MOV R4, #250 ;1T DEL2: NOP ;1T NOP ;1T DJNZ R4,DEL2 ;2T DJNZ R3,DEL1 ;2T DJNZ R2,DEL0 ;2T RET ;2T,1)晶振;(设12MHZ) 2)内循环延时;250 X (1+1+2)= 1000 us= 1ms 3)二重循环延时;100

温馨提示

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

评论

0/150

提交评论