




已阅读5页,还剩80页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第四章 汇编语言程序设计,回顾:MCS-51单片机系统硬件资源 MCS-51单片机指令系统,单片机系统应用程序设计: 熟悉单片机的硬件原理 掌握单片机的汇编指令 二者有机的组合,形成系统应用程序,提高单片机控制系统的特性和效率: 熟悉控制系统本身的硬件结构 熟悉编程思路、技巧,掌握编程方法、步骤,4.1 汇编语言程序设计方法 4.2 简单和分支程序设计 4.3 循环和查表程序设计 4.4 子程序和运算程序设计,4.1 汇编语言程序设计方法 4.1.1 程序设计步骤,1、汇编语言程序设计:根据设计任务要求,采用汇编语言编制程序的过程。,2、应用程序设计步骤: 1. 拟定任务书 2. 建立数学模型 3. 建立算法 4. 绘制程序流程图 5. 编制汇编语言源程序 6. 上机调试,注意:汇编调试需要多次试验,4.1.2 程序结构设计的基本方法,汇编语言程序设计基本要求:,高质量、可读性好、存储容量小和执行速度快,汇编程序结构设计的基本方法:,1.简单程序的设计 2.分支程序设计 3.循环程序设计 4.子程序设计 5.查表程序设计 6.散转程序设计,4.2 简单和分支程序设计,4.2.1 简单程序设计,例4.1 请用51汇编指令编写程序,将外部RAM单元中40H单元4位BCD数转换成ASCII码,送到内部RAM单元60H 61H之中。,简单程序:是指程序设计中没有使用转移类指令的程序段。 也称顺序程序或直线程序。 程序执行:按照指令存储位置的先后顺序依次执行,中间不会 有任何分支程序、循环程序等。 程序特点:结构简单,易于阅读理解,大量使用数据传送指令。,解:根据ASCII字符表,十进制数09的ASCII码和它的BCD码之间仅相差30H,本题需要把一个字节的两位BCD数进行拆分,然后分别和30H相加,即得到相应的ASCII码。,参考设计程序如下: ORG 1000H ADDR1 DATA 0040H ADDR2 EQU 60H MOV DPTR,#ADDR1 ; 源地址 = DPTR MOV R0, #ADDR2 ; 目标地址 = R0 MOV R0, #00H ; 目标地址单元清零 MOVX A,DPTR ; 源地址单元中BCD数送A MOV B,A ANL A,#0FH ORL A,#30H ; 完成低位BCD数转换 MOV R0,A ; 存入60H INC R0 MOV A,B ANL A,#0F0H SWAP A ; 高位BCD数送低4位 ORL A,#30H ; 完成高位BCD数转换 MOV R0,A ; 存入61H SJMP $ END,4.2.2 分支程序设计,分支程序的特点是程序中含有转移指令。 由于转移指令有无条件转移和条件转移之分,因此分支程序也可分为无条件分支程序和条件分支程序两类。 无条件分支程序中含有无条件转移指令,因简单这里不作专门讨论;条件分支程序中含有条件转移指令,是我们讨论的重点。,条件分支程序体现了计算机执行程序时的分析判断能力。若某种条件满足,则机器就转移到另一分支上执行程序;若条件不满足,则机器就按原程序继续执行。,MCS-51中,条件转移指令共有13条,分为累加器A判零条件转移、比较条件转移、减1条件转移和位控制条件转移等四类。,例4.2 已知VAR单元内有一自变量X,请按如下条件编出求函数值Y并将它存入FUNC单元的程序。 Y ,解:这是一个三分支归一的条件转移问题,程序实现通常可分为“先分支后赋值”和“先赋值后分支”两种求解办法。现分述如下:,1先分支后赋值。题意告诉我们,自变量X是个带符号数,可采用累加器判零条件转移和位控制条件转移指令来实现,程序流程如图4-1(a)所示。,相应程序为: ORG 1000H VAR DATA 30H FUNC DATA 31H MOV A,VAR ; X送A JZ DONE ; 若X=0,则转DONE JNB ACC.7,POSI ; 若X0,则转POSI MOV A,#0FFH ; 若X0,则1送A SJMP DONE ; 转DONE POSI: MOV A,#01H ; 1送A DONE:MOV FUNC,A ; 存Y值 SJMP $ END,2先赋值后分支。 先把X调入累加器A,并判断它是否为零? 若X0,则A中内容送FUNC单元; 若X0,则先给R0赋值(如1),然后判断A0,则把R0修改成1后送FUNC单元, 程序流程如图4-1(b)所示。,相应程序为: ORG 1000H VAR DATA 30H FUNC DATA 31H MOV R0,#00H MOV A, VAR ; X送A JZ DONE ; 若X = 0,则转DONE MOV R0, #0FFH ; 若X 0,则1送R0 JB ACC.7,DONE ; 若X 0,则1送R0 DONE:MOV FUNC,R0 ; 存Y值 SJMP $ END,例4.3 某系有200名学生参加外语统考,若成绩已存放在MCS-51外部RAM始地址为ENGLISH的连续存储单元,现决定给成绩在95分100分之间学生颁发A级合格证书和成绩在90分94分之间学生颁发B级合格证书。试编制一个程序,可以统计A级和B级证书的学生人数,并把统计结果存入内部RAM的GRADA和GRADB单元。,解:这是一个循环和分支相结合程序, 程序流程图如图4-2所示。,图4 -2 例4.3程序流程图,相应程序为: ORG 1000H ENGLISH DATA 2000H GRADA DATA 20H GRADB DATA 21H MOV GRADA, #00H ; GRADA单元清零 MOV GRADB, #00H ; GRADB单元清零 MOV R2,#0C8H ; 参考总人数送R2 MOV DPTR,#ENGLISH ; 学生成绩始地址送DPTR LOOP: MOVX A,DPTR ; 取某学生成绩到A CJNE A,#5FH,LOOP1 ; 和95作比较,形成Cy LOOP1: JNC NEXT1 ; 若A95,则NEXT1 CJNE A,#5AH,LOOP2 ; 和90作比较 LOOP2: JC NEXT ; A90,NEXT INC GRADB ; 为B级,则GRADB单元内容加1 SJMP NEXT NEXT1: INC GRADA ; A95,则GRADA单元内容加1 NEXT: INC DPTR ; 修改学生成绩指针 DJNZ R2, LOOP ; 未完,则LOOP SJMP $ ; 结束 END,4.2.3 散转程序设计,在利用MCS-51单片机指令设计汇编程序时,有时会遇到一类多分支程序的设计。分支转移的目标地址不是汇编或编程时确定的,而是在程序运行时动态决定的。,MCS-51单片机提供了间接转移指令 JMP A + DPTR, 恰好可以实现这一类转移。其中,DPTR装入多分支转移程序的首地址,用累加器A的内容来动态选择其中的某一个分支予以转移。这样一条指令可实现以DPTR内容为起始地址的256个字节范围的选择转移。,例4.4 已知通过调用键盘控制程序KEYREAD可将按下的按键键值0 15之一读到累加器A,要求编写程序对读入的不同键值,分别转入对应的键控程序段KEY0 KEY15执行。 即要求:当(A)=0时,转键控处理程序KEY0; 当(A)=1时,转键控处理程序KEY1; 当(A)=15时,转键控处理程序KEY15。,解: 对于上述要求的问题,编写程序如下: ORG 1000H ACALL KEYREAD ; 读键值程序 RL A ; 调整 MOV DPTR,#TABLE ; 表首址送DPTR JMP A+DPTR ; 以A中内容为偏移量跳转 TABLE: AJMP K0 ; 读入键为第1个键,转K0执行 AJMP K1 ; 读入键为第2个键,转K1执行 AJMP K15 ; 读入键为第16个键,转K15执行 K0: 第1键处理程序段 K1: 第2键处理程序段 K15: 第16键处理程序段 ,4.3 循环和查表程序设计,4.3.1 循环程序设计 循环程序的特点是程序中含有可以重复执行的程序段,该程序段通常称为循环体。 例如,求100个数的累加和是没有必要连续安排100条加法指令的,可以只用一条加法指令并使之循环执行100次。,循环程序的组成(四部分): 1.循环初始化 循环初始化程序段位于循环程序开头,用于完成循环前的准备工作,例如:循环体中循环计数器和各工作寄存器设置初值,其中循环计数器用于控制循环次数。,循环程序设计不仅可以大大缩短所编程序长度和使程序所占存储单元数最少,也能使程序结构紧凑和可读性变好。 应注意循环程序设计并不能缩短完成任务的程序执行时间。,2.循环处理 这部分程序位于循环体内,是循环程序的工作程序,需要重复执行。要求编写得尽可能简练,提高程序执行速度。,3.循环控制 循环控制程序也在循环体内,常常由修改循环计数器内容的语句和条件转移语句等组成,用于控制循环执行次数。,4.循环结束 这部分程序用于存放执行循环程序所得结果以及恢复各工作单元循环前的初值。,循环程序通常有两种编制方法: 一种是先循环处理后循环控制(即先处理后判断),如图4-3(a)所示; 另一种是先循环控制后循环处理(即先判断后处理),如图4-3(b)所示。,(a) 先处理后判断 (b) 先判断后处理 图4-3 循环程序结构类型,解:为了使读者对两种循环结构有一个全面了解,以便进行分析比较,现给出两种设计方案。 1先判断后处理(见图4-4(a)),例4.5 已知内部RAM的BLOCK单元开始有一无符号数据块,块长在LEN单元。请编出求数据块中各数累加和、并存入SUM单元的程序。,(a) 先判断后处理 (b) 先处理后判断 图4-4 例4.5程序流程图,求累加和参考程序: ORG 1000H LEN DATA 20H SUM DATA 21H BLOCK DATA 22H CLR A ;A清零 MOV R2,LEN ;块长送R2 MOV R1,#BLOCK ;块始地址送R1 INC R2 ;块长+1 SJMP CHECK LOOP: ADD A,R1 ;A+(R1)送A INC R1 ;修改数据块指针R1 CHECK: DJNZ R2,LOOP ;若未完,则转LOOP MOV SUM,A ;存累加和 SJMP $ END,2先处理后判断(见图4-4(b)) 参考程序为: ORG 1000H LEN DATA 20H SUM DATA 21H BLOCK DATA 22H CLR A ;A清零 MOV R2,LEN ;块长送R2 MOV R1,#BLOCK ;数据始地址送R1 NEXT: ADD A,R1 ;A+(R1)送A INC R1 ;修改数据块指针R1 DJNZ R2,NEXT ;若未完,则转NEXT MOV SUM,A ;存累加和 SJMP $ END,应当注意:上述两个程序是有区别的。 若块长0,则两个程序的执行结果相同; 若块长0,则先处理后判断程序的执行结果是错误的。 或者说,先处理后判断程序至少执行一次循环体内程序。,例4.6 设单片机MCS-51内部RAM起始地址为30H的数据块中有64个无符号数。试编制一个程序能使它们按从小到大数据排列。,解:设有64个无符号数,在数据块中序号为:e1,e2,e63,e64,使它们按从小到大顺序排列的方法颇多。现以气泡分类法为例加以介绍。,气泡分类法又称两两比较法。 它先使e63和e64比较,若e64 e63,则两个存贮单元中内容交换,反之就不交换; 然后使e62和e63相比,按同样原则决定是否交换; 一直比较下去;最后完成e1和e2比较及交换,经过N-163次比较(常用内循环63次来实现)后,e1位置上必然得到数组中的最大值,犹如一个气泡从水底冒到了水顶,如图4-5所示。 第二次冒泡过程和第一次冒泡过程完全相同,比较次数也可以是63次(其实只需62次),冒泡后可以在e2位置上得到次最大值,如图4-5所示。 冒泡循环次数计算: (以 64个数的排序为例) 大循环(外循环)共63次; 内循环:共6363次。 完成64个数的排序需要外循环63次、内循环3969次。,第一次冒泡排序(比较5次) N=6时 比较1 比较2 比较3 比较4 比较5,第二次冒泡排序(比较4次) N=6时 比较1 比较2 比较3 比较4,第三次冒泡排序(比较3次) N=6时 比较1 比较2 比较3,第四次冒泡排序(比较2次) N=6时 比较1 比较2,第五次冒泡排序(比较1次) N=6时 比较1,其实,64个无符号数的数组排序需要冒泡63次的机会是很少的,每次冒泡所需的数据比较次数,也是从63逐次减少(每冒一次泡减少一次比较)。 为了禁止那些不必要的冒泡次数,人们常常设置一个“交换标志位”。“交换标志位”在循环初始化时清零,在数据交换时置位成1(表示冒泡中进行过数据交换)。 “交换标志位”用来控制是否再需要冒泡: 若“交换标志位”为1,则表明刚刚进行的冒泡中发生过数据交换(即排序尚未完成),应继续进行冒泡; 若“交换标志位”为0,则表明刚进行完的冒泡中未发生过数据交换(即排序已完成),冒泡应该禁止。 例如,对于一个已经排好序的数组:1,2,3,63,64,排序程序只要进行一次冒泡便可根据“交换标志位”状态而结束排序程序的再执行,这自然可以节省63162次的冒泡时间。冒泡程序流程如图4-6所示。,图4-6 冒泡程序流程图,参考程序为: ORG 1000H BUBBLE: MOV R0,#30H ;置数据块指针R0 MOV R2,#64 ;块长送R2 CLR 7FH ;交换标志2FH.7清零 DEC R2 ;块长1为比较次数 BULOOP: MOV 20H,R0 ;e送20H MOV A,R0 ;e送A INC R0 MOV 21H,R0 ;e送21H CJNE A,21H,LOOP ;(20H)和(21H)比较 LOOP: JC BUNEXT ;若(20H) (21H),则BUNEXT MOV R0,20H ;若(20H) (21H),则两者交换 DEC R0 MOV R0,21H INC R0 ;恢复数块指针 SETB 7FH ;置“1”交换标志位 BUNEXT:DJNZ R2,BULOOP ;若一次冒泡未完,则BULOOP ; R2=0? JB 7FH,BUBBLE ;若交换标志位为1,则BUBBLE SJMP $ ;结束 END,在以上循环程序的实例中,单循环程序结构比较简单,程序每循环一次,其循环体就被执行一次。双循环(或多循环)程序就不同了,外循环一次内循环执行一圈。因此,在双重循环和多重循环程序设计中,内层循环体前应注意安排循环初始化,内外循环间也不应相互交叉。,4.3.2查表程序设计,查表是根据存放在ROM中数据表格的项数来查找和它对应的表中值。方法简便,可缩短程序长度和提高程序执行效率。,例如:查Y=X2(设X为09)的平方表时,可以预先计算出X为09时的Y值作为数据表格的内容,存放在起始地址为DTAB的ROM存储器中,并使X的值和数据表格的项数(所查数据的实际地址对DTAB的偏移量)一一对应。这样,就可以根据DTABX来找到X对应的Y值。,采用MCS-51汇编语言进行查表尤为方便,它有两条专门的查表指令: MOVC A, A+DPTR MOVC A, A+PC 第一条查表指令采用DPTR存放数据表格的起始地址,其查表过程比较简单。查表前要把数据表格起始地址存入DPTR,然后把要求查表的项数折算成相对数据表始地址的偏移量,送入累加器A,最后使用MOVC A, A+DPTR完成查表。,采用MOVC A, A+PC指令查表,其步骤分为如下三步。 (1) 使用传送指令把所查数据表格的项数送入累加器A.,(2) 使用ADD A,#data指令对累加器A进行修正。data值由下式确定。,PC + data = 数据表起始地址DTAB,其中,PC是查表指令MOVC A,A+PC的下一条指令码的起始地址。,data值实际等于查表指令和数据表存放初始地址之间的字节数。,(3)采用查表指令MOVC A,A+PC完成查表。,查表程序主要用于线性化处理、代码转换、代码显示、实时值的查表计算和按命令号实现转移等。,注意:MOVC A, A+DPTR指令可以实现64K地址范围内的数据查寻,而MOVC A,A+PC指令只能实现256字节范围内的数据查寻。,例4.7 已知BLOCK1为起始地址的数据块(数据块长度在LEN单元),数块中每个存储单元中的高、低4位分别为两个十六进制数,请编程把它们转换为相应ASCII码,并存放在BLOCK2开始的连续存储单元(低4位ASCII码在前,高4位ASCII码在后)。,解:由于每个存储单元中放有两个十六进制数,因此每个存储单元中十六进制数应分别转换成ASCII码。这就需要两次使用查表指令MOVC A,A+PC,这两条查表指令在程序中位置是不相同的,故两次对PC调整的值也不相同。在编程时,可以先把整个程序编完,然后再计算两条加法指令中的data修正值并填入相应位置。,相应参考程序为: ORG 1000H LEN DATA 30H BLOCK1 DATA 31H BLOCK2 DATA 51H MOV R0,#BLOCK1 ;BLOCK1送R0 MOV R1,#BLOCK2 ;BLOCK2送R1 LOOP: MOV A,R0 ;取源数据块中数 ANL A,#0FH ;取出低4位,ADD A,#17 ;第一次地址调整 MOVC A,A+PC ;第一次查表 MOV R1,A ;存第一次转换结果 MOV A,R0 ;重新取出被转换数 SWAP A ;高4位调入低4位 ANL A,#0FH ;取出低4位 ADD A,#09 ;第二次地址调整 MOVC A,A+PC ;第二次查表 INC R1 ;修改目的数据块指针 MOV R1,A ;存第二次转换结果 INC R0 ;修改源数据块指针 INC R1 ;修改目的数据块指针 DJNZ LEN,LOOP ;若未转换完,则转LOOP SJMP $ ASCTAB: DB 0,1,2,3,4 DB 5,6,7,8,9 DB A,B,C,D,E,F END,例:设有一巡回检测报警装置,需对16路输入量进行测量控制,每路有一个最大允许值。控制时根据测量的路数,找出该路的最大允许值。测量的路数保存在R2中,最大值结果保存在R3R4中。,解:利用查表程序完成。 LTB: MOV A,R2 ADD A,R2 MOV R3,A ADD A, #6 MOVC A,A+PC XCH A,R3 ADD A, #3 MOVC A, A+PC MOV R4,A RET MAX: DW 1520,3721,445,7850 DW 3483,32657,883,9943 DW 1101,40511,6756,331 DW 4468,5871,13224,9981,4.4 子程序和运算程序设计,子程序和运算程序是实用程序的两大支柱程序,在汇编语言程序设计中占有极其重要的地位。,4.4.1 子程序设计 子程序是指完成确定任务并能为其他程序反复调用的程序段。 调用子程序的程序叫做主程序或称调用程序。,例如:代码转换、通用算术及函数计算、外部设备的输入/输出驱动程序等等,都可以编成子程序。,只要在主程序中安排程序的主要线索,在需要调用某个子程序时采用LCALL或ACALL调用指令,便可从主程序转入相应子程序执行,CPU执行到子程序末尾的RET返回指令,即可从子程序返回主程序断点处执行。,在工程上,几乎所有实用程序都是由许多子程序构成的。子程序可以构成子程序库,集中存放在某一存储空间,任凭主程序随时调用。 采用子程序设计能使整个程序结构简单,缩短程序设计时间,减少对存储空间的占用。 例如:如果某一实用程序需要10次调用某一子程序,那么只要在主程序的相应地安排10条调用指令就可以避免把同一子程序编写10遍,内存空间几乎可以减少9倍子程序的长度。 主程序和子程序是相对的,没有主程序也不会有子程序。同一程序既可以作为另一程序的子程序,也可以有自己的子程序。即子程序是允许嵌套的,嵌套深度和堆栈区的大小有关。 总之,子程序是一种能完成某一专用任务的程序段,其资源需要为所有调用程序共享,因此,子程序在结构上应具有通用性和独立性,在编写子程序时应注意以下问题。,使用注意事项: 1)子程序的第一条指令地址称为子程序的始地址或入口地址。该指令前必须有标号,标号应以子程序任务定名,以便一看就一目了然。 例如:延时程序常以DELAY作为标号。,2)主程序调用子程序是通过安排在主程序中的调用指令实现的,子程序返回主程序一般执行安排在子程序末尾的一条RET返回指令。,3)主程序调用子程序和从子程序返回主程序,计算机能自动保护和恢复主程序的断点地址。但对于各工作寄存器、特殊功能寄存器和内存单元中内容,如果需要保护和恢复,就必须在子程序开头和末尾(RET指令前)安排一些能够保护和恢复它们的指令。,4)为使所编子程序可以放在64KB内存的任何区域并能为主程序调用,子程序内部一般使用相对转移指令而不使用其他转移指令,以便汇编时生成浮动代码。,5)子程序参数可以分为入口和出口参数两类:入口参数是指子程序需要的原始数,由调用它的主程序通过约定的工作寄存器R0R7、特殊功能寄存器SFR、内存单元或堆栈等预先传送给子程序使用:出口参数是由子程序根据入口参数执行程序后获得的结果参数,应由子程序通过约定的R0R7、SFR、内存单元或堆栈等传递给主程序使用。,传送子程序参数的方法通常有以下几种: 1)利用寄存器或片内RAM传送子程序参数 对于某些简单子程序、入口参数和出口参数通常较少。常可采用本传送参数的方式。例如:CPU可以预先在主程序中把乘数和被乘数送入R0 R7,转入乘法子程序执行后得到的乘积也可通过R0R7传送给主程序。 2)利用寄存器传送子程序参数的地址 如果上述方法不太方便,CPU也可在主程序中把子程序入口参数地址通过R0R7传送给子程序,子程序根据R0R7中入口参数地址便可找到入口参数并对它们进行相应的操作,操作得到的出口参数也可把它们的地址通过寄存器R0R7传送给主程序。,3)利用堆栈传送子程序参数 任何符合先进后出或后进先出原则的片内RAM区都可称为堆栈。堆栈中数据的存取是由堆栈指针SP指示的。因此,堆栈也可用来传送子程序参数。例如:CPU可以通过主程序中的PUSH指令把入口参数压入堆栈传送给子程序,子程序的出口参数也可通过堆栈传送给主程序。 4)利用位地址传送子程序参数 如果子程序的入口参数是字节中的某些位,那么利用本方法传送入口和出口参数也有方便之处,传送参数过程和上述诸方法类似。 子程序参数的上述传递方法也适用于中断服务程序的编制。 例4.8 设MDA和MDB内有两个数据a和b,请编制出求c = a2+b2并把c送入MDC的程序,设a和b皆为小于10的整数。,解:本程序由两部分组成:主程序和子程序。主程序通过累加器A传送子程序的入口参数a或b,子程序也通过累加器A传送出口参数a或b给主程序,子程序为求一个数的平方的通用子程序。相应程序如下: ORG 1000H MDA DATA 20H MDB DATA 21H MDC DATA 22H MOV A,MDA ;入口参数a送A ACALL SQR ;求a2 MOV R1,A ; a2送R1 MOV A,MDB ;入口参数b送A ACALL SQR ;求b2 ADD A,R1 ; a2 b2送A MOV MDC,A ;存入MDC SJMP $ ;结束,SQR: ADD A,#01H ;地址调整 MOVC A,A+PC ;查平方表 RET ;返回 SQRTAB: DB 0,1,4,9,16 DB 25,36,49,64,81 END 上述程序采用了查表法求一个数的平方,并且通过子程序调用实现了两个数的平方求和,值得注意的是,上述程序仅适应两个数比较小,两个数的平方和不大于用一个字节的数据表示。 例4.9 已知片内RAM中有一个五位BCD码(高位在前,低位在后),最大不超过65535,始地址在R0中,BCD码位数减1(04H)已在R2中,请编出把BCD码转换为二进制整数并存入R4R3中(R4中内容为高8位)中的程序。 解:本题只编出子程序,主程序从略。 算法,图4-7 例4-7 程序流程, 参考程序 入口参数: BCD字节地址指针R0,指数幂R2中。 出口参数: AY值应存于R4R3中(R4中为高字节)。 ORG 1000H BCDB: PUSH PSW ;保护现场 PUSH ACC PUSH B MOV R4,#00H ; R4 清令 MOV A,R0 MOV R3,A ; 万位BCD码送R3 LOOP: MOV A,R3 ; R3送A MOV B,#10 MUL AB ;A 10送BA MOV R3,A ;R310 低位送R3 MOV A,#10 XCH A,B XCH A,R4 ; R310 高位送R4 MUL AB ; R410 ADD A,R4,XCH A,R3 INC R0 ADD A,R0 XCH A,R3 ADDC A,#00H MOV R4,A ; 完成R4R3 R4R3+(R0) DJNZ R2,LOOP ; 若未完,则转LOOP执行。 POP B ; 恢复现场 POP ACC POP PSW RET ; 返回 程序中,R2中初值为位数n减1,对于五位BCD码,R2中初值位4。,4.4.2 运算程序设计,运算程序可分为浮点数运算程序和定点数运算程序两大类。 浮点数就是小数点不固定的数,其运算通常比较麻烦,常由阶码运算和数值运算两部分组成; 定点数就是小数点固定的数,通常包括整数、小数和混合小数等,其运算比较简单,但在数位相同时定点数的表示范围比浮点数的小。 以下只介绍定点数运算程序设计,若无特别说明,则所有程序均指定点数运算程序。 1加减运算程序设计 多字节加、减运算是应用程序设计中经常要进行的一种运算,加、减运算程序可以分为无符号多字节数加减运算和带符号多字节数加减运算程序两种。 无符号多字节加减运算程序 (1)无符号多字节加法运算程序的编制已在前面作过介绍,现以多字节减法程序为例加以介绍。,例4.10 已知BLOCK和BLOCK2为起始地址的存储区中分别有5字节无符号被减数和减数(低位在前,高位在后)。请编制一个减法子程序,令它们相减,并把差值放入BLOCK1为起始地址的存储单元。 解:用减法指令从低字节开始相减。相应程序为: ORG 1000H SBYTESUB: MOV R0,#BLOCK1 ;被减数始址送R0 MOV R1,#BLOCK2 ;减数始址送R1 MOV R2,#05H ;字长送R2 LOOP: CLR C ;Cy清零 MOV A,R0 ;被减数送A SUBB A,R1 ;相减 MOV R0,A ;存差 INC R0 ;修改被减数地址指针 INC R1 ;修改减数地址指针 DJNZ R2,LOOP ;若未完,则LOOP RET END,带符号单字节加减运算程序 带符号单字节加减运算程序和无符号加减运算程序类似,只是符号位处理上有所差别。 例4.11 设在BLOCK和BLOCK+1单元中有两个补码形式的带符号数。请编出求两数之和,并把它放在SUM和SUM+1单元(低8位在SUM单元)的子程序。 解:在两个8位二进制带符号数相加时,其和很可能会超过8位数能表示的范围而需要采用16位数形式来表示,因此,在进行加法时,可以预先把这两个加数扩张成16位二进制补码形式,然后对它完成双字节相加。例如:加数和被加数皆为98(补码为9EH)时,扩张成16位二进制形式后相加的算式为: 98 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 B +) 98 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 B 196 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 0 B,最高进位位丢失不计,换算成真值显然也是196,结果是正确的。 因此,一个8位二进制正数扩张成16位时只要把它的高8位变成全“0”,一个8位二进制负数扩张成16位时需要把它的高8位变成全“1”。据此,我们在编程时应在加减运算前先对加数和被加数进行扩张,然后完成求和。设R2和R3分别用来存放被加数和加数高8位,则相应程序为: ORG 1000H SBADD: PUSH ACC PUSH PSW ;保护现场 MOV PSW,#08H MOV R0,#BLOCK ;R0指向一个加数 MOV R1,#SUM ;R1指向和单元 MOV R2,#00H ;高位先令其为零 MOV R3,#00H MOV A,R0 ;一个加数 JNB ACC.7,POS1 ;若为正数,则转POS1 MOV R2,#0FFH ;若为负数,则全“1”送R2,POS1: INC R0 ;R0指向下一个加数 MOV B,R0 ;取第二加数到B JNB B.7,POS2 ;若是正数,则转POS2 MOV R3,#0FFH ;若是负数,则全“1”送R3 POS2: ADD A,B ;低8位相加 MOV R1,A ;存低8位和 INC R1 ;R1指向SUM+1单元 MOV A,R2 ADDC A,R3 ;完成高8位求和 MOV R1,A ;存高8位和 POP PSW ;恢复现场 POP ACC RET END 在上述程序中,入口:被加数存放在BLOCK,加数存放在BLOCK+1;出口:和的低字节存放在SUM,和的高字节存放在SUM+1。参数传递是利用BLOCK、BLOCK+1、SUM和SUM+1单元实现的。根据本程序,读者编出带符号8位数减法子程序并不困难。,(3)多字节十进制数BCD码减法 由于MCS-51指令系统中只有十进制加法调整指令DA A,也即该指令只有在加法指令(ADD、ADDC)后,才能得到正确的结果。为了用十进制加法调整指令对十进制减法进行调整,必须采用补码相加的办法,用9AH减去减数即得到以十为模的减数的补码。 例4.12 多字节十进制BCD码减法子程序如下: 入口:被减数低字节地址在R1,减数低字节地址在R0,字节数在R2。 出口:差(补码)的低字节地址在R0,字节数在R3。 07H为符号位,“0”为正,“1”为负。 原程序为: ORG 1000H SBCD: MOV R3,#00H ; 差字节数置0 CLR 07H ; 符号位清0 CLR C ; 借位位清0 SBCD1: MOV A,#9AH ; 减数对100 求补码 SUBB A,R0 ADD A,R1 ; 补码相加 DA A ; 十进制相加调整 MOV R0,A ; 存结果,INC R0 ; 地址值增加1 INC R1 INC R3 ; 差字节增加1 CPL C ; 进位位求反,以形成正确的借位 DJNZ R2,SBCD1 ; 未减完,转SBCD1,继续 JNC SBCD2 ; 无借位,转SBCD2 SETB 07H ; 有借位,置“1”符号位 SBCD2: RET ; 返回主程序 程序中,减数求补后与被减数相加,方可利用DA A指令进行调整,若二者相加调整后结果无进位C=0,实际上表示二者相减有借位;若二者相加调整后结果有进位C=1,实际上表示二者相减无借位。为了正确反映其借位情况,必须对其进位标志位C进行求反操作,举例说明如下: 求BCD码8943H - 7649H = ? 先对低位字节运算: 10011010 9A )01001001 49 01010001 51 ;49对100的补码为51 +) 01000011 43 ;加43 10010100 94,0,C = 0无进位,表示二者相减有借位,应对进位标志求反使C = 1。 再对高位字节运算: 10011010 9A )01110110 76 00100100 24 ; 减数76对100的补码为24 )00000001 ; 减去借位位C = 1 00100011 ; 得减数减1后的值为23 +)10001001 ; 加被减数89 10101100 ; +) 01100110 ; 对结果加66修正 00010010 ; 差为12 高位字节减数变补与被减数相加有进位,实际上表示两者相减无借位,为正确反映借位情况,应对进位标志求反使C = 0(减法时C = 1,表示有借位,C = 0,表示无借位)。 最后的运算结果差为1294H,且无借位,计算正确。 2. 乘除法运算程序设计 无符号多字节乘法运算程序,1,例4.13 16位无符号数乘法程序。已知BLOCK1和BLOCK2开始的存储单元内存放有16位乘数和被乘数(低字节在前,高字节在后)。试编程求积并把积放入BLOCK3开始的连续四个存储单元(低字节在前,高字节在后)。 解:MCS-51乘法指令只能完成两个8位无符号数相乘,因此16位无符号数求积必须将它们分解成四个8位数相乘来实现。其方法有先乘后加和边乘边加两种,现以边乘边加进行分析。边乘边加的乘法原理和过程如图4-8所示。图中:ab为16位被乘数(a为高8位,b为低8位)、cd为16位乘数(c为高8位,d为低8位)。第一次乘法完成bd,其积为bdH和bdL(bdH为高8位,bdL为低8位);第二次乘法完成ad,其积为adH和adL(adH为高8位,adL为低8位);同理可以得到的三次和第四次乘积bcHbcL和acHacL,其中bcH和acH分别为高8位。abcd的积共为4字节,分别存放在R0为起始地址的连续4个内存单元。相应参考程序为:,a b c d bdH bdL +) adH adL R2 R3 R0 +) bcH bcL R1 R2 R0+1 +) acH acL R0+3 R0+2 图4-8 边乘边加16位乘法法则示意图 (1)主程序 ORG 1000H MOV R4,BLOCK1 MOV R5,BLOCK1+1 ;乘数送R5R4 MOV R6,BLOCK2,MOV R7,BLOCK2+1 ;被乘数送R7R6 MOV R0,#BLOCK3 ;R0指向积单元始址 ACALL MLTY ;转入乘法子程序 (2)乘法子程序 ;入口参数:R7R6存放被乘数 R5R4存放乘数,R0存放积单元起始地址 MLTY: MOV A,R6 MOV B,R4 MUL AB ;bd = BA MOV R0,A ;bdL送(R0) MOV R3,B ;bdH送R3 MOV A,R7 MOV B,R4 MUL AB ;ad = BA ADD A,R3 ;加法形成Cy MOV R3,A ;bdH+adL送R3 MOV A,B,ADDC A,#00H MOV R2,A ;adH+Cy送R2 MOV A,R6 MOV B,R5 MUL AB ;bc = BA ADD A,R3 INC R0 MOV R0,A ;R3+bcL送(R0+1) MOV A,R2 ADDC A,B ;加法,并形成Cy MOV R2,A ;R2+bcH+Cy送R2 MOV R1,#00H JNC NXET ;若Cy = 0,则NEXT INC R1 ;若Cy 1,则存R1 NEXT: MOV A,R7 MOV B,R5 MUL AB ;ac = B ADD A, R2 INC R0,MOV R0,A ;R2+acL送(R0+2) MOV A,B ADDC A, R1 INC R0 MOV R0,A ;R1+acH+Cy送(R0+3) RET ;返回主程序 END 例4.14 设32位长的被除数已放在R5R4R3R2(R5内为最高字节),16位除数存放在R7R6,请编出使商存于R3、R2和余数存于R5R4的除法程序。该程序应能判定除数为零时转入ERR出错处理程序和商超过双字节时使PSW中F01(否则F0=0)。 解:根据题意,除法执行前后各寄存器分配如图4-9所示。 被 除 数 除 数,(a) 除法执行前寄存器分配 余 数 商 数 除 数 (b) 除法执行后的寄存器分配 图4-9 除法执行前后的寄存器分配 除法运算的法则可采用重复减法,相应算法步骤如下: (1)判断除数是否为零。若除数为零,则转出错处理程序ERR执行。 (2)若除数不为零,则判断商是否大于双字节,即判断R5R4R7R6? 若R5R4R7R6,则商大于双字节,使F0=1和结束除法运算。 (3)若R5R4R7R6,则采用重复比较法求商。由于是16位除法,故比较法求商时比较次数16 送B寄存器,以控制除法的循环次数。 (4)使32位被除数R5R4R3R2左移一位,即扩大两倍,R2最低位空出。 (5)使被除数高16位减去除数。若够减,则在R2最低位上商“1”(即除法完成后R3R2内可得到商,R5R4内得到余数);若不够减,则R2最低位上商“0”。,0,1 0 0 1 0 0 1 0,左移,1,0 0 1 0 0 1 0 0 1 0 1 1 0 1 1 1 0 1 1 1 0 1 0 1,Cy F0,F0=1,Cy=1,+1,0,0 1 1 1 0 1 0 1 1 1 1 0 1 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1,0,+1,0,0 0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 0 1 1 0,0,F0=0,Cy=0,F0=0,Cy=1,0,0 1 1 1 0 1 1 0 1 1 1 0 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 1 1 1 0 1,0,F0=0,Cy=0,+1,-,-
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 卸车岗位安全培训课件
- 2025河南驻马店市正阳县县管国有企业招聘20人(第二批)笔试参考题库附带答案详解
- 2025数字重庆大数据应用发展有限公司校园招聘10人笔试参考题库附带答案详解
- 2025年陕西农业发展集团有限公司(陕西省土地工程建设集团)招聘(200人)笔试参考题库附带答案详解
- 2025年度安徽中国人民健康保险股份有限公司芜湖中心支公司二季度招聘2人笔试参考题库附带答案详解
- 2025年国家能源集团广西电力有限公司高校毕业生春季招聘34人笔试参考题库附带答案详解
- 2025年中国大唐集团科技创新有限公司招聘14人笔试参考题库附带答案详解
- 2025山东万创智能装备科技有限公司招聘17人笔试参考题库附带答案详解
- 2025国网物资有限公司招聘高校毕业生约3人(第二批)笔试参考题库附带答案详解
- 2025四川经准特种设备检验有限公司招聘50人笔试参考题库附带答案详解
- 人教版 2024 版历史八年级上册第五单元 第 13 课《国共合作与北伐战争》检测卷
- 小学数学教师新课标考试试题(含答案)
- 厂房搬迁管理办法
- 保险学考试题(附答案)
- 中药处方点评管理办法
- 国企纪法教育实施路径
- 药品发放登记管理制度
- 临床科室科研管理制度
- 铁艺围栏采购合同
- 中国皮肤基底细胞癌诊疗指南2023
- 卫星通信技术在电力行业中的应用场景分析
评论
0/150
提交评论