第4章 汇编语言程序设计3(常见程序设

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

11.码制转换十、二进制数、ASCII码之间的互相转换。①BCD数→2进制数算法:Dn-1*10n-1+……+D0*100=(…(Dn-1*10+Dn-2)*10+…)*10+D0=(…((0*10+Dn-1)*10+Dn-2)*10+…)*10+D0即:新的中间结果=中间结果*10+本位数字(中间结果初值为0)4.5常见程序设计举例2程序1:将≤65535的非压缩BCD数转换成2进制数。程序如下:;数据段定义mydataSEGMENTdecnumDB5,3,0,1,9;BCD数53019binnumDW?mydataENDS3progSEGMENTASSUMECS:prog,DS:mydatabegin:MOVAX,mydataMOVDS,AXMOVSI,OFFSETdecnumMOVCX,5;5位BCD数MOVBX,10XORAX,AX;中间结果初始值为0Next:MULBX;中间结果*10+本位数字ADDAL,[SI]ADCAH,0INCSI;指向下位BCD数LOOPnextMOVbinnum,AX;保存结果MOVAH,4CHINT21HprogENDSENDbegin4程序2:把≤255的非压缩BCD数转换成2进制数decnumDB1,5,9;BCD数159binnumDB?……MOVAX,decnumXCHGAH,AL;百位在AH,十位在ALAAD;百位数*10+十位数MOVAH,AL;中间结果送AHMOVAL,decnum+2AAD;中间结果*10+个位数MOVbinnum,AL……5例:从键盘输入两个整数,并求其和。因键入为整数,故要进行如下转换:ASCII→BCD→二进制数ASCII→BCD码很简单,高4位清零即可得到非压缩的BCD码。BCD→二进制数在本例中采用用以下方法:((((0+千位数)*10+百位数)*10)+十位数)*10+个位数②ASCII码→二进制数(用于输入)第一次中间结果第二次中间结果第三次中间结果最终结果6开始两个数分别转换成二进制数键入两个数相加结束返回DOS如有溢出则提示开始取第一个ASCII码是负号吗?数字符个数-1,指针+1指针定位字符个数-1=0?取数字,与中间结果相加,再乘以10指向下一个数字字符加个位数是负数则求补存结果结束NYYN转换子程序7程序如下:DATASEGMENTSTR1DB10,?,10DUP(?);第1个数的输入缓冲区STR2DB10,?,10DUP(?);第2个数的输入缓冲区NUMDW?,?;存转换后的二进制数SUMDW0;存和OVERDB‘Overflow!’,13,10,’$’DATAENDS;CODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFAR8START:MOVAX,DATAMOVDS,AXMOVAH,0AHLEADX,STR1INT21H;输入第一个数字串(设为26)MOVAH,0AHLEADX,STR2INT21H;输入第二个数字串(设为33)LEABX,STR1;串1的首地址送BXLEADI,NUM;存二进制首地址送DICALLCHANGE;将串1ASCII码→二进制LEABX,STR2;串2的首地址送BX9LEADI,NUM+2;指向CALLCHANGE;将串2ASCII码→二进制MOVAX,NUM;(AX)=[NUM]=001AHADDAX,NUM+2;两数相加,(AX)=003BHMOVSUM,AX;存和JNONEXT;无溢出,转NEXTLEADX,OVERMOVAH,9INT21H;显示’Overflow!’NEXT:MOVAH,4CHINT21H;返回DOSMAINENDP10CHANGEPROCMOVCL,[BX+1];实际字符数送CLMOVAL,[BX+2];第一个字符送ALMOVCH,AL;暂存在CHCMPAL,’-’;第一个字符是负号吗?JNZNEXT1;不是,转NEXT1DECCL;字符数减1INCBXNEXT1:ADDBX,2;指向第一个数字字符MOVAX,0;清零AX,存二进制数LP1:DECCLJZNEXT2;若(CL)=0,转NEXT2MOVDL,[BX];取字符ANDDL,0FH;转换成BCD码ADDAL,DL;加到中间结果上ADCAH,011MOVDX,10MULDX;*10INCBX;指向下一个字符JMPSHORTLP1NEXT2:MOVDL,[BX];取个位数ANDDL,0FH;个位ASCII→未组合BCDADDAX,DX;加个位数,(AX)=001AHCMPCH,’-’;是’-’?JNZNEXT3;该数非负,转NEXT3NEGAX;若为负,求补NEXT3:MOV[DI],AX;存二进制结果RETCHANGEENDP;CODEENDSENDSTART12020A32360D…020A33330D…001A21003B00STR1STR2NUMSUM10个10个‘O’……OVER??040A313234…STR1若键入‘1234’330D‘1’‘2’‘3’‘4’…设键入第1个数为26,第2个数为33,则在内存各变量分配如下:13本例题重点掌握:*如何从键盘输入一个字符串*ASCII→未组合BCD→二进制*有符号数的运算,对负数和溢出如何处理思考题:若键入第一个数26,第二个数为-4,填写各变量结果。14方法1计算二进制数中所包含的1000的个数、100的个数、10的个数和1的个数。方法2除10取余。下面举例介绍第一种方法。流程图如下:③二进制数→BCD15YN二进制数AX令(DL)=0(AX)-10000?(DL)+1(AX)+1000(AX)DL存至缓冲区令(DL)=0YN(AX)-100?(DL)+1(AX)+10(AX)存DL存AL返回DOS求100的个数,结构同上A16汇编程序如下:DATASEGMENTBNUMDB270FHDNUMDB4DUP(?);存放BCD码的缓冲区DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATABINBCDPROCFARBEGIN:MOVAX,DATAMOVDS,AXMOVAX,BNUM;取二进制数LEABX,DNUM;BCD码缓冲区首地址送BX17;计算百位的个数MOVDL,0;千位的个数计数器AGAIN1:SUBAX,1000;(AX)-1000JCNEXT1;若≤0,则退出循环INCDL;(DL)+1JMPAGAIN1NEXT1:ADDAX,1000;(AX)←(AX)+1000MOV[BX],DL;存千位的个数;计算百位的个数MOVDL,0;百位的个数计数器AGAIN2:SUBAX,100;(AX)-100JCNEXT2INCDLJMPAGAIN2NEXT2:ADDAX,100MOV[BX+1],DL;存百位的个数18MOVDL,0;十位的个数计数器AGAIN3:SUBAX,10;(AX)-10JCNEXT3INCDLJMPAGAIN3NEXT3:ADDAX,10MOV[BX+2],DL;存十位的个数MOV[BX+3],AL;存个位的个数MOVAH,4CHINT21HBINBCDENDP;CODEENDSENDBEGIN19④BCD→ASCII前面举例介绍过,略。⑤二进制串转换为ASCII码一个二进制位串若要送显示或打印,需把串中每一位(0或1)化为ASCII码。思路:先将目标串全部预置为30H,再把每个二进制位逐位左移至CF,然后判CF=0?若是,取下一位;若不是,将31H送此单元。流程图如下:20初始化用’0’填满串取要转换的数左移1位存入‘1’结束CF=1?转换完?调整指针NN21汇编程序如下:DATASEGMENTNUMDW6F78HSTRINGDB16DUP(?)DATAENDS;CODESEGMENTASSUMECS:CODE,DS:DATABINCAPROCFARBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXCLDLEADI,STRINGMOVCX,16;串的长度22MOVAL,30HREPSTOSB;串中全部填充为‘0’MOVCX,16LEADI,STRINGMOVAL,’1’MOVBX,NUM;(BX)=6F78HAGAIN:RCLBX,1;含进位位循环左移JNCNEXT;若为0,转MOV[DI],AL;若为1,对应位送入’1’NEXT:INCDILOOPAGAIN23MOVAH,4CHINT21HBINCAENDPCODEENDSENDBEGIN242.子程序的参数传递编写子程序时,很重要的一个工作是如何把参数传给子程序,这个过程叫参数传送。传送方法有:把参数放在CPU内部寄存器中把参数放在变量中把参数放在地址表中利用堆栈传送参数25下面举例介绍第4种方法,它通常在主程序中把参数或参数地址保存在堆栈中,而在子程序中将参数从堆栈取出来。例:把一个用十六进制表示的字→ASCII码,然后送到屏幕上显示。汇编程序如下:DATASEGMENTNUMDW25AFH;要显示的数STRINGDB4DUP(?),13,10,’$’DATAENDS26STACKSEGMENTDB100DUP(?)TOPEQU$STACKENDS;CODESEGMENTASSUMECS:CODE,DS:DATA,ES:DATA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVES,AXMOVAX,STACKMOVSS,AXMOVSP,TOPLEABX,STRING;取变量偏址PUSHBX;将偏址压栈PUSHNUM;将变量压栈00020064H0062H(SP)25AF0060H堆栈27CALLBINHEX;(SP)=005EHCS:0113LEADX,STRING;(DX)=0002HMOVAH,9INT21HMOVAH,4CHINT21H;***********************BINHEXPROCPUSHBP;(SP)=005CHMOVBP,SP;(BP)=005CHPUSHAX;(SP)=005AHPUSHDI;(SP)=0058HPUSHCX;(SP)=0056HPUSHDX;(SP)=0054H00020064H0062H25AF0060H005EH0113005CH(SP)返回地址(IP)原(BP)2800020064H0062H25AF0060H005EH0113xxxx005CH(BP)PUSHF;(SP)=0052HMOVAX,[BP+4];(AX)=25AFHMOVDI,[BP+6];(DI)=0002HADDDI,LENGTHSTRING-4;(DI)=0005HMOVDX,AX;(DX)=25AFHMOVCX,4STD;从后往前存AGAIN:ANDAX,0FH;第一次(AX)=000FHCALLHEXD;转换为ASCII码STOSBPUSHCXMOVCL,4SHRDX,CL;逻辑右移4位MOVAX,DX;第1次(AX)=025AHPOPCXLOOPAGAIN;(CX)-1=0?不等,转+429POPFPOPDXPOPCXPOPDIPOPAXPOPBPRET4BINHEXENDP;********************HEXDPROCCMPAL,0AHJLLPADDAL,7LP:ADDAL,30HRETHEXDENDPCODEENDSENDBEGIN0064H0062H0060H005EH005CH000225AF0113xxxx(SP)30从本例可知,通过堆栈传递的两个参数分别为:变量NUM的内容25AFH和变量STRING的偏移地址。这两个参数在调用子程序之前压入堆栈,当CALL指令返回时,其(SP)=0060H,不是初值0064H。故采用带参数返回指令RET4。本例重点掌握:*进一步了解堆栈的使用*学会RETn的应用*子程序嵌套31其他例子宏的使用例子逻辑尺的例子查表法求立方值作业:p1944.6(1),4.10,4.17,4.18(用逻辑尺)

1 / 31
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功