您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第4章 8086汇编语言程序设计(2)汇编语言程序设计举例举例1
第4章8086汇编语言程序设计4-5汇编语言程序设计举例3-3-4汇编语言程序设计方法一、程序设计步骤1.根据实际问题抽象出数学模型2.确定解决此数学模型的算法3.分配内存工作单元和寄存器4.画出程序框图(流程图)5.根据框图编制程序6.上机调试,进行修改基本方法:二、如何划程序框图3.用菱形框表示判断框框中标明比较、判断和条件=0?NY1.用圆边框表示起始和终止框框中标明起始或终止框中用简明语言标明要完成的功能2.用方框表示工作框4.用双边框表示调用子程序或过程框中标明子程序名字(入口参数等)5.各框之间用直线连起来表示程序走向3-3-5汇编语言程序设计举例对字符串进行操作时,往往需要确定它的长度,通常字符串结束标志以CR或$作标志。1.字符串处理程序设计先看流程图:开始求串长串长256?显示串长高位显示串长低位结束Y警告:太长N子程序串符是‘$’?搜索CR返回N串长加1存串长找到?NYY确定串长流程DATASEGMENTSTRINGDB‘Thisisastring┄’,0DH,’$’LENGTH1DW?;存串长CRDB0DHMESSAGEDB‘Thestringistoolong!’,0D,0A,’$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARBEGIN:MOVAX,DATAMOVES,AXMOVDS,AXCALLSTRLEN;调子程序MOVDX,LENGTH1CMPDX,100HJBNEXT1;若(DX)100H,转LEADX,MESSAGE;若(DX)≥100H,MOVAH,9INT21H;显示信息程序:JMPNEXT2NEXT1:MOVDH,DL;串长暂存DHMOVCL,4SHRDL,CL;取串长高4位CMPDL,9JBELP;≤9,转ADDDL,7;9,加7LP:ADDDL,30H;高4位化为ASCII码MOVAH,6INT21H;显示这个ASCII码MOVDL,DH;取暂存串长ANDDL,0FH;取串长低4位CMPDL,9JBELP1;≤9,转ADDDL,7;9,加7LP1:ADDDL,30H;低4位化为ASCII码MOVAH,6INT21H;显示该ASCII码MOVDL,’H’MOVAH,6INT21H;显示’H’NEXT2:MOVAH,4CHINT21H;返回DOSMAINENDPSTRLENPROCLEADI,STRINGMOVCX,0FFFFH;(CX)=-1MOVAL,CR;(AL)=0DHMOVAH,’$’;(AH)=’$’CLD;DF=0AGAIN:INCCX;串长加1,初始值(CX)=0CMPCX,100HJAEDONE;串长255,则结束CMP[DI],AH;((DI))=’$’?JEDONE;是,则结束SCASB;(AL)-((DI)),找回车JNEAGAIN;未找到,返回继续DONE:MOVLENGTH1,CX;找到,LENGTH1←串长RET;返回主程序STRLENENDPCODEENDSENDBEGIN本例重点掌握:搜索关键字十六进制→ASCII码显示字符串及单个字符I/O装置通常按ASCII码处理数据。人们习惯用十进制数,而机器内以二进制方式运算,故这几者之间常需转换。2.码转换程序设计①一个十六进制数→ASCII码(用于输出)上面确定字符串长度例子中,化ASCII显示已介绍过。②ASCII码→二进制数(用于输入))例:从键盘输入两个整数,并求其和。因键入为整数,故要进行如下转换:ASCII→BCD→二进制数ASCII→BCD码很简单,去高4位即可BCD→二进制数?有两种方法:((千位数*10+百位数)*10+十位数)*10+个位数千位数*1000+百位数*100+十位数*10+个位数介绍第一种方法:开始两个数分别转换成二进制数键入两个数相加结束返回DOS如有溢出则提示开始得第一个ASCII是负数吗?数字符个数-1,指针+1指针定位字符个数-1是0吗?取数字符,与原值相加,乘以10指向下一个数字符加个位数是负数则求补存结果返回结束NYYN流程图:DATASEGMENTSTR1DB10,?,10DUP(?)STR2DB10,?,10DUP(?)NUMDW?,?;存二进制BUFFERDW0;存和OVERDB‘overflow!’,13,10,’$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARSTART:MOVAX,DATAMOVDS,AXMOVAH,0AHLEADX,STR1INT21H;输入第一个数字串(设为26)MOVAH,0AHLEADX,STR2INT21H;输入第二个数字串(设为33)程序:LEABX,STR1;输入串首地址送BXLEADI,NUM;存二进制首地址送DICALLCHANGE;将串1ASCII码→二进制LEABX,STR2;输入串2首地址送BXLEADI,NUM+2CALLCHANGE;将串2ASCII码→二进制MOVAX,NUM;(AX)=[NUM]=001AHADDAX,NUM+2;两数相加,(AX)=003BHMOVBUFFER,AX;存和JNONEXT;无溢出,转NEXTLEADX,OVERMOVAH,9INT21H;显示’overflow!’NEXT:MOVAH,4CHINT21H;返回DOSMAINENDPCHANGEPROCMOVCL,[BX+1];实际字符数送CLMOVAL,[BX+2];第一个字符送ALMOVCH,AL;暂存在CHCMPAL,’-’;第一个字符是’-’吗?JNZNEXT1;不是,转NEXT1DECCL;字符数减1INCBXNEXT1:ADDBX,2;指向第一个数字字符MOVAX,0;清零AX,存二进制数LP1:DECCLJZNEXT2;若(CL)=0,转NEXT2MOVDH,0MOVDL,[BX];得到该数字ANDDL,0FH;ASCII→未组合BCD第1次(键入26)ADDAX,DX;(AX)=0002HADDAX,AX;*2(AX)=0004HMOVDX,AX(DX)=0004HADDAX,AX;*4(AX)=0008HADDAX,AX;*8(AX)=0010HADDAX,DX;*10(AX)=0014H*10INCBX;指向下一个字符JMPSHORTLP1NEXT2:MOVDL,[BX];取个位数ANDDL,0FH;个位ASCII→未组合BCDMOVDH,0ADDAX,DX;加个位数,(AX)=001AHCMPCH,’-’;是’-’?JNZNEXT3;该数非负,转NEXT3NEGAX;若为负,求补NEXT3:MOV[DI],AX;存二进制结果RETCHANGEENDPCODEENDSENDSTART设键入第一个数为26,第二个数为33,则在内存中各变量分配如下:若键入1234STR10ASTR10A0204323136320D33┇34STR20A0D02┇33330D┇NUM1A002100BUFFER3B0010个10个??本例题重点掌握:键盘输入字符串ASCII→未组合BCD→二进制有符号数加,对负数处理,对溢出处理思考题:若键入第一个数26,第二个数为-4,填写各变量结果。方法1:找二进制数中包含1000,100,10的个数转换为相应的BCD码,最后将个位数转换为BCD码。方法2:将二进制数不断地除以10,并记下余数,直到商为0为止,余数系列即为所求的BCD码,第一个余数为BCD码低位。介绍第一种方法。③二进制→BCDYN二进制数AX令(DL)=0(AX)-10000?(DL)+1(AX)+1000(AX)DL存至缓冲区令(DL)=0YN(AX)-100?(DL)+1(AX)+10(AX)存DL存AL返回DOSMM流程图:DATASEGMENTBNUMDB270FHDNUMDB4DUP(?);存BCD码的缓冲区DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATABINBCDPROCFARBEGIN:MOVAX,DATAMOVDS,AXMOVAX,BNUM;取二进制数LEABX,DNUM;存BCD码首地址送BXMOVDL,0AGAIN1:SUBAX,03E8H;(AX)-1000JCNEXT1;不够减,即CF=1转INCDL;(DL)+1JMPAGAIN1程序:NEXT1:ADDAX,03E8H;(AX)←(AX)+1000MOV[BX],DL;存DLINCBX;BX加1MOVDL,0;令(DL)=0AGAIN2:SUBAX,0064H;(AX)-100JCNEXT2INCDLJMPAGAIN2NEXT2:ADDAX,0064HMOV[BX],DLINCBXMOVDL,0AGAIN3:SUBAX,000AH;(AX)-10JCNEXT3INCDLJMPAGAIN3NEXT3:ADDAX,000AHMOV[BX],DLINCBXMOV[BX],ALMOVAH,4CHINT21HBINBCDENDPCODEENDSENDBEGIN此例得到的结果为09090909,为非压缩的BCD码,亦可拼成压缩BCD码。一个二进制位串若要送显示或打印,需把串中每一位(0或1)化为ASCII码。思路:先将存ASCII单元全部送上30H,再分别取出每个二进制位,左移至CF,然后判:CF=0?是,取下一位;否,将31H送此单元。④BCD→ASCII(不介绍了)⑤二进制串转换为ASCII码011011110111100030303030303030303030303030303030NN初始化用‘0’填满串取要转换的数左移一位CF=1?存入‘1’修改地址指针返回DOS完成否?YY流程图:DATASEGMENTNUMDW6F78HSTRINGDB16DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATABINCAPROCFARBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXCLDLEADI,STRINGMOVCX,LENGTHSTRING;(CX)=16PUSHDI;为什么压栈?PUSHCX;因DI、CX随REP重复而改变MOVAL,30HREPSTOSB;((DI))←(AL),(DI)←(DI)+1直至CX为0程序:POPCXPOPDIMOVAL,31HMOVBX,NUM;(BX)=6F78HAGAIN:RCLBX,1;含进位位循环左移JNCNEXT;若为0,转MOV[DI],AL;若为1,则送’1’NEXT:INCDILOOPAGAINMOVAH,4CHINT21HBINCAENDPCODEENDSENDBEGINCFBX编写子程序时,很重要的一个工作是如何把参数传给子程序,这个过程叫参数传送。传送方法有:3.子程序设计把参数放在CPU内部寄存器中把参数放在变量中把参数放在地址表中利用堆栈传送参数下面介绍第4种方法,它通常在主程序中把参数或参数地址保存在堆栈中,而在子程序中将参数从堆栈取出来。例:把一个用十六进制表示的字→ASCII码,然后送显示。DATASEGMENTNUMDW25AFHSTRINGDB4DUP(?),13,10,’$’DATAENDSSTACKSEGMENTDB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,ES:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXMOVAX,STACKMOVSS,AXLEABX,STRING;取变量偏址PUSHBX;将偏址压栈PUSHNUM;将变量压栈程序:(SP)00020064H0062H25AF0060H堆栈CALLBINHEX;(SP)=005EHCS:0113LEADX,STRING;(DX)=0002HMOVAH,9INT21HMOVAH,4CHINT21H;***********************BINHEXPROCPUS
本文标题:第4章 8086汇编语言程序设计(2)汇编语言程序设计举例举例1
链接地址:https://www.777doc.com/doc-3955582 .html