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

下载本文档

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

文档简介

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

4-1

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

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

汇编语言程序到机器语言程序的转换过程称为汇编。1、手工汇编:人工查指令表汇编。用于设计短小程序或调试程序的场合。2、机器汇编:用汇编程序进行汇编。2024/4/192源程序使用机器汇编要考虑汇编程序的约定:1)按指令格式和语法规则编写程序。常数的表示: 十进制数:20 十六进制数:87H,0F0H

二进制数:01011001B

字符: ‘H’

字符串: “Hello”。

2)使用伪指令提供汇编信息。2024/4/193汇编的主要任务:1)确定程序中每条汇编语言指令的指令机器码。2)确定每条指令在存储器中的存放地址。3)提供错误信息。 4)提供目标执行文件(*.OBJ/*.HEX)和列表文件(*.LST)。汇编语言的语句格式

语句行由四个字段组成:

[标号:]操作码[操作数][;注释]

括号内的部分可以根据实际情况取舍。每个字段之间要用分隔符分隔,可以用作分隔符的符号有空格、冒号、逗号、分号等。如:LOOP:MOVA,#7FH;A←7FH2024/4/194一、标号标号是语句地址的标志符号,用于引导对该语句的非顺序访问。有关标号的规定为:标号由1~8个ASCII字符组成。第一个字符必须是字母,其余字符可以是字母、数字或其他特定字符;不能使用该汇编语言已经定义了的符号作为标号。如指令助记符、寄存器符号名称等;标号后边必须跟冒号。二、操作码操作码用于规定语句执行的操作。它是汇编语句中唯一不能空缺的部分。它由指令助记符表示。

2024/4/195三、操作数操作数用于给指令的操作提供数据或地址。在一条汇编语句中操作数可能是空缺的,也可能包括一项,还可能包括两项或三项。各操作数间以逗号分隔。操作数字段的内容可能包括以下几种情况:(1)工作寄存器名;(2)特殊功能寄存器名;(3)标号名;(4)常数;(5)符号“$”,表示程序计数器PC的当前值;(6)表达式。2024/4/196四、注释

注释不属于汇编语句的功能部分,它只是对语句的说明。注释字段可以增加程序的可读性,有助于编程人员的阅读和维护。注释字段必须以分号“;”开头,长度不限,当一行书写不下时,可以换行接着书写,但换行时应注意在开头使用分号“;”。汇编语言指令类型:

1.机器指令:

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

汇编控制指令,仅提供汇编信息,没有指令代码。2024/4/1973.宏指令:

宏汇编功能:将需要多次反复执行的程序段定义成一个宏指令名(宏定义),编程时,可在程序中使用宏指令名来替代一段程序(宏调用)。宏定义过程:宏指令名MACRO

形式参数 … ;定义程序段

ENDM宏调用过程: … 宏指令名实际参数 … 宏指令名实际参数2024/4/198二、汇编控制指令(伪指令):伪指令是放在汇编语言源程序中用于指示汇编程序如何对源程序进行汇编的指令,它不同于指令系统中的指令,指令系统中的指令在汇编程序汇编时能够产生相应的指令代码,而伪指令在汇编程序汇编时不会产生代码,只是对汇编过程进行相应的控制和说明。伪指令通常在汇编语言源程序中用于定义数据、分配存储空间、控制程序的输入输出等。MCS-51汇编语言源程序相对于一般的微型计算机汇编语言源程序结构简单,伪指令数目少,常用的伪指令只有几条。2024/4/1991.ORG—起始地址指令:指明程序和数据块起始地址。该指令的功能是向汇编程序说明下面紧接的程序段或数据段存放的起始地址。表达式通常为16进制地址,也可以是已定义的标号地址。常用伪指令及其功能:

ORG8000HSTART:MOVA,#30H……

此时规定该段程序的机器码从地址8000H单元开始存放。在每一个汇编语言源程序的开始,都要设置一条ORG伪指令来指定该程序在存储器中存放的起始位置。若省略ORG伪指令,则该程序段从0000H单元开始存放。在一个源程序中,可以多次使用ORG伪指令规定不同程序段或数据段存放的起始地址,但要求地址值由小到大依序排列,不允许空间重叠。2024/4/19102.DB伪指令格式:[标号:]DB项或项表

DB伪指令用于定义字节数据,可以定义一个字节,也可定义多个字节,字义多个字节时,两两之间用逗号间隔,定义的多个字节在存储器中是连续存放的。定义的字节可以是一般常数,也可以为字符,还可以是字符串,字符和字符串以引号括起来,字符数据在存储器中以ASCII码形式存放。在定义时前面可以带标号,定义的标号在程序中是起始单元的地址。【例3-19】ORG3000HTAB1:DB12H,34HDB'5','A','abc'汇编后,各个数据在存储单元中的存放情况如下:12H34H35H41H61H62H63H3000H3001H3002H3003H3004H3005H3006H2024/4/19113.DW伪指令格式:[标号:]DW项或项表这条指令与DB相似,但用于定义字数据。项或项表指所定义的一个字在存储器中占两个字节。汇编时,机器自动按低字节在前,高字节在后,即低字节存放在低地址单元,高字节存放在高地址单元。【例3-20】ORG3000HTAB2:DW1234H,5678H汇编后,各个数据在存储单元中的存放情况如下:34H12H78H56H3000H3001H3002H3003H2024/4/19124.DS伪指令格式:[标号:]DS数值表达式该伪指令用在存储器中保留一定数量的字节单元。保留存贮空间主要为以后存放数据。保留的字节单元数由表达式的值决定。【例3-21】ORG2000HTAB1:DB12H,34HDS4HDB'5'汇编后,存储单元中的分配情况如下:12H34H----35H3000H3001H3002H3003H3004H3005H3006H2024/4/19135.EQU伪指令格式:符号EQU项该伪指令的功能是将指令中的项的值赋予EQU前面的符号。项可以是常数、地址标号或表达式。以后可以通过使用该符号使用相应的项。【例3-22】TAB1EQU1000HTAB2EQU2000H汇编后TAB1、TAB2分别等于1000H、2000H。程序后面使用1000H、2000H的地方就可以用符号TAB1、TAB2替换。用EQU伪指令对某标号赋值后,该符号的值在整个程序中不能再改变。2024/4/19147.END伪指令格式:END

该指令放于程序最后位置,用于指明汇编语言源程序的结束位置,当汇编程序汇编到END伪指令时,汇编结束。END后面的指令,汇编程序都不予处理。一个源程序只能有一个END命令,否则就有一部分指令不能被汇编。6.bit伪指令格式:符号bit位地址bit该伪指令用于给位地址赋予符号,经赋值后可用该符号代替bit后面的位地址。【例3-23】FLGbitF0AIbit P1.0定义后,在程序中位地址F0、P1.0就可以通过FLG和AI来使用。2024/4/19154-2汇编语言程序设计步骤一、确定方案和计算方法;二、了解应用系统的硬件配置、性能指标;三、建立系统数学模型,确定控制算法和操作步骤;四、画程序流程图;表示程序结构和程序功能。五、编制源程序。1.合理分配存储器单元和了解I/O接口地址。2.按功能设计程序,明确各程序之间的相互关系。3.用注释行说明程序,便于阅读、修改和调试。2024/4/1916常用程序结构:4-3顺序程序顺序程序是指无分支、无循环结构的程序。其执行流程是依指令在存储器中的存放顺序进行的。顺序程序又称简单程序,程序走向只有一条路径。例:双字节变补程序(设数据在R4R5中): MOV A,R5

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

;取高字节 CPL A ADDCA,#00H ;高字节变补 MOV R4,A

顺序程序、分支程序、循环程序。

2024/4/1917例题(顺序)[例4.1]

三字节无符号数相加,其中被加数在内部RAM的50H、51H和52H单元中;加数在内部RAM的53H、54H和55H单元中;要求把相加之和存放在50H、51H和52H单元中,进位存放在位寻址区的00H位中。低字节低字节中字节中字节高字节高字节高字节高字节低字节低字节R0→R1→2024/4/1918MOV R0,#52HMOV R1,#55HMOV A,@R0ADD A,@R1MOV @R0,ADEC R0DEC R1MOV A,@R0ADDC A,@R1MOV @R0,ADEC R0DEC R1MOV A,@R0ADDC A,@R1MOV @R0,ACLR AADDC A,#00HMOV R0,#00HMOV @R0,A;被加数的低字节地址;加数的低字节地址;低字节相加;存低字节相加结果;中间字节带进位相加;存中间字节相加结果;高字节带进位相加;存高字节相加结果;存放进位的单元地址;进位送00H位保存程序:MOV C,ACC.0MOV 00H,CMOV R0,#20HMOV @R0,A2024/4/1919例:压缩式BCD码分解成为单字节BCD码。MOV R0,#40H ;设指针MOV A,@R0

;取一个字节MOV R2,A ;暂存ANL A,#0FH ;高半字节清0INC R0MOV @R0,A ;保存数据个位MOV A,R2SWAPA ;十位换到低半字节ANL A,#0FHINC R0MOV @R0,A ;保存数据十位十个2024/4/19204-4 分支程序

4-4-1 单重分支程序一个判断决策框,程序有两条出路。两种分支结构:例:求R2中补码绝对值:正数不变,负数变补。

MOVA,R2 JNBACC.7,NEXT;为正数?为0跳

CPLA ;负数变补

INCA MOVR2,ANEXT:SJMPNEXT;结束由条件转移指令构成程序判断框部分,形成程序分支结构。2024/4/1921P85:例题(单分支)[例4.2]假定在外部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单元;存大数2024/4/1922例:FRT:MOVA,40H ;取行李重量计价单位G MOVR3,A MOVB,#03H ;M=G×3 MULAB MOVR2,A ;暂存3G MOVA,R3

;取回G CJNEA,#05H,L1;G=5?G≠5跳L1 SJMPWETC L1:JCWETC ;是,转至WETC(C=1即G<5跳) SUBBA,#05H ;否则M=3G+2(G-5)

RLCA ADDA,R2

SJMPL2WETC:MOVA,R2L2:MOV41H,A ;存结果M RETG=5?=:跳WETC

≠:G<5:跳WETC

G>5:顺序执行行李计价:当G≤5,M=G×3;

当G>5,M=G×3+(G-5)×(5-3)。2024/4/1923例求双字节补码。设在内部RAM的addr1和addr+1单元存有一个双字节数(高位字节存于高地址单元)。编写程序将其读出取补后再存入addr2和addr2+1单元。首先对低字节取补,然后判其结果是否为全“0”。若是,则高字节取补,否则高字节取反。

START:MOVR0,#addr1;原码低字节地址送R0 MOVR1,#addr2;补码低字节地址送R1 MOVA,@R0;原码低字节送A CPLA;A内容取补

INCAMOV@R1,A;存补码低字节

INCR0;调整地址,指向下一单元

INCR1JZZERO;(A)=0时转ZEROMOVA,@R0;原码高字节送A CPLAMOV@R1,A;高字节反码存入addr2+1单元

SJMPLOOP1ZERO:MOVA,@R0;高字节取补存入addr2+1单元

CPLAINCAMOV@R1,ALOOP1:RET2024/4/19244-4-2多重分支程序例:求符号函数Y=SGN(X)

+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一、多次使用条件转移指令,形成两个以上判断框。2024/4/1925温控系统结构框图电热箱采用电热丝加热,由双向可控硅控制加热量的大小;温度传感器检测电热箱内的温度,经放大与A/D转换后进入单片机;单片机将设定的温度值与检测到的电热箱中的实际温度进行比较,并调节运算后,发出控制信号经光电隔离器去驱动双向可控硅以调节加在电热丝的电压,从而控制电热箱的温度。电热箱单片机温控系统结构框图2024/4/1926例题(多分支)[例4.3]某温度控制系统,采集的温度值(Ta)放在累加器A中。此外,在内部RAM54H单元存放控制温度下限值(T54),

在55H单元存放控制温度上限值(T55)。若Ta>T55,程序转向JW(降温处理子程序);

若Ta<T54,则程序转向SW(升温处理子程序);

若T55≥Ta≥T54,则程序转向FH(返回主程序)。

=:去FH思路:Ta=T55?≠:Ta>T55:去JW

Ta<T55:Ta=T54?=:去FH

≠:Ta<T54:去SW

Ta>T54:去FH算法:(1)Ta>T55:去JW

(2)Ta<T54:去SW

(3)T55≥Ta≥T54:去FH2024/4/1927程序:

CJNEA,55H,LOOP1 AJMPFHLOOP1:JNCJWCJNEA,54H,LOOP2AJMPFHLOOP2:JCSWFH:RET;Ta

≠T55:转向LOOP1;Ta=T55:返回;若CY=0,表明Ta>T55,转降温处理程序;Ta

≠T54:转向LOOP2;Ta=T54:返回;若CY=1,表明Ta<T54,转升温处理程序;T55≥Ta≥T54,返回主程序若Ta>T55,程序转向JW(降温处理子程序);若Ta<T54,则程序转向SW(升温处理子程序);若T55≥Ta≥T54,则程序转向FH(返回主程序)。2024/4/1928二、按分支号转移。如:当分支号=0,程序转移到ADDR0处;当分支号=1,程序转移到ADDR1处;…。[例4.4]有BR0、BR1、BR2和BR3共4个分支程序段,各分支程序段的功能依次是从内部RAM256B范围取数、从外部RAM低256B范围取数、从外部RAM4KB范围取数和从外部RAM64KB范围取数。并假定R0

中存放取数地址低8位地址,R1中存放高8位地址,R3中存放分支序号值。假定以BRTAB作差值表首地址,BR0_BRTAB~BR3_BRTAB为差值。

分析:差值表=分支入口地址-该表首址1、利用查地址表法:2024/4/1929

MOV A,R3 MOV DPTR,#BRTAB MOVC A,@A+DPTR JMP @A+DPTRBRTAB: DB BR0_BRTAB DB BR1_BRTAB DB BR2_BRTAB DB BR3_BRTABBR0: MOV A,@R0 SJMP BREBR1: MOVX A,@R0 SJMP BREBR2: MOV A,R1 ANL A,#0FH ANL P2,#0F0H ORL P2,A MOVX A,@R0

SJMP BREBR3: MOV DPL,R0 MOV DPH,R1 MOVX A,@DPTRBRE:SJMP $;分支转移值送A(如R3=2);差值表首址(BRTAB=3000H);查表[A+DPTR=3002H,(A)=40H];转移(A+DPTR=3040H);差值表(=10H)

(=20H)

(=40H)

(=60H);从内部RAM取数;从外部RAM256B取数;从外部RAM4KB取数;高位地址取低4位;清P2口低4位;发高位地址;从外部RAM64KB取数程序:入口地址:3010H3020H3040H3060H差值表=分支入口地址-该表首址2024/4/1930例题(查转移指令表)[4.5]假定键盘上有3个操作键,功能说明如下表: … MOV DPTR,#3000H CLR C RLC A JMP @A+DPTR AJMP DS AJMP XS AJMP CR …

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

对LJMP指令应将分支序号乘以3,转移范围为64KB。2024/4/1931

设分支号已存入A。把分支程序入口地址存放在表中。MTJS:MOVSP,#30H MOVDPTR,#TAB;取分支入口地址表首地址

CLRC ;分支号×2

RLCA MOVR2,A MOVCA,@A+DPTR;取分支地址低位

PUSHA ;入栈保存

MOVA,R2 INCA MOVCA,@A+DPTR;取分支地址高位

PUSHA ;入栈保存RET ;分支地址→PC,转移TAB:DWADDR0

;分支程序入口地址表

DWADDR1

… ADDR0:… ;程序段0…ADDR1:… ;程序段1…ADDR2:… ;程序段2…3、利用堆栈操作法:如:DPTR=3000H

A=2※※★★★★※※★★※※※※★★PC2024/4/19324-5 循环程序4-5-1 循环程序的构成各个环节任务:一、初始化部分:循环准备工作。如:清结果单元、设指针、设循环控制变量初值等。二、循环体:循环工作部分:需多次重复处理的工作。循环控制部分:

1.修改指针和循环控制变量。2.检测循环条件:满足循环条件,继续循环,否则退出循环。三、结束部分:

处理和保存循环结果。允许0次循环的循环结构:在循环工作之前检测循环条件。包含多次重复执行的程序段,循环结构使程序紧凑。

2024/4/19334-5-2单重循环简单循环结构:循环体中不套循环。循环控制方法: 计数控制; 特征标志控制。2024/4/1934例:求n个单字节数据的累加,设数据串已在43H起始单元,数据串长度在42H单元,累加和不超过2个字节。SUM: 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→2024/4/1935一、计数控制:

例:为一串7位ASCII码数据的D7位加上奇校验,设数据存放在片外RAM的2101H起始单元,数据长度在2100H单元。MOVDPTR,#2100HMOVXA,@DPTRMOVR2,ANEXT:INCDPTRMOVXA,@DPTRORLA,#80HJNBP,PASS;P=0:1的个数为偶数,跳MOVX@DPTR,APASS:DJNZR2,NEXTDONE:SJMPDONE设循环计数器,控制循环次数。正计数和倒计数两种方式。2024/4/1936二、特征控制:例:找正数表最小值。正数表存在片外RAM中以LIST为起始单元,用-1作为结束标志。START:MOVDPTR,#LIST ;数表首地址

MOVB,#127 ;预置最小值NEXT:MOVXA,@DPTR ;取数INCDPTR ;修改指针

CJNEA,#-1,NEXT1 ;是否为数表结尾?(A≠-1跳)

SJMPDONE ;循环结束NEXT1:CJNEA,B,NEXT2 ;比较(A≠B跳)NEXT2:JNCNEXT ;C=0跳MOVB,A ;保存较小值

SJMPNEXTDONE:SJMPDONE习题:统计一班考试为100分和不及格人数,成绩单在41H起始单元。设定循环结束标志实现循环控制。2024/4/19374-5-3多重循环例:将内存一串单字节无符号数升序排序步骤:每次取相邻单元的两个数比较,决定是否需要交换数据位置。第一次循环,比较N-1次,取到数据表中最大值。第二次循环,比较N-2次,取到次大值。…第N-1次循环:比较一次,排序结束。循环体中套循环结构。以双重循环使用较多。2024/4/1938SORT:MOV A,#N-1 ;N个数据排序

MOV R4,A ;外循环次数LOOP1:MOV A,R4 MOV R3,A ;内循环次数

MOV R0,#TAB ;设数据指针LOOP2:MOV A,@R0

;取二数

MOV B,A INC R0 MOV A,@R0 CJNEA,B,L1 ;比较(A≠B跳)L1:JNC UNEX ;A≥B,不交换

DEC R0

;否则交换数据

XCH A,@R0 INC R0 MOV @R0,AUNEX:DJNZR3,LOOP2 ;内循环结束?

DJNZR4,LOOP1 ;外循环结束?

RET2024/4/19391、单循环定时程序:

(参看P88)

MOV R5,#TIME LOOP: NOP NOP DJNZR5,LOOP软件延时程序:1T1T1T2T设:fOSC=6MHz,

则T=12/6MHz=2

s

t=(1+4×TIME)×T=2+8×TIME(

s)用循环程序将指令重复多次执行,实现软件延时。2024/4/1940试计算延时程序的执行时间。

源程序 指令周期(M)指令执行次数习题:DELAY:MOVR6,#100 1D1:MOVR7,#10 1D2:NOP 1

DJNZR7,D2 2t=6.606ms

DJNZR6,D1 2 RET 2计算延时程序的执行时间(设时钟fOSC=6MHz,T=2

s

。DELAY:MOVR6,#64H(=100) 1 I1:MOVR7,#0FFH(=255) 1 I2:DJNZR7,I2 2 DJNZR6,I1 2 RET 2延时时间计算:(设时钟fOSC=12MHz)T=1

st=(1×1+1×100+2×100×255+2×100+2×1)×T=51.303ms1100100×25510012、多重循环定时:用循环程序将指令重复多次执行,实现较长时间的延时。2024/4/19414-6算术运算程序

4-6-1 多字节加减运算程序多字节加法子程序,Z=X+Y。(参看P84)ADDS:CLR CMOVR2,#23H

LOOP:MOV A,@R0 ADDC A,@R1

;加一字节

MOV @R0,A ;存和一字节

INC R0

;修改指针

INC R1 DJNZ R2,LOOP ;全部字节加完?

RET习题1:编写十进制多字节加法子程序,Z=X+Y。习题2:编写多字节减法子程序,Z=X-Y。思考题:修改程序使运算结果保存到其他存储单元。2024/4/1942设被乘数的高字节放在R7中,低字节放于R6中;乘数的高字节放于R5中,低字节放于R4中。乘得的积有4个字节,按由低字节到高字节的次序存于片内RAM中以ADDR为首址的区域中。由于MCS-51单片机只有一条单字节无符号数乘法指令MUL,而且要求参加运算的两个字节须放于累加器A和B寄存器中,而乘得的结果高字节放于B寄存器中,低字节放于累加器A中。因而两字节乘法须用四次乘法指令来实现,即R6

R4、R7R4、R6R5和R7R5,设R6R4的结果为B1A1,R7R4结果为B2A1,R6R5的结果为B3A3,R7R5的结果为B4A4,乘得的结果须按下面的关系加起来。R7R6R5R4

B1A1B2A2B3A3B4A4C2C1C4C3+4-6-2 多字节无符号数乘除运算2024/4/1943即乘积的最低字节C1只由A1这部分得到,乘积的第二字节C2由B1、A2和A3相加得到,乘积的第三字节C3由B2、B3、A4以及C2部分的进位相加得到,乘积的第四字节C4由B4和低字节的进位相加得到。由于在计算机内部不能同时实现多个数相加,因而我们用累加的方法来计算C2、C3和C4部分,用R3寄存器来累加C2部分,用R2寄存器来累加C3部分,用R1寄存器来累加C4部分,另外用R0作指针来依次存放C1、C2、C3、C4入存储器。程序如下:

ORG0100H MOVR0,#ADDRMUL1:MOVA,R6 MOVB,R4 MULAB;R6

R4,结果的低字节直接存入积的第一字节单元

MOV@R0,A;结果的高字节存入R3中暂存起来

MOVR3,BMUL2:MOVA,R7 MOVB,R4 MULAB;R7R4,结果的低字节与R3相加后,再存入R3中

ADDA,R3 MOVR3,A2024/4/1944

MOVA,B;结果的高字节加上进位位后存入R2中暂存起来

ADDCA,#00 MOVR2,AMUL3:MOVA,R6 MOVB,R5 MULAB;R6

R5,结果的低字节与R3相加存入积的第二字节单元

ADDA,R3 INCR0 MOV@R0,A MOVA,R2 ADDCA,B;结果的高字节加R2再加进位位后,再存入R2中

MOVR2,A MOVA,#00 ADDCA,#00;相加的进位位存入R1中

MOVR1,A2024/4/1945MUL4:MOVA,R7 MOVB,R5 MULAB;R7R5,结果的低字节与R2相加存入积的第三字节单元

ADDA,R2 INCR0 MOV@R0,A MOVA,B ADDCA,R1;结果的高字节加R1再加进位后存入积的第四字节单元

INCR0 MOV@R0,A END2024/4/1946例:R2R3R4R5÷R6R7®R4R5(余数®R2R3)解:1.判断R2R3<R6R7?使商不大于16位。

2.被除数左移1位,试减除数。 3.若够减,商加1并保留余数。

101110101/01110100

0101 1001

01011000

0101

0110

0101 1

Cy←R2R3←R4R5←0

-R6R7+1够减116÷5=23…1

R2R3

不够减恢复余数循环16次相减计算多字节除法程序。步骤:1.对齐高位被除数试减除数。2.若够减商上1,不够减商上0且恢复余数。3.余数左移或除数右移对位。4.循环重复前3步,直至取够相应位数的商。

“四舍五入”:得到余数后,判断余数乘2后

是否大于除数,若大于除数则商再加“1”;否则不加。2024/4/19474-6-3代码转换程序(一)十六进制数转换为ASCII码;(二)ASCII码转换为十六进制数。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码转换为十六进制数:AHEX:CLRC SUBB A,#30H CJNE A,#0AH,NN:JC N1 SJMP AEN1:SUBB A,#11H CJNE A,#06H,N2N2:JNC ERR ADD A,#0AH SJMP AEERR:MOV A,#0FFHAE: RET2024/4/1948P96:例题(数制转换)[例4.11]在内部RAM的hex单元中存有2位十六进制数,试将其转换为ASCII码,并存放于asc和asc+1两个单元中。设(hex)=7BH

MOV SP,#3FHMAIN:PUSH hex ACALL HASC POP asc

(SP=40H)

MOV A,hex SWAP A PUSH ACC ACALL HASC POP asc+1 子程序(HASC):HASC:DEC SP DEC SP POP ACC ANL A,#0FH

ADD A,#7(A=12H) MOVC A,@A+PC

PUSH ACC INC SP INC SP7个字节 RET(SP=40H)ASCTAB:DB “0,1,2,3,4,5,6,7” DB “8,9,A,B,C,D,E,F”;十六进制数进栈(SP=40H);调用转换子程序(SP=41H→42H);第一位转换结果送asc单元(SP=3FH);再取原十六进制数;高低半字节交换;交换后的十六进制数进栈(SP=40H);调用转换子程序(SP=41H→42H);第二位转换结果送asc+1单元;跨过断点保护内容(SP=41H);跨过断点保护内容(SP=40H);弹出转换数据(SP=3FH);屏蔽高位 (A=0BH);修改变址寄存器内容(PC=2008H);查表(12H+2009H=201BH);查表结果进栈(SP=40H);修改堆栈指针回到断点保护内容;(42H)→PC8~15,(41H)→PC0~7;ASCII码表;(201BH)=0BH2000H2001H2002H2004H2006H2008H2009H200BH200DH200FH2010H2018H22212024/4/1949(三)BCD码与二进制数之间的转换

1.BCD码转换为二进制数:

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有乘法和除法两种转换方式。2024/4/1950“整数二翻十”:从最高位开始,按十进制运算法则循环。“乘二加次低位”:D=D×2+di

。除法转换式:bn-1×2n-1+bn-2×2n-2+…+b0=dm-1×10m-1+dm-2×10m-2+…+d0两边同时除基数,两边的整数或小数应该分别相等。除基数,取出1位余数,得到的商继续除基数取余数。循环“除基取余”操作,得到转换进制的各位系数。编程习题要求:1.为程序标明必要注释。2.上机调试通过。3.给出程序执行前设定的数据,并记录程序执行后的结果数据。4.要求写明数据的存储单元。2.二进制数转换为BCD码:

B=bn-1×2n-1+bn-2×2n-2+…+b1×21+b0×20

=(((bn-1×2+bn-2)×2+bn-3)×2+…b1)+b02024/4/19513.10.4子程序及其调用一、子程序的调用在实际应用中,经常会遇到一些带有通用性的问题,例如:数值转换、数值计算等,在一个程序中可能要使用多次。这时可以将其设计成通用的子程序供随时调用。子程序的结构与一般的程序并无多大区别,它的主要特点是,在执行过程中需要由其它程序来调用,执行完后又需要把执行流程返回到调用该子程序的主程序。子程序调用时要注意两点:一是现场的保护和恢复;二是主程序与子程序的参数传递。2024/4/1952二、现场保护与恢复在子程序执行过程中常常要用到单片机的一些通用单元,如工作寄存器R0~R7、累加器A、数据指针DPTR,以及有关标志和状态等。而这些单元中的内容在调用结束后的主程序中仍有用,所以需要进行保护,称为现场保护。在执行完子程序,返回继续执行主程序前恢复其原内容,称为现场恢复。保护与恢复的方法有以下两种:在主程序中实现;在子程序中实现。2024/4/1953

1、在主程序中实现示例如下:

PUSHPSW;保护现场

PUSHACC;

PUSHB;

MOVPSW,#10H;换当前工作寄存器组

LCALLaddr16;子程序调用

POPB;恢复现场

POPACC;

POPPSW;

……

其特点是结构灵活。2024/4/1954

2、在子程序中实现示例如下:SUB1:PUSHPSW;保护现场

PUSHACC;

PUSHB;

……MOVPSW,#10H;换当前工作寄存器组

……POPB;恢复现场

POPACC;

POPPSW;

RET其特点是程序规范、清晰。注意,无论哪种方法保护与恢复的顺序要对应。2024/4/1955三、参数传递

由于子程序是主程序的一部分,所以,在程序的执行时必然要发生数据上的联系。在调用子程序时,主程序应通过某种方式把有关参数(即子程序的入口参数)传给子程序,当子程序执行完毕后,又需要通过某种方式把有关参数(即子程序的出口参数)传给主程序。在80C51单片机中,传递参数的方法有三种:

1、利用累加器或寄存器在这种方式中,要把预传递的参数存放在累加器A或工作寄存器R0~R7中。即在主程序调用子程序时,应事先把子程序需要的数据送入累加器A或指定的工作寄存器中,当子程序执行时,可以从指定的单元中取得数据,执行运算。反之,子程序也可以用同样的方法把结果传送给主程序。2024/4/1956例编写程序,实现c=a2+b2。设a,b,c分别存于内部RAM的30H,31H,32H三个单元中。程序段如下:START:MOVA,30H;取aACALLSQR;调用查平方表

MOVR1,A;a2暂存于R1中

MOVA,31H;取bACALLSQR;调用查平方表

ADDA,R1;a2+b2存于A中

MOV32H,A;存结果

SJMP$SQR:MOVDPTR,#TAB;子程序

MOVCA,@A+DPTR;

RETTAB:DB0,1,4,9,16,25,36,49,64,81

2024/4/19572、利用存储器当传送的数据量比较大时,可以利用存储器实现参数的传递。在这种方式中,事先要建立一个参数表,用指针指示参数表所在的位置。当参数表建立在内部RAM时,用R0或R1作参数表的指针。当参数表建立在外部RAM时,用DPTR作参数表的指针。

例将R0和R1指向的内部RAM中两个3字节无符号整数相加,结果送到由R0指向的内部RAM中。入口时,R0和R1分别指向加数和被加数的低位字节;出口时,R0指向结果的高位字节。低字节在高地址,高字节在低地址。

2024/4/1958实现程序:NADD:MOVR7,#3;三字节加法

CLRC;NADD1:MOVA,@R0;取加数低字节

ADDCA,@R1;被加数低字节加AMOV@R0,A;

DECR0DECR1DJNZR7,NADD1INCR0RET

2024/4/19593、利用堆栈利用堆栈传递参数是在子程序嵌套中常采用的一种方法。在调用子程序前,用PUSH指令将子程序中所需数据压入堆栈,进入执行子程序时,再用POP指令从堆栈中弹出数据。

例把内部RAM中20H单元中的1个字节十六进制数转换为2位ASCII码,存放在R0指示的两个单元中。

2024/4/1960

MAIN:MOVA,20H;

SWAPAPUSHACC;参数入栈

ACALLHEASCPOPACCMOV@R0,A;存高位十六进制数转换结果

温馨提示

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

评论

0/150

提交评论