您好,欢迎访问三七文档
第四章汇编语言程序设计所谓程序设计,就是按照给定的任务要求,编写出完整的计算机程序。要完成同样的任务,使用的方法或程序并不是唯一的。因此,程序设计的质量将直接影响到计算机系统的工作效率、运行可靠性。前面我们学过了汇编语言形式的指令系统,本章重点介绍汇编语言程序结构以及如何利用汇编语言指令进行程序设计的方法。4.1汇编语言程序设计概述4.1.1汇编语言程序设计步骤使用汇编语言设计一个程序大致上可分为以下几个步骤。(1)分析题意,明确要求。(2)确定算法。(3)画程序流程图,用图解来描述和说明解题步骤。图4.1常用的流程图符号(4)分配内存工作单元,确定程序与数据区的存放地址。(5)编写源程序(6)程序优化。(7)上机调试、修改和最后确定源程序。4.2.2伪指令语句伪指令并不是真正的指令,也不产生相应的机器码,它们只是在计算机将汇编语言转换为机器码时,指导汇编过程,告诉汇编程序如何汇编。下面介绍一些MCS-51汇编程序常用的伪指令。(1)汇编起始伪指令ORG格式:[标号:]ORG16位地址功能:规定程序块或数据块存放的起始地址。如:ORG8000HSTART:MOVA,#30H……该指令规定第一条指令从地址8000H单元开始存放,即标号START的值为8000H。(2)汇编结束伪指令END格式:[标号:]END[表达式]功能:结束汇编。例如:ORG2000HSTART:MOVA,#00H……END(ENDSTART)表示标号START开始的程序段结束。(3)等值指令EQU格式:字符名称EQU项例如,TESTEQUR0MOVA,TEST(4)定义字节指令DB格式:[标号:]DB8位二进制数表DB命令是从指定的地址单元开始,定义若干个8位内存单元的内容。例如,ORG1000HTAB;DB23H,73,“6”,“B”TABl:DB110B以上伪指令经汇编以后,将对从1000H开始的若干内存单元赋值:(1000H)=23H(1001H)=49H(1002H)=36H(1003H)=42H(1004H)=06H其中36H和42H分别是字符6和B的ASCII码,其余的十进制数(73)和二进制数(110B)也都换算为十六进制数了。(5)定义字命令DW格式:[标号:]DW16位二进制数表例如,ORG1000HTAB:DW1234H,0ABH,10汇编后:(1000H)=12H(1001H)=34H(1002H)=00H(1003H)=ABH(1004H)=00H(1005H)=0AHDB、DW伪指令都只对程序存储器起作用,不能用来对数据存储器的内容进行赋值或进行其它初始化的工作。4.2顺序程序设计顺序结构程序是一种最简单、最基本的程序(也称为简单程序),它是一种无分支的直线形程序,按照程序编写的顺序依次执行。【例4-1】两个8位无符号数相加,和仍为8位。假设两个无符号数X1,X2分别存放于内部RAM60H、61H单元中,求其和并将和送入62H单元。程序如下:ORG0000HCLRCMOVR0,#60H;设R0为数据指针MOVA,@R0;取X11NCR0ADDCA,@R0;X1+X21NCR0MOV@R0,A;保存结果END【例4-2】两个无符号双字节数相加。设被加数存放在内部存储器30H(高位字节)、31H(低位字节)单元,加数存放在内部存储器40H(高位字节)、41H(低位字节)单元,和存入30H(高位字节)、31H(低位字节)单元。程序如下:ORG0000HCLRC;将C清零MOVR0,#31H;送被加数首址MOVR1,#41H;送加数首址MOVA,@R0;取被加数低字节ADDA,@R1;两个低字节相加MOV@R0,A;低字节和存人被加数低字节DECR0;修改指针,指向被加数高字节DECR1;修改指针,指向加数高字节MOVA,@R0;取被加数高字节ADDCA,@R1;高字节相加MOV@R0,A;存结果END【例4-3】编写16位二进制数求补程序二进制数的求补可归结为“求反加1”的过程,求反可用CPL指令实现;加1时应注意,加1只能加在低8位的最低位上。因为现在是16位数,有两个字节,因此要考虑进位问题,即低8位取反加1,高8位取反后应加上低8位加1时可能产生的进位,还要注意这里的加1不能用INC指令,因为INC指令不影响CY标志。程序如下:ORG0200HMOVA,R0;低8位送ACPLA;取反ADDA,#01H;加lMOVR2,A;存结果MOVA,R1;高8位送ACPLA;取反ADDCA,#00H;加进位MOVR3,A;存结果(R1R0---R3R2)END【例4-4】编程将20H单元中的8位无符号二进制数转换成3位BCD码,并存放在22H(百位)和21H(10位,个位)两个单元中。程序如下:ORG1000HMOVA,20H;取数送AMOVB,#64H;除数100送B中DIVAB;商(百位数BCD码)在A中,余数在B中MOV22H,A;百位数送22HMOVA,B;余数送A做被除数MOVB,#0AH;除数10送B中DIVAB;十位数BCD码在A中,个位数在B中SWAPA;十位数BCD码移至高4位ORLA,B;并入个位数的BCD码MOV21H,A;十位、个位BCD码存人21HEND查表[例4-5]一变量放在内部RAM的20H,取值为00H-05H。编写程序,求该变量的平方值,将结果放片内21HORG1000HSTART:MOVDPTR,#2000H;orMOVDPTR,#TABLEMOVA,20HMOVCA,@A+DPTRMOV21H,ASJMP$ORG2000HTABLE:DB00,01,04,09,16,25END图4.2分支程序结构图4.2(a)结构使用条件转移指令来实现分支,当给出的条件成立时,执行程序段A,否则执行程序段B。图4.2(b)结构使用散转指令JMP来实现多分支转移,它首先将分支程序按序号的值来实现分支转移。4.3分支程序设计【例4-6】设补码X放在内部RAM30H单元中,函数Y与X有如下的关系式:试编写程序,根据X的值求出Y,并放回原单元。解取出X后先做取值范围的判断,用累加器A状态转移指令判断X是否为0,用位状态转移指令判断X是大于0还是小于0。程序流程图如图4.3所示。程序如下:MOVA,30HJZZER0JNBACC.7,PLUSADDA,#5MOV30H,APLUS:SJMP$ZERO:MOV30H,#20HSJMP$END开始结束A=0?A0?(30H)A(30H)+5(30H)20H(30H)图4.3[例4-5]程序框图【例4-7】内部RAM40H和41H单元中各有一无符号数,比较其大小,将大数存放于内部RAM60H单元,小数存放于内部RAM61H单元,如两数相等,则分别送往这2个单元。解用比较不等转移指令CJNE比较力两个无符号书,先确定它们是否相等,若不相等时再根据借位标志确定这两个无符号书的大小。程序框图如图4.4所示。程序如下:Y开始A(41H)A与(61H)交换结束(40H)(60H)A(60H)N图4.4[例4-6]程序框图(40H)AMOVA,40HMOV61H,41HCJNEA,41H,LOOPAJMPAGEQLOOP:JNCAGEQ;A≥(41H)则无借位XCHA,61H;A<(41H)有借位;A与(61H)交换AGEQ:MOV60H,ASJMP$END【例4-8】某温度控制系统,采集的温度值(Ta)放在累加器A中。此外,在内部RAM54H单元存放控制温度下限(T54),在55H单元存放控制温度上限(T55)。若TaT55,程序转向JW(降温处理程序);若TaT54,则程序转向SW(升温处理程序);T55≥Ta≥T54,则程序转向FH(返回主程序)。程序如下:CJNEA,55H,LOOP1;Ta≠T55,转向LOOPlAJMPFH;Ta=T55,返回LOOPl:JNCJW;若(CY)=0,表明TaT55,转降温处理程序CJNEA,54H,LOOP2;Ta≠T54,转向LOOP2AJMPFH;Ta=54,返回LOOP2:JCSW;若(CY)=1,表明TaT54,转升温处理程序FH:RET;T55≥Ta≥T54,返回主程序【例4-9】N路分支程序,N≤8。要求程序根据其运行中所产生的寄存器R3的值,来决定如何进行分支。MOVA,R3MOVDPTR,#BRTABMOVCA,@A+DPTRJMP@A+DPTRBRTABAJMPBR0AJMPBR1AJMPBR2AJMPBR3BR0:SETBP1.0SJMPBRKBR1:SETBP1.1SJMPBRKBR2:SETBP1.2SJMPBRKBR3:SETBP1.3BRK:SJMPBRK4.4循环程序设计循环程序一般由4部分组成。(1)置循环初值。(2)循环体。(3)循环修改。(4)循环控制。图4.7(a)结构是“先执行后判断”,适用于循环次数已知的情况。图4.7(b)结构是“先判断后执行”,适用于循环次数未知的情况。YN开始置循环初值循环处理循环修改结束处理循环结束?结束Y(a)先执行后判断开始结束置循环初值循环结束?循环处理循环修改结束处理N(b)先判断后执行二、程序清单ORGOOOOHSTART:MOVA,#01H;使L1灯亮,其它不亮LOOP:MOVP1,A;从P1口输出到发光二极管MOVR1,#10H;延时1秒,根据机器周期算DEL1:MOVR2,#200DEL2:MOVR3,#126DEL3:DJNZR3,DEL3DJNZR2,DEL2DJNZR1,DEL1RLA;左移一位,下一个发光二极管亮AJMPLOOP;循环END【例4-10】多个单字节数求知。已知有10个单字节数,依次存放在内部RAM40H单元开始的数据存储区中,求和并将结果存人寄存器R2、R3中(高位存R2,低位存R3)。本题中,要重复进行加法运算,因此采用循环结构程序。循环次数就是数据块字节数,这是已知的。在置初值时,将数据块长度置人寄存器R5;将数据块首地址送人寄存器R0,即以R0作为数据块的地址指针,采用间接寻址方式:每做一次加法之后,修改地址指针,以便取出下一个数来相加,并且使计数器R5减l。到R5减为0时,求和结束。程序流程图如图4.8所示。ORG2000HSUM:MOVR0,#40H;设地址指针MOVR5,#0AH;计数器初值送R5SUM:MOVA,#00HMOVR2,ALP:ADDA,@R0JNCLP1INCR2;若有进位,和的高八位+1LP1:INCR0;地址指针+1DJNZR5,LP;判循环结束条件MOVR3,A;存和的低八位END【例4-11】从内存BLOCK单元开始有一个无符号数的数据块,其长度为LEN,试求出其最大值,并存入MAX单元。这是一个搜索问题。这里采用依次进行比较和取代的方法来寻找最大值。具体做法是:先取出第一个数作为基准,和第二个数比较,若比较结果基准数大,不作变动;若比较结果基准数小,则用大数来代替原基准数,然后再和下一个数作比较。到比较结束时,基准数就是所求的最大值。为了进行两数的比较,采用两数相减以后判断CY的值来确定哪个数大,这比用CJNE指令更简单。比较时将基准数放在累加器A中。若A中先放零,比较次数等于LEN;若A中先放人第一个数,则比较次数等于LEN-1。采用R2作为计数器,R1作为地址指针。程序流程如图4.9所示。ORG2000HCOMP:CLRAMOVR2,#LENMOVR1,#BLOCKMOVR3,ALOOP:CLRCMOVA,R3SUBBA,@R1JNCNEXT;A((R1))MOVA,@R1:A((R1))MOVR3,ANEXT:INCR1DJNZR2,LOOPMOVA,R3MOVMAX,A【例4-12】假设从内存RAM的50H单元,连续存放一串字符,以回车符(其ASCII码为0DH)作为结束标志,要求测出该字符串的长度。测试方法可采用将该字符串的每一个字符与回车符依次相比,若不相等,则将统计字符串长度的计数器加l,继续比较;若比较相等,则表示该字符串结束,这时计数器中的值就是字节符串的长度。程
本文标题:汇编程序设计
链接地址:https://www.777doc.com/doc-3297334 .html