接口技术-第4章-(46).ppt
《接口技术-第4章-(46).ppt》由会员分享,可在线阅读,更多相关《接口技术-第4章-(46).ppt(25页珍藏版)》请在冰豆网上搜索。
4.6模块化程序设计技术1.全局符号的定义与引用单个模块中使用的符号(变量、标号或子程序名)为局部符号。
一个模块中定义的符号如不另加说明,均为局部符号,局部符号只能在定义它的模块中使用。
多个模块可共同使用的符号为全局符号。
只要将局部符号在定义和使用它的模块中分别用PUBLIC和EXTRN语句说明,即可作为全局符号(又称外部符号)使用,全局符号构成了模块间通信的主要渠道。
2.模块间的转移模块间的转移有两种:
近(段内)转移和远(段间)转移。
它们都是通过转移语句来实现的。
具体实现转移的语句是:
JMP、CALL和INT。
3.多个模块的组合形式NONE表示本段为独立段,不与其他模块段发生连接逻辑。
PUBLIC表示将本段与其他模块中说明为PUBLIC的同名段邻接在一起,共用一个段地址。
组成一个大的物理段(“段组”)。
STACK表示将该段与其他同名的堆栈段连接在一起,组合后的物理段的长度等于参与组合的各堆栈段的长度之和。
COMMON各模块中由COMMON方式说明的同名段重叠覆盖,重叠部分的内容取决于参与覆盖的最后一个段的内容,复合段的长度等于参与覆盖的最长的段的长度。
MEMORY表示该段将位于被链接在一起的其他段之上(高地址处),如果链接时出现多个段有MEMORY组合类型,将对第一个MEMORY的段赋予这一属性,其他段作COMMON段处理。
例1:
键盘输入十进制数,以十六进制形式在屏幕上显示。
;模块A文件名MAIN.ASMEXTRNPROMPT:
FAR,BINHEX:
FAR;引用外部符号PUBLICDECNUM,KEYIN;定义外部符号SSEGSEGMENTPARASTACKSTACKDB100DUP(?
)SSEGENDSDSEG1SEGMENTDECNUMDW?
DSEG1ENDSCSEG1SEGMENTASSUMECS:
CSEG1,DS:
DSEG1,START:
MOVAX,DSEG1MOVDS,AX;装入段基址PUSHDSJMPFARPTRPROMPTKEYIN:
CALLDECBIN;键盘输入十进制数MOVDECNUM,BX;二进制数DECNUMCALLFARPTRBINHEX;以十六进制形式显示MOVAH,4CHINT21H;返回DOS,;从键盘输入十进制数,将其转换为二进制数并送BXDECBINPROCNEARMOVBX,0;累加和BX(已转换的二进制)初始化GETCHAR:
MOVAH,1INT21HSUBAL,30H;键入值是否在09之间?
JLEXIT;否,转至EXITCMPAL,09HJGEXITMOVAH,0;是,将AX中的BCD数与BX内容交换XCHGAX,BXMOVCX,0AH;累加和AX乘以当前权值MULCXXCHGAX,BXADDBX,AX;送累加和BXJMPGETCHAREXIT:
RETDECBINENDPCSEG1ENDSENDSTART,;模块B文件名SUB.ASMEXTRNDECNUM:
WORD,KEYIN:
FARPUBLICPROMPT,BINHEXSSEGSEGMENTPARASTACKSTACKDB200DUP(?
)SSEGENDSDSEG2ENDSCSEG2SEGMENTPARAASSUMECS:
CSEG2,DS:
DSEG2PROMPT:
MOVAX,DSEG2MOVDS,AX;装入段基址LEADX,MSGMOVAH,09HINT21HPOPDSJMPFARPTRKEYIN,;将DECNUM中的二进制数转换为十六进制数的ASCII码并输出BINHEXPROCFARMOVBX,DECNUMMOVCH,04H;共有4位十六进制数ROTATE:
MOVCL,04HROLBX,CL;取最4bit二进制数待转换MOVAL,BLANDAL,0FHADDAL,30H;十六进制数ASCII码CMPAL,3AH;十六进制数在09之间吗?
JLPRINTIT;是,输出ADDAL,07H;否,再加上07HPRINTIT:
MOVDL,AL;输出单个字符MOVAH,02HINT21HDECCHJNZROTATE;继续下次转换RETBINHEXENDPCSEG2ENDSEND,例2:
求无序表中的最大元素及其位置;模块A,文件名MAIN.ASMEXTRNFOUND:
NEARDATA1SEGMENTARRAYDBd1,d2,d3,dnCOUNTEQU$ARRAY;数据个数DATA1ENDSCODESEGMENTWORDPUBLICCODEASSUMECS:
CODE,DS:
DATA1MAIN:
MOVAX,DATA1MOVDS,AX;装入段基址MOVCX,COUNTLEASI,ARRAYCALLFOUND;找出最大元素及位置MOVAH,4CHINT21HCODEENDSENDMAIN,;模块B,文件名SUB.ASMPUBLICFOUNDDATA2SEGMENTMAXDB?
PLACEDB?
DATA2ENDSCODESEGMENTWORDPUBLICCODEASSUMECS:
CODE,FOUNDPROCNEARMOVDH,1MOVDL,0DECCXMOVAL,SICOMP:
CMPAL,SI+1JGBIGGERMOVAL,SI+1MOVDL,DHBIGGER:
INCSIINCDHLOOPCOMPASSUMEDS:
DATA2MOVBX,DATA2MOVDS,BXMOVMAX,ALMOVPLACE,DLRETFOUNDENDPCODEENDSEND,例1;D_SEGSEGMENTWDW8120;数据定义XDW40YDW16ZDW480RESULTDW2DUP(?
)D_SEGENDSS_SEGSEGMNETPARASTACKSTACKDW100DUP(?
)S_SEGENDSC_SEGSEGMENTASSUMECS:
C_SEG,DS:
D_SEGSTART:
MOVAX,D_SEG;填入段地址MOVDS,AXMOVAX,X;X+120ADDAX,120IMULY;(X+120)XYMOVCX,AX;乘积暂时存BX:
CXMOVBX,DXMOVAX,W;将W带符号扩展CWDSUBAX,CX;实现W(X+120)XYSBBDX,BX;结果在DX:
AX中ADDAX,200;实现W(X+120)XY+200ADCDX,0;结果在DX,AX中IDIVZ;最后除以Z,结果商在AX,余数在DX中MOVRESULT,AX;存放结果到数据区MOVRESULT+2,DXMOVAH,4CH;返回到DOSINT21HC_SEGENDSENDSTART;汇编结束,例1:
BCD码转换为二进制数设AX寄存器中存放着4位BCD码(09999),将其转换成二进制数并仍存于AX中,BCD码即用4位二进制数表示一个十进制数的编码。
所以AX=9827H表示值为9827该程序算法是:
(万位数0+千位数)10+百位数10+十位数10+个位数W10DW10;十进制数权值;子程序名:
BCDTO2。
入口参数:
AX=BCD码。
出口参数:
AX=二进制数。
BCDTO2PROCNEARPUSHBXPUSHCXPUSHDXMOVBX,AX;保存AX中的BCD码到BXMOVAX,0;结果单元清零MOVCX,4;共处理4位BCD码,RETRY:
PUSHCXMOVCL,4ROLBX,CL;1位BCD码移到BX中的低半字节POPCXMULW10;累加和AX10DX:
AXPUSHBXANDBX,000FH;取出BX中的1位BCD码ADDAX,BX;累加到AX中POPBXLOOPRETRYPOPDXPOPCXPOPBXRETBCDTO2ENDP,例2:
二进制数转换为BCD码编程将AX中的二进制数转换成4位BCD码,转换的结果放在AX中(设AX中的数值小于十进制数10000)。
算法:
将AX中的二进制数除以1000得到的商是千位上的BCD码,所得余数除以100得到的商是百位上的BCD码,所得余数再除以10得到的商是十位上的BCD码,最后所得的余数是个位上的BCD码。
W1000DW1000,100,10,1;十进制数千,百。
十,个位权值;子程序名:
AX2TOBCD。
入口参数:
AX=二进制数。
出口参数:
AX=压缩BCD码,AX2TOBCDPROCNEAR;保护现场XORBX,BX;BCD码暂存单元清零MOVSI,OFFSETW1000;权值首地址送SIMOVCX,4;循环次数4CXRETRY:
PUSHCXMOVCL,4SHLBX,CLMOVDX,0;DX:
AX组成被除数DIVWORDPTRSI;除以权值,商、余数在AX、DX中ORBX,AX;压缩BCD码MOVAX,DX;余数送AXPOPCXADDSI,2;地址加2,指向下一权值LOOPRETRYMOVAX,BX;BCD码由BXAX;恢复现场RETAX2TOBCDENDP,例3:
二进制数转换为ASCII码AX中的二进制数最大数值为65535,转换为ASCII码需5个字节单元。
程序首先将AX中的数除以10,所得余数为个位上的数,加上30H变为相应的ASCII码,所得的商再作为被除数除以10,得到的余数为十位上的数,加上30H变为相应的ASCII码,所得的商再作为被除数除以10,得到的余数为百位上的数,直到被除数小于10时,得到最后的一位数。
ASCBUFDB5DUP(0);子程序名;BINTOASC.入口参数;AX二进制数。
出口参数:
无。
BINTOASCPROCNEARMOVCX,10;除数送CXLEASI,ASCBUF+4;SI指向ASCII码个位数地址BTOA1:
CMPAX,10;二进制数小余10吗?
JBBTOA2;小余10转BTOA2XORDX,DX;被除数高字清0DIVCX;除以0ORDL,30H;余数变ASCII吗MOVSI,AL;存最高位的ASCII码DECSI;ASCII码地址减1JMPBTOA1BTOA2:
ORAL,30HMOVSI,AL;存最高位的ASCII码RETBINTOASCENDP,例5:
在字节数组中找出第一个非零元素,并显示它的下标.MODELSMALL.DATAARRAYDB0,0,0,25H,0,0,34H,36H,45HCOUNTEQU9.CODESTART:
MOVAX,DATAMOVDS,AXMOVCX,COUNTMOVDI,1NEXT:
INCDI;DI为元素下标CMPARRAYDI,0;从0号元素起,逐个与0比较LOOPZNEXTJNEOK;ZF0,即有非零单元素,转OKMOVDL,0;没有找到非零元素,显示一个0OK:
MOVDX,DIORDL,30H;将下标字符转换成ASCII码SHOW:
MOVAH,02HINT21HMOVAX,4C00H;显示下标INT21H;返回DOS.STACKENDSTART,例6:
在目的串中指定位置上插入字符串;子程序名:
STR_INSERT;入口参数DS:
BX指向源串,ES:
BP指向目的串,ES:
DX指向目的串中插入源串的位置。
每个串的前两个字节内为16位的串长度。
;出口参数在目的串指定位置上插入了源串STR_INSERTPROCFAR;保护现场MOVSI,BP;当前目的串首地址SIAD