收藏 分享(赏)

第4章+MCS-51汇编语言程序设计.ppt

上传人:11xg27ws 文档编号:5788268 上传时间:2019-03-17 格式:PPT 页数:180 大小:1.12MB
下载 相关 举报
第4章+MCS-51汇编语言程序设计.ppt_第1页
第1页 / 共180页
第4章+MCS-51汇编语言程序设计.ppt_第2页
第2页 / 共180页
第4章+MCS-51汇编语言程序设计.ppt_第3页
第3页 / 共180页
第4章+MCS-51汇编语言程序设计.ppt_第4页
第4页 / 共180页
第4章+MCS-51汇编语言程序设计.ppt_第5页
第5页 / 共180页
点击查看更多>>
资源描述

1、主 编 范立南 谢子殿 副主编 刘 彤 尹授远 李雪飞,单片机原理及应用教程第4章 MCS-51汇编语言程序设计,4.1 程序设计方法 4.2 汇编语言程序设计方法 4.3 单片机汇编程序结构 4.4 综合编程举例,第4章 MCS-51汇编语言程序设计,4.1 程序设计方法 程序设计就是用计算机所能接受的语言把解决问题的步骤描述出来,也就是编制程序。 常用的MCS-51程序设计语言有MCS-51汇编语言和MBASIC51、C51、PLM51等高级语言。 本节介绍MCS-51汇编语言的程序设计方法。,4.1.1 程序设计步骤用汇编语言编写一个程序的过程可分为以下几个步骤。(1) 根据所要解决的问

2、题进行分析,明确问题的要求。(2) 确定算法。根据实际问题的要求和指令系统的特点,决定所采用的计算公式和计算方法,也就是一般所说的算法。(3) 制定程序框图。根据所选的算法,制定出运算步骤和顺序,把运算过程画成程序框图。(4) 确定数据格式,分配工作单元。(5) 根据程序框图,编写程序。(6) 程序测试。利用单片机仿真器结合单片机目标系统,对程序进行测试。(7) 程序优化。程序优化以缩短程序量、减少运算时间和节省工作单元。,4.1.2 伪指令 一般的汇编语言程序中也包括一些伪指令,但它并不被译成机器码,只是影响到汇编过程。它是用来对汇编过程进行说明和指导的一组命令。每种汇编程序都定义若干条伪指

3、令,不同版本的汇编程序伪指令的符号和含义可能有差异,但基本用法是相似的。 下面介绍一些常用的伪指令。,1. 定位伪指令 ORG m m为十进制或十六进制数。m指出在该伪指令后的指令的汇编地址,即生成的机器指令的起始存储器地址。在一个汇编语言源程序中允许使用多条定位伪指令,但其值应和前面生成的机器指令存放地址不重叠,如:ORG 100H START: MOV A, #30HMOV B, #50H,2. 定义字节伪指令DB X1, X2,Xn Xi为单字节数据,它可以是十进制或十六进制数,也可以是一个表达式。Xi也可以是由两个单引号括起来的一个字符串,这时Xi定义的字节长度等于字符串的长度,每一个

4、字符为一个ASCII码。该伪指令把X1,X2,Xn存入目标程序存储器,通常用于定义一个常数表,如:BTAB:DB 00H, 01H, 02H, 03H, 04H,3. 字定义伪指令 DW Y1, Y2,Yn Yi为双字节数据,它可以是十进制或十六进制数,也可以是一个表达式。该伪指令把Y1,Y2,Yn存入目标程序存储器,经常用于定义一个地址表,如:WTAB:DW 1000H, 2000H, 3000H, 7890H, 4567H,4. 字或字节赋值伪指令标号 EQU m该伪指令把值m赋给前面的标号,在程序中标号和m是等价的,如:DBUF EQU 30H则符号DBUF等价于30H。在程序中可对DB

5、UF进行赋值,实际上是对内部RAM的30H写一个值。,5. 位赋值伪指令标号 bit n该伪指令把值n赋给前面的标号,n一般指位地址,在程序中标号和n是等价的。如:HIGH bit 20H则HIGH等价于位地址20H(22H).0),1HIGH等价于120H等价于1(22H).0。,6. 汇编结束伪指令END该伪指令指出结束汇编,即使后面还有指令,汇编程序也不作处理。,7. 标号和注释 汇编程序允许用户在源程序中使用标号和注释。标号加在指令之前,标号必须以字母开始,后跟18个字母或数字,并以冒号“:”结尾,用户定义的标号不能和汇编保留符号(包括指令操作码助记符以及寄存器名等)重复。标号的值是它

6、后面的指令存储地址。注释是用户对某一条指令或某一段程序的功能说明,它必须以分号“;”开始,如果一行写不下,可以另起一行,但都必须以分号“;”开始。下面为含有标号和注释的程序行格式。 标号: 操作码(空格)操作数1, 操作数2, 操作数3;注释,4.1.3 汇编语言源程序的编程和汇编1. 编程 汇编语言编程时大多在PC中用文本编辑器(如EDIT)编写,目前几乎所有的单片机仿真器所配的软件均有文本编辑器。如南京伟福WAVE 6000 for Windows、Keil Vision2等软件。只要运行软件后进入程序编辑状态即可编写程序。,2. 汇编 汇编语言必须经过机器汇编或人工汇编才能得到相应的机器

7、程序,即目标程序,以供单片机识别和执行。由于人工汇编工作量大,容易出错,现已不用。机器汇编一般是在PC上利用一些汇编软件进行。目前几乎所有的单片机仿真器配的开发软件都有汇编程序,在源程序编写完成后使用汇编功能菜单即可进行对源程序汇编。在汇编时若发现源程序有语法错误或跳转超出范围等情况,系统会将错误显示给用户。用户在改正错误后,需再对源程序进行汇编,直到源程序完全没有语法错误。此时汇编程序会生成与其对应的目标文件。一般情况下是生成HEX(十六进制)和BIN(二进制)文件。没有语法错误并不等于程序开发成功,一般来说还要对程序进一步调试、修改,运行无误后,程序才算最终完成。这时才可将目标文件写入到程

8、序存储器中。,4.2 汇编语言程序设计方法 单片机应用系统软件一般由汇编语言或其他高级语言写成,一个单片机程序中由主程序、若干个子程序、中断程序组成,从程序结构上分为顺序程序、分支程序、循环程序、子程序、中断程序等。,4.2.1 顺序程序 顺序程序在单片机中是最简单的程序片段,在顺序程序中没有判断、没有分支。只是顺序向下执行。如单片机开始时对内部或外部资源初始化的程序就是一个典型的顺序程序。,【例4.1】 以下是对串行口工作方式初始化的程序。 TX:MOV R2,#03HMOV TMOD,#20HMOV TH1,#0F3HMOV TL1,#0F3HMOV SCON,#0E0HMOV PCON,

9、#080H,SETB TR1SETB 7FHMOV 65H,#00HMOV 64H,#20HMOV 63H,#00HMOV 62H,#01HMOV 61H,#00HSETB EASETB ES,4.2.2 分支程序 分支程序就是在程序执行过程中要判断某些条件,当条件成立后程序转移到不同的功能处运行。在MCS-51单片机中条件转移指令都可以用在分支程序中。 测试条件符合转移,如:JNB TI, $CLR TI,比较不相等转移,如:CJNE R0, #2FH, LOOPRET 减1不为0转移,如:DJNZ R7, LOOPRET 根据某些单元或寄存器的内容转移,如:JMP A+DPTR,4.2.3

10、 循环程序循环程序是一段可以反复执行的程序,这时可用循环程序结构,这有助于缩短程序,提高程序质量。一个循环程序结构由以下3部分组成。 循环体:就是要求某一段程序重复执行的程序段部分。 循环结束条件:在循环程序中必须有循环结束条件。常用的循环结束条件是计数循环。 循环初值:用于循环过程的工作单元,在循环开始要赋初值。下面通过一些实例,说明如何编制循环程序。,1. 单重循环 计算几个数据的和,计算公式为,如果直接按这个公式编制程序,则n=11时,需要编写连续10次加法。这样程序太长,并且对于n可变时,将无法编制出顺序程序。因而上面的公式要改成易于在单片机中实现的形式:,当i=n时,yn+1即为所求

11、n个数据之和y。这种形式的公式叫递推公式。在用单片机的汇编程序实现时,yi是一个变量,这可用式(4-3)表示:,根据这个公式,可以画出程序框图,如图4.1所示。,图4.1 求数据和程序框图,【例4.2】 有n个单字节数,并按一定的顺序存放在MCS-51单片机内部RAM从40H开始的单元中,n放在R2中,编写求和程序,结果放在R3R4中。,ADD1: MOV R3, #0HMOV R4, #0HMOV R0, #40H LOOP: MOV A, R4ADD A, R0MOV R4, AINC R0CLR AADDC A, R3MOV R3, ADJNZ R2, LOOPRET,【例4.3】 设在

12、外部RAM中放有一个ASCII字符串,它的首址在DPTR中,字符串以0结束。现在要求用MCS-51单片机的串行口将字符串发送出去。在串行口已经初始化的情况下,程序框图如图4.2所示。,图4.2 发送字符串程序框图,SOUT: MOVX A,DPTRJNZ SOT1RET SOT1: JNB TI,SOT1CLR TIMOV SBUF,AINC DPTRSJMP SOUT,2. 多重循环 如果一个循环程序中包含了其他循环程序,那么该循环程序称多重循环程序。在单片机系统中常用到多重循环程序。 最简单的多重循环程序是由DJNZ指令构成的软件定时程序,它是较常见的程序之一。 【例4.4】 50ms延时

13、程序。 软件延时程序与MCS-51单片机的指令构成有很大的关系。在时钟为12MHz时,一个机器周期为1s。DJNZ指令执行时间为2s。可用双重循环完成如下的软件延时50ms的程序。,DEL: MOV R7,#200 DEL1: MOV R6,#123NOPDJNZ R6,$DJNZ R7,DEL1RET,4.3 单片机汇编程序结构 一个完整单片机的程序由多个功能模块组成,其中主程序是必须的,其他功能子程序则根据实际的系统情况可有可无,而子程序由主程序调用,中断服务程序则根据中断条件决定是否执行。,4.3.1 程序总体结构 MCS-51单片机的汇编程序由主程序、若干个子程序、中断服务程序等组成。

14、 由于MCS-51单片机复位后PC=0000H,也就是程序从程序存储器的0000H开始执行,由于MCS-51单片机程序存储器的0003H、000BH、0013H、001BH、0023H分别是外部中断0、定时器0、外部中断1、定时器1、串行口的中断入口地址,所以主程序开始的地址一般安排在0030H之后的程序存储器中。一般在程序存储器的0000H开始放一条无条件转移指令(AJMP、LJMP、SJMP)转到主程序的开始处。如果要使用某些中断,则在相应的中断入口地址也放一条无条件转移指令,多数情况下用LJMP指令,这是因为使用LJMP指令可使中断服务程序在单片机程序存储器中的任意位置编写。图4.3是M

15、CS-51单片机的程序总体结构图。,图4.3 MCS-51单片机程序总体结构,在MCS-51单片机汇编程序中,主程序是必须有的,而子程序及中断服务程序则根据具体系统可有可无。如果系统功能比较简单,则不需要子程序,一些具体功能在主程序中就可实现。对于中断服务程序也不是全用甚至一个也没有,在不用的中断入口处可什么都不写,同时也要在程序中将对应的中断关闭。值得注意的是在图4.3中,中断服务程序和功能子程序与主程序不是并列的,一般中断服务程序与功能子程序是依次安排在主程序的后面,如果有常数表的话,可将表安排在所有程序的后面。以下是一个实际汇编程序的结构程序片段。,ORG 0000HAJMP MAIN

16、;转主程序ORG 0003HLJMP INT00ORG 000BHLJMP T000ORG 0030H MAIN:MOV TMOD,#01H ;主程序初始化MOV TH0,#03HMOV TL0,#0F8H,MAIN1:LJMP KEY00 ;调键盘程序LJMP DISP ;调显示程序AJMP MAIN1 ;主程序循环 KEY00: ;键盘程序RET DISP: ;显示程序RET INT00: ;外部中断服务程序RETI T000: ;定时器0中断服务程序RETI TAB:DB 3FH,06H,5BH,4FH,66H;显示字模表END ;汇编结束,4.3.2 主程序 MCS-51单片机的主程序

17、一般是由一些顺序程序组成的,主程序的结构与单片机应用系统及编程者的习惯有关。不同的应用系统其主程序的结构是不同的,编程者的不同习惯也决定着主程序的结构。如有些编程人员习惯将显示程序、键盘程序、数据处理程序等放在定时中断服务程序中,或者根据中断处理的标志执行不同的功能模块。还有一些编程人员习惯将各子程序放在主程序中依次循环调用。但无论哪一种习惯,一般在进入主程序后都要根据具体要求对所用的可编程的硬件资源进行初始化。如MCS-51单片机内部的中断、定时器、串行口以及一些RAM单元等。如有外部扩展可编程芯片也要对其进行初始化,以便使其工作在需要的工作状态下。图4.4是根据中断处理的标志决定执行哪一个

18、功能模块。这种结构的主程序是在初始化后等待定时中断服务程序中处理的标志。如定时器0为10ms中断一次,每次将一个单元的内容加1,如有5个功能模块,单元内容由0加到4再回到0,而主程序可根据此单元的内容调用某一个功能模块。,图4.5是将各功能模块由主程序循环调用的一种结构。这种结构是在主程序初始化后根据系统的要求依次调用各子程序,最后一个子程序执行完后再转回调用第一个子程序。,图4.4 根据中断处理的主程序,图4.5 在主程序中循环调用各子程序,中断方式与循环方式的主程序比较:中断方式比较复杂,而循环调用方式则相对来说要简单得多,并且程序调试时也相对容易。但由于定时中断方式各程序执行的时间间隔固

19、定,而循环调用方式的时间由各子程序的运行时间决定。对于定时中断方式要注意功能模块程序的执行时间不能超过定时时间。 无论是定时调用还是顺序调用方式,由于在主程序后大多会有一些子程序、中断服务程序、数据表等,主程序必须是一个无限循环程序,即主程序要在自己的程序内循环,不能一直执行下去,否则一旦不是在调用状态下进入其他程序,整个程序系统就会紊乱。,4.3.3 子程序 子程序是在MCS-51单片机系统中使用最多的公用程序段,它可被主程序或其他子程序调用,一般情况下不主张子程序调用自己(递归)。因单片机的内部RAM太小,相应堆栈也很小,如重复调用自己,堆栈会马上溢出。 一般情况下单片机的子程序都是具有一

20、定功能的程序模块。在单片机编程时最好根据系统的具体要求,将一些功能模块编制成子程序,如显示模块、键盘模块、数据采集模块、数据处理模块、数据输出模块等。程序调试时在主程序中可分别调用各功能模块,调试哪一个功能就调用哪一个模块,其他模块可暂时关闭,直到每一个模块调试完成后,再根据系统的要求在主程序中将每一个功能模块按一定的顺序进行调用。,子程序的结构如图4.6所示,子程序由子程序名、具体功能程序、子程序返回组成。子程序名在一个单片机程序中是唯一的,不能重复,在汇编语言编写的程序中子程序名就是一个合法的标号。子程序的具体功能就是由一系列指令完成的具有一定功能的程序片段。子程序返回由RET指令完成。在

21、一个子程序中不能向另一个子程序或主程序中转移。,图4.6 子程序结构,4.3.4 中断服务程序 MCS-51单片机一共有5个中断,分别是外部中断0、定时器中断0、外部中断1、定时器中断1、串行口中断。在使用某一中断时,在中断开放状态下,一旦具备中断条件,无论程序运行到何处,程序将立即转入其中断的入口地址,在入口地址安排一条无条件转移指令,转到相应的中断服务程序,中断服务程序执行完后,由中断返回指令RETI返回到断点处。,中断服务程序也是具有一定功能的程序模块,它与子程序的区别是进入方式不同。子程序的进入方式是由主程序或其他子程序进行调用,也就是可在程序中安排何时调用子程序,编程人员是知道子程序

22、何时运行的。而中断服务程序则不同,中断服务程序的进入完全根据中断产生的时刻而定,它是一个随机的事件,可在程序运行时的任何时刻产生。因此编程人员在编制中断服务程序时一定要注意保护好现场,如果中断服务程序中使用工作寄存器,注意一定不要与主程序工作在一个区。,在MCS-51单片机中的5个中断中,只有两个中断优先级,因此在有多个中断情况下要注意安排好中断的优先级别和工作寄存器的保护,以防在中断嵌套时现场被破坏。 中断服务程序的结构与子程序的结构基本相同,所不同的是中断服务程序的返回指令是RETI。 值得注意的是一个中断服务程序的运行时间不能太长,如果两次中断间隔时间小于中断程序的运行时间则会发生中断重

23、入现象,这种情况将导致系统瘫痪。因此在设计中断服务程序时要尽量简短,将一些运行时间长的程序放到主程序或子程序中。中断服务程序的结构如图4.7所示。,图4.7 中断服务程序结构,4.4 综合编程举例 4.4.1 运算程序 在大多数的单片机应用系统中都离不开数值计算,而最基本的数值计算是四则运算。单片机中的数多以二进制形式表示,二进制算法有很多,其中最基本的是定点制与浮点制,本节讨论定点数的各种表示方法,以及它们的运算规则和相应的程序设计方法。4.4.2节将讨论浮点数的各种表示方法及运算规则和相应的程序设计方法。,1. 定点数的表示方法 定点数就是小数点固定的数。它可分为整数、小数、混合小数等。另

24、外按数的正负可分为无符号数和有符号数。 1) 有符号数的表示 在普通算术中,一个负数用在一个负号后紧跟数的数值部分来表示。在计算机中,常在数的表示式中附加一位二进制数来指示这个数是正数还是负数。常用的有符号数的表示法有原码和补码两种。,(1) 原码表示法。 如果在一个无符号数中增加一个符号位,符号位为0表示该数是正数,符号位为1表示该数是负数。 一般符号位均加在数的最前面。例如8位二进制数00110100,表示十进制数+52,而10110100表示-52。这时,用两个字节(16位)能表示的最大数为+32 767,最小数为32 767。原码表示法的优点是简单直观,执行乘除运算及输出、输入都比较方

25、便,缺点是加减运算复杂。,例如把(-52)10与(+5)10相加时,实际上必须执行减法,而不是加法。一般来说,对原码表示的有符号数执行加减运算时,必须按符号位的不同执行不同的运算,运算中符号位一般不直接参加运算。 对于0的原码表示,它的数值等于0,它的符号位可为0,也可为1,故原码表示法有两个0:正0(00000000)2和负0(10000000)2。,(2) 补码表示法。 对于基数为r的数制,定义数N的补码(N补)为: N补=rn-N (4-4) 这里n是数N中整数的位数,对于二进制数,r =2,不管是整数还是小数,可采用把数值位的每位取反后再加1来计算一个数的补码。例如0110100的补码

26、为1001100。 引入补码后,可用补码在计算机中表示带符号的数。这时,一般在数的前面加一位符号位,该位为0表示正数,为1表示负数。对于正数,数值表示法不变;对于负数,采用该数的补码来表示。例如(-52)10,它的8位二进制补码表示为11001100。 在补码表示法中,只有一个0(正0),而数值位等于0的负数为最小负数。例如8位二进制数中,10000000表示(-128)10。这样,用两个字节(16位)可表示的最大数为+32 767,最小数为32 767。,补码表示法的优点是加减运算方便,可直接带符号位进行运算,缺点是乘除运算复杂。例如对8位二进制数补码表示的数:(+83)10= (01010

27、011)2(-4)10=(11111100)2(83)10+(-4)10 =(01010011)2-(11111100)2=(01001111)2=(79)10 执行补码加减运算时,有时会发生溢出,故需对运算结果进行判断。例如对(+123)10+(81)10 =(+204)10的运算,如采用8位二进制补码来进行计算,则运算结果(+204)10无法用8位二进制补码来表示(最大值为+127)。补码运算时,不能像原码运算那样用进位来表示溢出与否。下面用竖式来分析补码运算溢出的判断方法。,(+123)10=(01111011)2(81)10=(01010001)20111 1011+ 0101 000

28、1 1100 1100 这时,最高位(符号位)无进位,而次高位(数值最高位)有进位。在前面介绍的(83)10加(-4)10的运算中,两者都有进位。由此可见,在带符号位的补码加减运算中,如果符号位和数值最高位都有进位或都无进位,则运算结果没有溢出,反之有溢出。为了方便补码运算的溢出判断,MCS-51单片机中有一个OV位,专门用来表示补码加减运算中的溢出情况。 OV=1有溢出,OV=0无溢出。,对于补码表示的数,在执行乘除运算时,采用首先把它们转换成原码,然后再执行原码的乘除运算,最后把积再转换成补码,这样需要进行补码与原码的转换。一个正数的补码与原码相同,不需转换。对于负数,求补码表示的负数的原

29、码或求原码表示的负数的补码,都可采用求它补码的方法,即对于二进制数,可采用先按位取反,然后把结果加1。 【例4.5】 双字节数取补子程序。 功能:(R4R5)取补(R4R5)。 入口:R4R5中存放被取补数。 出口:取补后数仍存放在R4R5中。,程序: CMPT: MOV A, R5CPL AADD A, #1MOV R5, AMOV A, R4CPL A ADDC A, #0MOV R4, ARET,2) 带符号数的移位 在一个采用位置表示法的数制中,数的左移和右移操作分别等价于乘以或除以基数的操作。即对于一个十进制数,左移一位相当于乘以10,右移一位相当于除以10。对于二进制数,左移一位相

30、当于乘以2,右移一位相当于除以2。由于一般带符号数的最高位为符号位,故在执行算术移位操作时,必须保持最高位不变,并且为了符合乘以基数或除以基数的要求,在向左移或向右移时,需选择适当的数字移入空位置。下面以带符号的二进制数为例,说明算术移位的规则。,(1) 正数:由于正数的符号位为0,故左移或右移都移入0。(2) 原码表示的负数:由于负数的符号位为1,故移位时符号位不应参加移位,并保证左移和右移时都移入0。 【例4.6】 双字节原码左移一位子程序。 功能:(R2R3)左移一位(R2R3),不改变符号位,不考虑溢出。 入口:原码双字节存放在R2R3中。 出口:左移后仍存放在R2R3中。,程序: D

31、RL1: MOV A, R3CLR CRLC AMOV R3, AMOV A, R2RLC AMOV A.7, C ;恢复符号位MOV R2, ARET,【例4.7】 双字节原码右移一位子程序。 功能:(R2R3)右移一位(R2R3),不改变符号位。 入口:双字节原码存放在R2R3中。 出口:右移一位后原码存放在R2R3中。 程序: DRR1:MOV A, R2MOV C, A.7 ;保护符号位CLR A.7 ;移入0RRC AMOV R2, AMOV A, R3RRC AMOV R3, ARET,(3) 补码表示的负数:左移操作与原码相同,移入0。右移时,最高位应移入1。由于负数的符号位为1

32、,正数的符号位为0,故对补码表示的数执行右移时,最高位可移入符号位。 【例4.8】 双字节补码右移一位子程序。 功能:(R2R3)右移一位(R2R3),不改变符号位。 入口:双字节补码存放在R2R3中。 出口:右移后双字节补码仍存放在R2R3中。,程序: CRR1:MOV A, R2MOV C, A.7 ;保护符号位RRC A ;移入符号位 MOV R2, AMOV A, R3RRC AMOV R3, ARET,2. 定点数加减运算 1) 补码加减运算 前面已经介绍过,补码表示的数执行加减运算非常方便。编程序时,只需按所采用的计算机指令直接编出相应的加法和减法程序即可。下面举例说明具体编程方法

33、。【例4.9】 双字节补码加法子程序。 功能:(R2R3)+(R6R7)(R4R5)。 入口:R2R3存放被加数,R6R7存放加数。 出口:结果存放在R4R5中。 出口时OV=1表示溢出。,程序: NADD:MOV A, R3ADD A, R7MOV R5, AMOV A, R2ADDC A, R6MOV R4, ARET,【例4.10】 双字节补码减法子程序。 功能:(R2R3)-(R6R7)(R4R5)。 入口:R2R3存放被减数,R6R7存放减数。 出口:结果存放在R4R5中。 出口时OV=1表示溢出。 程序: NSUB1:MOV A, R3CLR CSUBB A, R7MOV R5,

34、AMOV A, R2SUBB A, R6MOV R4, ARET,2) 原码加减运算 对于原码表示的数,不能直接执行加减运算,必须先按操作数的符号决定运算类型,然后再对数值部分执行操作。对加法运算,首先应判断两个数的符号位是否相同,若相同,则执行加法(注意这时运算只对数值部分进行,不包括符号位),加法结果有溢出,则最终结果溢出,无溢出时,结果的符号位与被加数相同。如两个数的符号位不相同,则执行减法,如果够减,则结果的符号位等于被加数的符号位;如果不够减,则应对差取补,而结果的符号位等于加数的符号位。对于减法运算,只需先把减数的符号位取反,然后执行加法运算,设被加数(或被减数)为A,它的符号位为

35、A0,数值为A*,加数(或减数)为B,它的符号位为B0,数值位为B*。A、B均为原码表示的数,则按上述的算法可得出图4.8的原码加减运算程序框图。,图4.8 原码加减运算程序框图,【例4.11】 双字节原码加减法子程序。 功能:(R2R3)(R6R7)(R4R5)。 入口:R2R3中存放被减数(或加数),R6R7中存放减数(或加数)。 出口:和(或差)存放在R4R5中。 说明:数据均为原码表示的数,最高位为符号位。DADD为原码加法子程序入口,DSUB为原码减法子程序入口。出口时,CY=1发生溢出,CY=0正常。,程序: DSUB: MOV A, R6CPL A.7 ;取反符号位MOV R6,

36、 A DADD: MOV A, R2MOV C, A.7 ;保存被加数符号位MOV F0, CXRL A, R6MOV C, A.7 ;C=1,两数异号MOV A, R2 ;C=0,两数同号 CLR A, 7 ;清0被加数符号MOV R2, AMOV A, R6CLR A.7 ;清0加数符号 MOV R6, AJC DAB2ACALL NADD ;同号,执行加法MOV A, R4JB A.7, DABE,DAB1:MOV C, F0 ;恢复结果的符号 MOV A.7, CMOV R4, ARET DABE:SETB C ;溢出RET DAB2:ACALL NSUB1 ;异号,执行减法MOV A

37、, R4JNB A.7, DAB1ACALL CMPT ;不够减,取补CPL F0 ;符号位取反SJMP DAB1RET,3. 定点数乘法运算1) 无符号数二进制数乘法 在介绍无符号数二进制乘法时,先回顾一下二进制的手算乘法方法。下式说明了两个二进制数A=1011和B=1001手算乘法步骤:,在手算中,先形成所有部分积,然后在适当位置上累加这些部分积。由于一次只能完成两个数相加,故必须用重复加法来实现乘法,把手算法改用重复加法来实现,如下:,可见,当被乘数和乘数有相同的字长时,它们的积为双字长。重复加法的乘法算法可叙述如下。 (1) 清0累计积。 (2) 从最低位开始检查各个乘数位。 (3)

38、如乘数位为1,加被乘数至累计积,否则不加。 (4) 左移一位被乘数。 (5) 重复步骤(2)(4)n次(n为字长)。,【例4.12】 采用重复加法的双字节无符号乘法。 功能:(R2R3)(R6R7)(R4R5R6R7)。 入口:R2R3中存放被乘数,R6R7中存放乘数。 出口:结果存放在R4R5R6R7中,程序框图如图4.10所示。,程序: NMUL: MOV R4, #0MOV R5, #0MOV R0, #16 ;16位二进制数;右移一位CLR C NMLP: MOV A, R4 ;右移一位RRC AMOV R4, AMOV A, R5RRC AMOV R5, AMOV A, R6RRC

39、AMOV R6, AMOV A, R7RRC AMOV R7, AJNC NMLN ;C为移出的乘数最低位MOV A, R5 ;执行加法,ADD A, R3MOV R5, AMOV A, R4ADDC A, R2MOV R4, A NMLN: DJNZ R0, NMLP ;循环16次MOV A, R4 ;最后再右移一位RRC AMOV R4, AMOV A, R5RRC AMOV R5, AMOV A, R6RRC AMOV R6, AMOV A, R7RRC AMOV R7, ARET,图4.9 无符号二进制数乘法程序框图,图4.10 无符号双字节乘法程序框图,2) 带符号二进制乘法 (1)

40、 原码乘法:对原码表示的带符号二进制数,只需在乘法前,先按正数与正数相乘为正,正数与负数相乘为负,负数与负数相乘为正的原则,得出积的符号(计算机中可用异或操作得出积符),然后清0符号位,执行不带符号位的乘法,最后送积的符号。设被乘数A的符号位为A0,数值为A*,乘数B的符号位为B0,数值为B*,积C的符号为C0,数值为C*,这个算法可用图4.11来表示(图中F0为符号暂存位)。,【例4.13】 原码有符号数双字节乘法。 功能:(R2R3)(R6R7)(R4R5R6R7)。 入口:R2R3中存放被乘数,R6R7中存放乘数。 出口:积存放在R4R5R6R7中。 说明:所有操作数均为原码,符号位在最

41、高位。本程序调用例4.12的无符号双字节乘法子程序。,程序: IMUL: MOV A, R2XRL A, R6MOV C, A.7MOV F0, CMOV A, R2CLR A.7MOV R2, AMOV A, R6CLR A.7MOV R6, AACALLNMULMOV A, R4MOV C, F0MOV A.7, CMOV R4, ARET,(2) 补码乘法:对补码表示的带符号二进制数乘法,除了需像原码乘法一样对符号进行处理外,在被乘数、乘数或积为负数时,还需对负数取补(变成原码)。 补码乘法的程序框图如图4.12所示。这里取补操作对符号位和数值一起进行,如果被乘数为负数,则取补后,最高位

42、(符号位)必然为0,符合无符号二进制数运算的要求。调用无符号数乘法子程序后,乘积的最高位总是0,如乘积为负数(符号标志等于1),则取补后,最高位必然为1,即为积的符号位(负数)。 (2) 补码乘法:对补码表示的带符号二进制数乘法,除了需像原码乘法一样对符号进行处理外,在被乘数、乘数或积为负数时,还需对负数取补(变成原码)。 补码乘法的程序框图如图4.12所示。这里取补操作对符号位和数值一起进行,如果被乘数为负数,则取补后,最高位(符号位)必然为0,符合无符号二进制数运算的要求。调用无符号数乘法子程序后,乘积的最高位总是0,如乘积为负数(符号标志等于1),则取补后,最高位必然为1,即为积的符号位

43、(负数)。,图4.11 原码乘法程序框图,图4.12 补码乘法程序框图,这种补码乘法,采取先变成原码,然后再执行乘法。3) MCS-51快速乘法 使用重复加法的乘法速度比较慢,例如前面介绍的无符号双字节乘法,对于使用晶振频率为12MHz的MCS-51来说,平均需320s。在实时控制应用场合中,经常需要在100s内完成一次双字节乘法。因此需要设计一种快速乘法。 MCS-51有一条乘法指令:MUI AB。它执行(A)(B)BA操作,即单字节乘以单字节,积为双字节的运算。由于单字节运算不能满足实际需要,故必须把它扩展为双字节的乘法,扩展时可按照以字节为单位的竖式乘法来编写程序。下面以无符号双字节乘法

44、为例,说明这条乘法指令的扩展使用方法。,【例4.14】 无符号双字节快速乘法。 功能:(R2R3)(R6R7)(R4R5R6R7)。 入口:R2R3中存放被乘数,R6R7中存放乘数。 出口:积存放在R4R5R6R7中。,程序: QMUL:MOV A, R3MOV B, R7MUL AB ;(R3)*(R7)XCH A, R7 MOV R5, B ;(R7)=(R3*R7)MOV B, R2MUL AB ;(R2)*(R7) ADD A, R5MOV R4, ACLR AADDC A, BMOV R5, A ;(R5)=(R2*R7)MOV A, R6MOV B, R3,MUL AB ;(R3)

45、*(R6)ADD A, R4XCH A, R6XCH A, BADDC A, R5MOV R5, AMOV F0, C ;暂存CYMOV A, R2MUL AB ;(R2)*(R6)ADD A, R5MOV R5, ACLR AMOV A.0, CMOV C, F0 ;加以前加法的进位ADDC A, BMOV R4, ARET,计算原理如下式:,该竖式中(R3R7)L表示(R3)(R7)的低位字节,(R3R7)H表示(R3)(R7)的高位字节,只要按这个竖式,利用MCS-51的乘法和加法指令,就能完成双字节乘法。以上程序完成的是双字节乘以双字节,称为四字节的乘法。对于其他各种字节的乘法,也可用

46、竖式来分析,例如双字节乘以三字节或单字节乘以四字节等,用此法可容易的编出相应的程序。,4. 定点数除法1) 无符号二进制数除法 正如乘法能由一系列加法和移位操作实现一样,除法也可由一系列减法和移位操作实现。为了设计出除法的算法,先分析二进制数的手算除法。下式说明两个二进制数A=100100和B=101的手算除法步骤:,可以看出,商位是以串行方式获得的,下次得一位。首先把被除数的高位与除数相比较,如被除数高位大于除数,则商位为1,并从被除数中减去除数,形成一个部分余数;否则商位为0,不执行减法。然后把新的部分余数左移一位,并与除数再次进行比较。循环此步骤,直到被除数的所有位都处理完为止,一般商的

47、字长为n,则需循环n次。这种除法上商前,先比较被除数与除数,根据比较结果,决定商1或0,并且只有在商为1时,才执行减法,因此称之为比较法。根据这个算法,可画出适于计算机编程的框图,如图4.13所示。,从前面所示的手算除法中,可以看出被除数的字长比除数和商的字长要长,一般在计算机中,被除数均为双倍字长,即如果除数和商为双字节,则被除数为四字节。由于商为单字长,故如果在除法中发生商大于单字长,称为溢出。在进行除法前,应该检查是否会发生溢出。一般可在进行除法前,先比较被除数的高位与除数,如被除数高位大于等于除数,则溢出,应该置溢出标志,不执行除法。另外,从手算除法中还可看出,如果除数和商为3位,被除

48、数为6位,则执行比较或减法操作时,部分余数必须取4位,除数为3位,否则有可能产生错误。例如第3步的比较和减法运算时,部分余数为1000,如果只取3则为000,所以在实际编程时,必须注意到这一点。,【例4.15】 采用比较法的无符号双字节除法。 功能:(R2R3R4R5)/(R6R7)(R4R5),余数为(R2R3)。 程序框图如图4.14所示。,图4.13 比较除法程序框图,图4.14 无符号双字节除法程序框图,说明:在这个框图中,(R2R3R4R5)为被除数,同时(R4R5)又是商。运算前,先比较(R2R3)和(R6R7),如(R2R3)(R6R7)则为溢出,置位F0,然后直接返回。否则执行

49、除法,这时出口F0=0。上商时,商1采用加1的方法,商0不加1(无操作)。比较操作采用减法来实现,只是先不回送减法结果,而是保存在累加器A和寄存器R1中,在需要执行减法时,才回送结果。B为循环次数控制计数器,初值为16(除数和商为16位)。运算结束后,(R4R5)为商,(R2R3)为余数,(R6R7)不变。在左移时,把移出的最高位存放到MCS-51的用户标志F0中,如F0=1则被除数(部分余数,有17位)总是大于除数,因为除数最多只有16位,这时必然执行减法并商1。,入口:R2R3R4R5中存放被除数,R6R7中存放除数。 出口:商存放在R4R5中,余数存放在R2R3中。 程序: NDIV1:MOV A, R3 ;先比较是否发生溢出CLR CSUBB A, R7MOV A, R2SUBB A, R6JNC NDVE1MOV B, #16 ;无溢出,进行除法,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 社会民生

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报