第4章 汇编语言程序设计_第1页
第4章 汇编语言程序设计_第2页
第4章 汇编语言程序设计_第3页
第4章 汇编语言程序设计_第4页
第4章 汇编语言程序设计_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

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

文档简介

第4章汇编语言程序设计第4章汇编语言程序设计4-1汇编程序约定4-2汇编程序设计步骤4-3顺序程序4-4分支程序4-5循环程序4-6算术运算程序

4-1

汇编程序约定汇编语言程序:用汇编语言编写的、完成特定功能的指令序列。汇编程序:

能将汇编语言源程序转换成机器语言目标程序的系统软件。

汇编语言程序到机器语言程序的转换过程称为汇编。1、手工汇编:人工查指令表汇编。用于设计短小程序或调试程序的场合。2、机器汇编:用汇编程序进行汇编。源程序使用机器汇编要考虑汇编程序的约定:1〕按指令格式和语法规那么编写程序。常数的表示: 十进制数:20D;D可省:可简写为20 十六进制数:87H,0F0HH不能省 二进制数:01011001BB不能省 字符: ‘H’ 字符串: “Hello〞。2〕使用伪指令提供汇编信息。汇编的主要任务:1〕确定程序中每条汇编语言指令的指令机器码。2〕确定每条指令在存储器中的存放地址。3〕提供错误信息。 4〕提供目标执行文件〔*.OBJ/*.HEX)和列表文件〔*.LST〕。一、汇编语言指令类型:

1.机器指令:

指令系统中的全部指令,每条指令有对应的机器代码。2.伪指令:

汇编控制指令,仅提供汇编信息,没有指令代码。伪指令一般的汇编语言程序中也包括一些伪指令,但它并不被译成机器码,只是影响到汇编过程。它是用来对汇编过程进行说明和指导的一组命令。每种汇编程序都定义假设干条伪指令,不同版本的汇编程序伪指令的符号和含义可能有差异,但根本用法是相似的。下面介绍一些常用的伪指令。二、汇编控制指令(伪指令):常用伪指令及其功能(参见书P46--49)1.定位伪指令(汇编起始地址伪指令)ORGm

m为十进制或十六进制数。m指出在该伪指令后的指令的汇编地址,即生成的机器指令的起始存储器地址。在一个汇编语言源程序中允许使用多条定位伪指令,但其值应和前面生成的机器指令存放地址不重叠,如:

ORG100HSTART: MOVA,#30H MOVB,#50H ……参照书P48指令地址

机器码 源程序

ORG2000H

2000H

7830 MAIN:MOVR0,#30H 2002H

E6 MOVA,@R0

ORG3000H 3000H

23 DB23H,100,‘A’

3001H

64

3002H

41

2.汇编结束伪指令

END

该伪指令指出结束汇编,即使后面还有指令,汇编程序也不作处理。在源程序中只能有一条END指令参照书P46 3.字或字节赋值伪指令 标号EQUm 该伪指令把值m赋给前面的标号,在程序中标号和m是等价的,如: DBUFEQU30H 那么符号DBUF等价于30H。在程序中可对DBUF进行赋值,实际上是对内部RAM的30H写一个值。参照书P48EQU赋值伪指令举例说明:

字符名称EQU项〔数或汇编符号〕例: AA EQU R1 MOV A,AA例: D10 EQU 10 ADD_Y EQU 07ABH MOV A,D10 LCALL ADD_YEQU伪指令是把“项〞赋给“字符名称〞,注意这里的“字符名称〞不同于指令标号〔其后没有冒号〕,但它是必须的。用EQU赋过值的符号名可以用作数据地址、代码地址、位地址或是一个立即数。;(R1)A;10A;调用始于07ABH处子程序

4.定义字节伪指令

DBX1,X2,…,Xn

Xi为单字节数据,它可以是十进制或十六进制数,也可以是一个表达式。Xi也可以是由两个单引号括起来的一个字符串,这时Xi定义的字节长度等于字符串的长度,每一个字符为一个ASCII码。 该伪指令把X1,X2,…,Xn存入目标程序存储器,通常用于定义一个常数表,如:

BTAB:DB00H,01H,02H,03H,04H

参照书P47定义字节伪指令举例说明:

[标号:]DBX1、X2

…Xn ORG 1000H

DB 0AAH

DATA1: DB 25,25H

DATA2: DB 'MCS-51'

经汇编后,从地址1000H处存贮器的内容为:

〔1000H〕=AAH

〔1001H〕=19H

〔1002H〕=25H

〔1003H〕=4DH

〔1004H〕=43H

〔1005H〕=53H

〔1006H〕=2DH

〔1007H〕=35H

〔1008H〕=31H

5.字定义伪指令

DWY1,Y2,…,Yn

Yi为双字节数据,它可以是十进制或十六进制数,也可以是一个表达式。 该伪指令把Y1,Y2,…,Yn存入目标程序存储器,经常用于定义一个地址表,如:

WTAB:DW1000H,2000H,3000H,7890H,4567H参照书P48字定义伪指令举例说明:

[标号:]DWY1,Y2

,…,Yn通知汇编程序从当前ROM地址开始,保存存贮单元,并存入DW后面的数据。存放时高8位在前,低8位在后。

例: ORG 1000H

DW 1234H

DATA:DW56H,2000

经汇编后,从地址1000H处存贮器的内容为:

〔1000H〕=12H

〔1001H〕=34H

〔1002H〕=00H

〔1003H〕=56H

〔1004H〕=07H

〔1005H〕=0D0H6、DS预留存贮空间伪指令

[标号:]DS

表达式在汇编时,从指定地址开始保存DS之后“表达式〞的值所规定的存贮单元。 ORG 1000H DS 07H DB 20H,20 DW 12H经汇编后,从地址1000H开始保存7个单元,然后从1007H处存贮器的内容为: 〔1007H〕=20H 〔1008H〕=14H 〔1009H〕=00H 〔100AH〕=12H参照书P48 7.位赋值伪指令 标号bitn 该伪指令把值n赋给前面的标号,n一般指位地址,在程序中标号和n是等价的。如: HIGHbit10H 那么HIGH等价于位地址10H((22H.0〕),1→HIGH等价于1→10H等价于1→22H.0。参见书P15表2.5参照书P48--49BIT位赋值伪指令举例说明:

字符名称BIT

位地址这里的“字符名称〞与标号不同〔其后没有冒号〕,但它是必须的,其功能是把BIT之后的“位地址〞值赋给“字符名称〞。例:Psa BIT P1.1 A2 BIT 02H MOVC,Psa MOVA2,C参见书P15表2.5

三.汇编语言源程序的编程和汇编

1.编程汇编语言编程时大多在PC机中用文本编辑器(如EDIT)编写,目前几乎所有的单片机仿真器所配的软件均有文本编辑器。如南京伟福WAVE6000forWindows、DVCC软件、开发实验箱等。只要运行软件后进入程序编辑状态即可编写程序。注意:汇编源程序的扩展名为:〞asm〞 2.汇编汇编语言必须经过机器汇编或人工汇编才能得到相应的机器程序,即目标程序,以供单片机识别和执行。由于人工汇编工作量大,容易出错,现已很少用〔个人创业〕。机器汇编一般是在PC机上利用一些汇编软件进行。目前几乎所有的单片机仿真器配的开发软件都有汇编程序,在源程序编写完成后使用汇编功能菜单即可进行对源程序汇编。在汇编时假设发现源程序有语法错误或跳转超出范围等情况,系统会将错误显示给用户。用户在改正错误后,需再对源程序进行汇编,直到源程序完全没有语法错误。此时汇编程序会生成与其对应的目标文件。一般情况下是生成HEX(十六进制)和BIN(二进制)文件。

没有语法错误并不等于程序开发成功,一般来说还要对程序进一步调试、修改,运行无误后,程序才算最终完成。这时才可将目标文件写入到程序存储器中。 汇编语言程序设计方法单片机应用系统软件一般由汇编语言或其他高级语言写成,一个单片机程序中由主程序、假设干个子程序、中断程序组成,从程序结构上分为顺序程序、分支程序、循环程序、子程序、中断程序等。4-2汇编语言程序设计步骤一、依工程方案、参数指标等确定设计方案和计算方法;二、了解应用系统的硬件配置、性能指标;三、建立系统数学模型,确定控制算法和操作步骤;四、画程序流程图;表示程序结构和程序功能。五、编制源程序。1.合理分配存储器单元和了解I/O接口地址。2.按功能设计程序,明确各程序之间的相互关系。3.用注释行说明程序,便于阅读、修改和调试。常用程序结构:4-3顺序程序顺序程序又称简单程序,程序走向只有一条路径。例:双字节求补程序(设数据在R4R5中): CLRCMOV A,R5

;取低字节 CPL A ADD A,#01H ;低字节变补 MOV R5,A MOV A,R4

;取高字节 CPL A ADDCA,#00H ;高字节变补 MOV R4,A顺序程序、分支程序、循环程序。

例:三字节无符号数相加,其中被加数在内部RAM的50H、51H和52H单元中;加数在内部RAM的53H、54H和55H单元中;要求把相加之和存放在50H、51H和52H单元中,进位存放在位寻址区的00H位中。低字节低字节中字节中字节高字节高字节高字节高字节低字节低字节R0→R1→MOV R0,#52HMOV R1,#55HMOV A,@R0ADD A,@R1MOV @R0,ADEC R0DEC R1MOV A,@R0ADDCA,@R1MOV @R0,ADEC R0DEC R1MOV A,@R0ADDCA,@R1MOV @R0,ACLR AADDCA,#00HMOV R0,#00HMOV @R0,A;被加数的低字节地址;加数的低字节地址;低字节相加;存低字节相加结果;中间字节带进位相加;存中间字节相加结果;高字节带进位相加;存高字节相加结果;存放进位的单元地址;进位送00H位保存程序:更高效的方法是编制循环程序后面讲CLRCMOV00H,C

例:压缩式BCD码分解成为单字节BCD码。MOV R0,#40H ;设指针MOV A,@R0

;取一个字节MOV R2,A ;暂存ANL A,#0FH ;高半字节清0INC R0;指针指向41HMOV @R0,A ;保存数据个位MOV A,R2SWAPA ;十位换到低半字节ANL A,#0FH;高半字节清0INC R0;指针指向42H

MOV @R0,A ;保存数据十位十个

分支程序就是在程序执行过程中要判断某些条件,当条件成立后程序转移到不同的功能处运行。在MCS-51单片机中条件转移指令都可以用在分支程序中。

(复习、参见书P38---39)

(1)测试条件符合转移,如:

JZ、JNB…等

4--4 分支程序〔参见书P49-57〕〔2〕比较不相等转移,如: CJNER0,#2FH,LOOP

〔3〕减1不为0转移,如: DJNZR7,LOOP

〔4〕根据某些单元或存放器的内容转移,如: JMP@A+DPTR4-4-1单重分支程序一个判断决策框,程序有两条出路。两种分支结构:由条件转移指令构成程序判断框局部,形成程序分支结构。例:假定在外部RAM中有ST1、ST2和ST3共3个连续单元,其中ST1和ST2单元中分别存放着两个8位无符号二进制数,要求找出其中的大数并存入ST3单元中。START:CLRC MOVDPTR,#ST1MOVXA,@DPTRMOVR2,AINCDPTR MOVXA,@DPTRSUBBA,R2JNCBIG1XCHA,R2BIG0:INCDPTRMOVX@DPTR,ARETBIG1:MOVXA,@DPTRSJMPBIG0;进位位清“0〞;设置数据指针,指向ST1;取第一个数;第一个数存R2;数据指针加1,指向ST2;取第二个数;两数比较〔第二个数-第一个数〕;第二个数大转BIG1〔C=0无借位跳〕;第一个数大整字节交换继续;指向ST3单元;存大数;重取第二个数4-4-2多重分支程序例:求符号函数Y=SGN(X),X在片内RAM40H,结果放入片内RAM41H+1〔当X>0〕SGN(X)=0〔当X=0〕-1〔当X<0〕SYMB:MOVA,40H ;取X JZ STOR ;X=0跳,Y=X JB ACC.7,MINUS;X<0〔A.7=1跳〕MOVA,#01H ;X>0,Y=+1SJMPSTORMINUS:MOVA,#0FFH;X<0,Y=-1STOR:MOV41H,A ;保存YRET屡次使用条件转移指令,形成两个以上判断框。参见书P49例1按分支号转移如:当分支号=0,程序转移到ADDR0处;当分支号=1,程序转移到ADDR1处;…。例:有RAM0、RAM1、RAM2和RAM3共4个分支程序段,各分支程序段的功能依次是从内部RAM256B范围取数、从外部RAM低256B范围取数、从外部RAM4KB范围取数和从外部RAM64KB范围取数。并假定R0中存放取数地址低8位地址,R1中存放高8位地址,R3中存放分支序号值〔0,1,2,3〕。假定以SUBTAB作差值表首地址,RAM0_SUBTAB~RAM3_SUBTAB为差值。分析:差值表=分支入口地址-该表首址

1、利用查地址表法:

(参见书P51例3)。

MOVA,R3MOVDPTR,#SUBTAB

MOVCA,@A+DPTRJMP @A+DPTRSUBTAB:DBRAM0_SUBTABDBRAM1_SUBTAB DBRAM2_SUBTABDBRAM3_SUBTABRAM0:MOV A,@R0 SJMPDONERAM1:MOVXA,@R0

SJMP DONERAM2:MOV A,R1 ANL A,#0FHANL P2#0F0H ORL P2,A MOVXA,@R0

SJMPDONERAM3:MOV DPL,R0 MOV DPH,R1 MOVXA,@DPTRDONE:SJMP$;分支转移值送A〔如R3=2〕;差值表首址〔SUBTAB=3000H〕;查表[A+DPTR=3002H,(A)=40H];转移〔A+DPTR=3040H〕;差值表〔=10H〕〔=20H〕〔=40H〕〔=60H〕;从内部RAM取数;从外部RAM256B取数;从外部RAM4KB取数;高位地址取低4位;清P2口低4位;发高位地址;从外部RAM64KB取数程序:入口地址:3010H3020H3040H3060H差值表=分支入口地址-该表首址表首址3000H例题:查转移指令表(参见书P52例4〕

假定键盘上有3个操作键,键值存于A中。功能说明如右表:

… MOV DPTR,#3000H CLR C RLC AJMP @A+DPTR

AJMP DSAJMP XSAJMP CR …

3000H3001H3002H3003H3004H3005H3006H;3000H为基址;进位位CY清“0〞;A带进位位循环左移(A)X2;转操作键处理程序;转读数据程序;转写数据程序;转插入程序2、使用转移指令表法。用分支转移指令AJMP…对AJMP指令应将分支序号乘以2,转移范围为2KB;

对LJMP指令应将分支序号乘以3,转移范围为64KB。4-5 循环程序4-5-1 循环程序的构成各个环节任务:一、初始化局部:循环准备工作。如:清结果单元、设指针、设循环控制变量初值等。二、循环体:循环工作局部:需屡次重复处理的工作。循环控制局部:1.修改指针和循环控制变量。2.检测循环条件:满足循环条件,继续循环,否那么退出循环。三、结束局部:处理和保存循环结果。

4-5-2单重循环简单循环结构:循环体中不套循环。循环控制方法: 计数控制; 特征标志控制。例:求n个单字节数据的累加,设数据串已在43H起始单元,数据串长度在42H单元,累加和不超过2个字节,高位放入41H、低位放入40H。SUM:CLRC MOV R0,#42H ;设指针 MOV A,@R0 MOV R2,A ;循环计数器←n CLR A ;结果单元清0 MOV R3,AADD1:INC R0 ;修改指针 ADD A,@R0 ;累加 JNCNEXT ;处理进位〔C=0跳〕 INC R3 ;有进位,高字节加1NEXT:DJNZ R2,ADD1 ;循环控制:数据是否加完? MOV 40H,A ;循环结束,保存结果 MOV 41H,R3 RETR0→计数控制:

例:为一串7位ASCII码数据的D7位加上奇校验,设数据存放在片外RAM的2101H起始单元,数据长度在2100H单元。MOVDPTR,#2100HMOVXA,@DPTRMOVR2,ANEXT:INCDPTRMOVXA,@DPTRORLA,#80HJBP,PASS;P=1:ACC中1的个数为奇数,那么原;ASCII中1的个数为偶数,跳MOVX@DPTR,APASS:DJNZR2,NEXTDONE:SJMPDONE设循环计数器,控制循环次数。正计数和倒计数两种方式。参见书P13如ACC中1的个数为奇数:P=1;反之:P=0特征控制:例:找出正数表最小值B。正数表存于片外RAM中以LIST为起始单元,用-1作为结束标志。START:MOVDPTR,#LIST ;数表首地址 MOVB,#127 ;预置最小值。门限设为MAX,以免漏比NEXT:MOVXA,@DPTR ;取数INCDPTR ;修改指针 CJNEA,#-1,NEXT1 ;是否为数表结尾?〔A≠-1跳〕 SJMPDONE ;循环结束NEXT1:CJNEA,B,NEXT2 ;比较〔A≠B跳〕AJMPNEXTNEXT2:JNCNEXT ;C=0跳MOVB,A ;保存较小值 SJMPNEXTDONE:SJMP$LIST:DB…DB…设定循环结束标志实现循环控制。4-5-3多重循环例:将内存一串单字节无符号数升序排序。〔参看P69例10〕步骤:每次取相邻单元的两个数比较,决定是否需要交换数据位置。第一次循环,比较N-1次,取到数据表中最大值。第二次循环,比较N-2次,取到次大值。…第N-1次循环:比较一次,排序结束。

循环体中套循环结构。以双重循环使用较多。SORT:MOVA,#N-1 ;N个数据排序 MOVR4,A ;外循环次数LOOP1:MOVA,R4 MOVR3,A ;内循环次数 MOVR0,#TAB ;设数据指针LOOP2:MOVA,@R0 ;取二数 MOVB,A INCR0 MOVA,@R0 CJNEA,B,L1 ;比较〔A≠B跳〕SJMPUNEXL1:JNCUNEX ;A≥B,不交换 DECR0 ;否那么交换数据 XCHA,@R0 INCR0 MOV@R0,AUNEX:DJNZR3,LOOP2;内循环结束? DJNZR4,LOOP1;外循环结束? RET1、单循环定时程序:短延时〔参看P58〔3〕〕 MOV R5,#TIMELOOP:NOP NOP DJNZR5,LOOP软件延时程序:1T1T1T2T设:fOSC=6MHz,那么T=12/6MHz=2st=〔1+4×TIME〕×T=2+8×TIME〔s〕用循环程序将指令重复屡次执行,实现软件延时。试计算延时程序的执行时间。〔参看P58〔2〕〕 源程序 指令周期(M)指令执行次数计算下面延时程序的延时时间?(设fOSC=6MHz,T=2s〕。DELAY:MOVR6,#100 1D1:MOVR7,#10 1D2:NOP 1 DJNZR7,D2 2 DJNZR6,D1 2 RET 2DELAY:MOVR6,#64H〔=100〕 1 I1:MOVR7,#0FFH〔=255〕 1 I2:DJNZR7,I2 2 DJNZR6,I1 2 RET 2延时时间计算:〔设时钟fOSC=12MHz〕T=1st=(1×1+1×100+2×100×255+2×100+2×1)×T=51.303ms1100100×25510012、多重循环定时:用循环程序将指令重复屡次执行,实现较长时间的延时。t=(1x1+1x100+3x1000+2x100+2x1)xT=3003X2s

=6.606ms110010×10010×1001001指令周期(M)指令执行次数4-6算术运算程序

4-6-1 多字节加减运算程序多字节加法子程序,Z=X+Y。〔参看P60〕ADDS:CLR CMOVR2,#LENLOOP:MOV A,@R0ADDCA,@R1 ;加一字节 MOV @R0,A;存和一字节 INCR0 ;修改指针INC R1DJNZR2,LOOP;全部字节加完?

RET

MOV00H,C先介绍一种便于初学者理解的方法:考虑:利用乘法根本指令:MULAB;积为双字节:B中存积的高位字节,A中存积的低位字节功能:(R2R3)×(R6R7)→(43H42H41H40H)。入口:R2R3中存放被乘数,R6R7中存放乘数。出口:积存放在43H42H41H40H中。

4-6-2 多字节无符号数乘法运算计算原理如下式:参见书P62图(43H)(42H)(41H)(40H)程序:MOV A,R3 MOV B,R7 MUL AB;(R3)*(R7),(R3*R7)L→A,(R3*R7)H→B

MOV40H,A;(R3*R7)L→40H▽1

MOV 41H,B;(R3*R7)H→41H MOV A,R2MOV B,R7 MUL AB;(R2)*(R7) ADD A,41H;(R2*R7)L+(R3*R7)H→A,可能产生进位CY MOV 41H,A;(41H)=(R3*R7)H+(R2*R7)L MOVA,B;A←

(R2*R7)H ADDCA,#00H;只加进位,(A)=(R2*R7)H+CY+0 MOV 42H,A;(42H)=(A) MOV A,R3 MOV B,R6

MUL AB;(R3)*(R6) ADD A,41H;A←(R3*R6)L+

(R3*R7)H+

(R2*R7)L,CY?

MOV41H,A;(41H)=(R3*R7)H+

(R2*R7)L+(R3*R6)L▽2 MOVA,42H;A←(R2*R7)H ADDCA,B;A←(R2*R7)H+(R3*R6)H+CY

,CY?

MOV00H,C

;保存进位

MOV 42H,A;(42H)←(A)MOV A,R2 MOV B,R6MUL AB;(R2)*(R6) ADD A,42H;(A)=(R2*R6)L+(R2*R7)H+(R3*R6)H+CY,CY?

MOV 42H,A

;(42H)=(R2*R7)H+(R3*R6)H+(R2*R6)L▽3 MOVA,B ADDCA,#00H;

只加进位(R2*R6)H+CY+0→A

MOVC,00H

ADDCA,#00H;

只加进位(R2*R6)H+CY+0→AMOV 43H,A;(43H)=(R2*R6)H▽4

RET二.无符号双字节快速乘法。〔参见书P62—63〕考虑利用乘法根本指令:MULAB;积为双字节:B中存积的高位字节,A中存积的低位字节功能:(R2R3)×(R6R7)→(R4R5R6R7)。入口:R2R3中存放被乘数,R6R7中存放乘数。出口:积存放在R4R5R6R7中。*使用重复加法的乘法速度比较慢,对于使用晶振频率为12MHz的MCS-51来说,平均耗时>300µs。在实时控制应用场合中,经常需要在100µs内完成一次双字节乘法。因此需要设计一种快速乘法。计算原理如下式:参见书P62图程序:QMUL:MOV A,R3 MOV B,R7 MUL AB;(R3)*(R7) XCH A,R7;(A)(R7),(R7)=(R3*R7)L▽1 MOV R5,B;(R5)=(R3*R7)H MOV B,R2 MUL AB;(R2)*(R7) ADD A,R5;(A)=(R2*R7)L+(R3*R7)H,可能产生CY MOV R4,A;(R4)=(R3*R7)H+(R2*R7)L CLR A;(A)=0,〔下一条指令只加进位CYI及(R2*R7)H〕 ADDCA,B;(A)=(R2*R7)H+CY+0 MOV R5,A;(R5)=(R2*R7)H+CY MOV A,R6 MOV B,R3 MUL AB;(R3)*(R6) ADD A,R4;(A)=(R3*R6)L+(R3*R7)H+(R2*R7)L,CY? XCH A,R6;(A)(R6),(R6)=(R3*R7)H+(R2*R7)L+(R3*R6)L▽2 XCH A,B;(A)=(R3*R6)H,(B)=(R6), ADDCA,R5;(A)=(R3*R6)H+(R2*R7)H+CY+CY,CY? MOV R5,A;(R5)=(R3*R6)H+(R2*R7)H+CY+CY MOV F0,C;暂存CY MOV A,R2 MUL AB;(R2)*(R6) ADD A,R5;(A)=(R2*R6)L+R2*R7)H+CY+(R3*R6)H+CY,CY? MOV R5,A;(R5)=(R2*R7)H+(R3*R6)H+(R2*R6)L▽3 CLR A MOV ACC.0,C;CYACC.0 MOV C,F0;准备加以前加法的进位CY,〔F0〕=CYC ADDCA,B;(A)=(R2*R6)H+CY+CY MOV R4,A;(R4)=(R2*R6)H+CY2▽4;OK!!!! RET

该竖式中(R3R7)L表示(R3)×(R7)的低位字节,(R3R7)H表示(R3)×(R7)的高位字节,只要按这个竖式,利用MCS-51的乘法和加法指令,就能完成双字节乘法。以上程序完成的是双字节乘以双字节,称为四字节的乘法。对于其他各种字节的乘法,也可用竖式来分析,例如双字节乘以三字节或单字节乘以四字节等,用此法可容易的编出相应的程序。举一反三!创新强国!无符号二进制数除法正如乘法能由一系列加法和移位操作实现一样,除法也可由一系列减法和移位操作实现。为了设计出除法的算法,先分析二进制数的手算除法。下式说明两个二进制数A=100100和B=101的手算除法步骤:

MCS-51指令系统虽有一条8位除法指令,但难用于多字节除法,计算机除法常采用“左移被除数相减法〞。做除法前先将余数单元请0,在CY=0条件下,执行左循环移位,将被除数最高位移入余数单元最低位,被除数最低位移入0,然后使余数减去除数。如够减,那么此时被除数移位单元最低位置1,即商为1,同时用差取代余数;如不够减,那么此时的被除数移位单元仍为0,即商0。这样重复移位、做减法,直到被除数全部左移入余数单元。最后被除数移位单元变成了商数单元,余数单元保存余数。左循环如以下图所示。

0Dn……….D0Dm……….D0

CY余数单元被除数单元先清0CY、清0余数单元,并和被除数组成循环体

第1次左移位:余数小于除数,不够减,商为0,继续移位:

第2次左移位:余数仍小于除数,不够减,商为0,继续移位:

00000

1011

CY余数单元被除数单元00001

0110

CY余数单元被除数单元00010

1100

CY余数单元被除数单元00101

1000

CY余数单元被除数单元00001

0010

CY余数单元被除数单元举例:设被除数为1011B,除数为0101B,采用移位除法过程为:第3次左移位:余数等于除数,够减且差值为0000,用此差值取代原来余数,并将被除数单元最低位置1:即余数单元=0000被除数=1001继续左移:

第4次左移位〔已左移完被除数〕:余数单元=0001=余数被除数=0010=商00001001可以看出,商位是以串行移位方式获得的,每次得一位。首先把被除数移入余数单元的数与除数相比较,如余数大于除数,那么商位为1,并从余数中减去除数,形成一个局部余数;否那么商位为0,不执行减法。然后把局部余数连同被除数左移一位,形成新的余数单元,并与除数再次进行比较。…循环此步骤,直到被除数的所有位都左移处理完为止,一般被除数的位长为m,那么需循环m次。这种除法上商前,先比较余数与除数,根据比较结果,决定商1或0,并且只有在商为1时,才执行减法,因此称之为“左移被除数相减法〞。举例:采用“左移被除数相减法〞的无符号双字节除法。功能:(R5R6)/(R4)→(R4)余数存(R3)。程序框图如下页图所示。参见书P63--64图a“左移被除数相减法〞除法程序框图除法移位次数10H计数器R2被除数单元左移1位被除数单元>除数?计数器减1计数器=0?返回NYN商减去除数0商Y除数≠0?YN错误处理程序:MDIV:MOVA,R4JNZMDIV1SETBPSW.2LJMPERORRMDIV1:MOVR2,#10HMOVR3,#00HCLRCMDIV2:MOVA,R6RLCAMOVR6,AMOVA,R5RLCAMOVR5,A;除数非0那么执行除法;否那么OV标志置“1〞;并转错误处理子程;余数单元清0;清0CY

MOVA,R3RLCAMOVR3,A

CLRCSUBBA,R4JCMDIV3MOVR3,AINCR6MDIV3:DJNZR2,MDIV2……;小于除数那么转MDIV3;否那么差值送余数单元;商1;被除数所有位左移完否?

未考虑商溢出*从前面所示的手算除法中,可以看出被除数的字长比除数和商的字长要长,一般在计算机中,被除数均为双倍字长,即如果除数和商为双字节,那么被除数为四字节。由于商为单字长,故如果在除法中发生商大于单字长,称为溢出。在进行除法前,应该检查是否会发生溢出。一般可在进行除法前,先比较被除数的高位与除数,如被除数高位大于等于除数,那么溢出,应该置溢出标志,不执行除法。*带符号二进制乘法原码乘法:对原码表示的带符号二进制数,只需在乘法前,先按正数与正数相乘为正,正数与负数相乘为负,负数与负数相乘为正的原那么,得出积的符号(计算机中可用异或操作得出积符),然后清0符号位,执行不带符号位的乘法,最后送积的符号。设被乘数A的符号位为A0,数值为A*,乘数B的符号位为B0,数值为B*,积C的符号为C0,数值为C*(这个算法可用F0为符号暂存位)。补码乘法:对补码表示的带符号二进制数乘法,除了需像原码乘法一样对符号进行处理外,在被乘数、乘数或积为负数时,还需对负数取补(变成原码)。

*同理,对于补码表示的数,在执行除法运算时,采用首先把它们转换成原码,然后再执行原码的除法运算,最后把商再转换成补码。这样需要进行补码与原码的转换。一个正数的补码与原码相同,不需转换。对于负数,求补码表示的负数的原码或求原码表示的负数的补码,都可采用求它补码的方法,即对于二进制数,可采用先按位取反,然后把结果加1。举例:双字节数取补子程序。功能:(R4R5)取补→(R4R5)。入口:R4R5中存放被取补数。出口:取补后数仍存放在R4R5中。程序:CMPT: MOV A,R5 CPL A ADD A,#1 MOV R5,A MOV A,R4 CPL A ADDC A,#0 MOV R4,A RET4-6-3代码转换程序(一)十六进制数转换为ASCII码;〔参见书P64--65〕(二)ASCII码转换为十六进制数。〔参见书P65〕0~9的ASCII码:30~39H;〔一〕十六进制数转换为ASCII码:HASC:CJNEA,#0AH,N N:JNC N1〔C=0跳N1〕 ADD A,#30H SJMP SEN1:ADD A,#37HSE:RET A~F的ASCII码:41~46H。〔二〕ASCII码转换为十六进制数:CJNE A,#29H,E1SJMPERRE1:JCERRCJNE A,#47H,E2SJMPERRE2:JNCERR

AHEX:CLRC SUBB A,#30H CJNE A,#0AH,NSJMPN1N:JCAE N1:SUBBA,#07H SJMPAEERR:MOV A,#0FFHAE:RET(三)BCD码与二进制数之间的转换

1.BCD码转换为二进制数:(比照书P65—67除法转换方式)

D=dn-1×10n-1+dn-2×10n-2+…+d1×101+d0×100

=(((dn-1×10+dn-2)×10+dn-3)×10+…d1)×10+d0“整数十翻二〞:从最高位开始,按二进制运算法那么循环。“乘十加次低位〞:B=B×10+bi。R3←0R4←010×R3R4+(R0)R3R4R0←R0+1有乘法和除法两种转换方式。*例:4位十进制数转换成二进制数。入口:设BCD码a3、a2、a1、a0分别放在50H~53H。出口:二进制结果放在R3R4中。*程序:IDTB: MOV R0,#50H MOV R2,#3 MOV R3,#0 MOV A,@R0 MOV R4,ALOP:MOVA,R4 MOV B,#10 MUL AB MOV R4,A MOV A,#10 XCH A,B XCH A,R3MUL AB

ADDA,R3XCHA,R4INCR0ADDA,@R0XCHA,R4ADDCA,#0MOVR3,ADJNZR2,LOPRET“整数二翻十〞:从最高位开始,按十进制运算

温馨提示

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

评论

0/150

提交评论