1、4.6模块化程序设计技术1.全局符号的定义与引用单个模块中使用的符号(变量、标号或子程序名)为局部符号。一个模块中定义的符号如不另加说明,均为局部符号,局部符号只能在定义它的模块中使用。多个模块可共同使用的符号为全局符号。只要将局部符号在定义和使用它的模块中分别用 PUBLIC 和EXTRN语句说明,即可作为全局符号(又称外部符号)使用,全局符号构成了模块间通信的主要渠道。2.模块间的转移模块间的转移有两种:近(段内)转移和远(段间)转移。它们都是通过转移语句来实现的。具体实现转移的语句是:JMP、CALL 和 INT。,3.多个模块的组合形式NONE 表示本段为独立段,不与其他模块段发生连接
2、逻辑。PUBLIC 表示将本段与其他模块中说明为PUBLIC的同名段邻接在一起,共用一个段地址。组成一个大的物理段(“段组”)。STACK 表示将该段与其他同名的堆栈段连接在一起,组合后的物理段的长度等于参与组合的各堆栈段的长度之和。COMMON 各模块中由COMMON方式说明的同名段重叠覆盖,重叠部分的内容取决于参与覆盖的最后一个段的内容,复合段的长度等于参与覆盖的最长的段的长度。MEMORY 表示该段将位于被链接在一起的其他段之上(高地址处),如果链接时出现多个段有MEMORY组合类型,将对第一个MEMORY的段赋予这一属性,其他段作COMMON段处理。,例1:键盘输入十进制数,以十六进制
3、形式在屏幕上显示。;模块A 文件名MAIN.ASM EXTRN PROMPT:FAR,BINHEX:FAR;引用外部符号PUBLIC DECNUM,KEYIN;定义外部符号SSEG SEGMENT PARA STACK STACK DB 100 DUP(?)SSEG ENDSDSEG1 SEGMENTDECNUM DW?DSEG1 ENDSCSEG1 SEGMENT ASSUME CS:CSEG1,DS:DSEG1,START:MOV AX,DSEG1 MOV DS,AX;装入段基址 PUSH DS JMP FAR PTR PROMPTKEYIN:CALL DECBIN;键盘输入十进制数 MO
4、V DECNUM,BX;二进制数DECNUM CALL FAR PTR BINHEX;以十六进制形式显示 MOV AH,4CH INT 21H;返回DOS,;从键盘输入十进制数,将其转换为二进制数并送BXDECBIN PROC NEAR MOV BX,0;累加和BX(已转换的二进制)初始化GETCHAR:MOV AH,1 INT 21H SUB AL,30H;键入值是否在09之间?JL EXIT;否,转至EXIT CMP AL,09H JG EXIT MOV AH,0;是,将AX中的BCD数与BX内容交换 XCHG AX,BX MOV CX,0AH;累加和AX乘以当前权值 MUL CX XCH
5、G AX,BX ADD BX,AX;送累加和 BX JMP GETCHAREXIT:RETDECBIN ENDPCSEG1 ENDS END START,;模块B 文件名SUB.ASMEXTRN DECNUM:WORD,KEYIN:FARPUBLIC PROMPT,BINHEXSSEG SEGMENT PARA STACK STACK DB 200 DUP(?)SSEG ENDSDSEG2 ENDSCSEG2 SEGMENT PARA ASSUME CS:CSEG2,DS:DSEG2PROMPT:MOV AX,DSEG2 MOV DS,AX;装入段基址 LEA DX,MSG MOV AH,09
6、H INT 21H POP DS JMP FAR PTR KEYIN,;将DECNUM中的二进制数转换为十六进制数的ASCII 码并输出BINHEX PROC FAR MOV BX,DECNUM MOV CH,04H;共有4位十六进制数ROTATE:MOV CL,04H ROL BX,CL;取最4bit二进制数待转换 MOV AL,BL AND AL,0FH ADD AL,30H;十六进制数 ASCII码 CMP AL,3AH;十六进制数在09之间吗?JL PRINTIT;是,输出 ADD AL,07H;否,再加上07HPRINTIT:MOV DL,AL;输出单个字符 MOV AH,02H I
7、NT 21H DEC CH JNZ ROTATE;继续下次转换 RETBINHEX ENDPCSEG2 ENDS END,例2:求无序表中的最大元素及其位置;模块A,文件名MAIN.ASMEXTRN FOUND:NEARDATA1 SEGMENTARRAY DB d1,d2,d3,dnCOUNT EQU$ARRAY;数据个数DATA1 ENDSCODE SEGMENT WORD PUBLIC CODE ASSUME CS:CODE,DS:DATA1MAIN:MOV AX,DATA1 MOV DS,AX;装入段基址 MOV CX,COUNT LEA SI,ARRAY CALL FOUND;找出最
8、大元素及位置 MOV AH,4CH INT 21HCODE ENDS END MAIN,;模块B,文件名SUB.ASMPUBLIC FOUNDDATA2 SEGMENTMAX DB?PLACE DB?DATA2 ENDSCODE SEGMENT WORD PUBLIC CODE ASSUME CS:CODE,FOUND PROC NEAR MOV DH,1 MOV DL,0 DEC CX MOV AL,SICOMP:CMP AL,SI+1 JG BIGGER MOV AL,SI+1 MOV DL,DHBIGGER:INC SI INC DH LOOP COMP ASSUME DS:DATA2
9、MOV BX,DATA2 MOV DS,BX MOV MAX,AL MOV PLACE,DL RETFOUND ENDPCODE ENDS END,例1;D_SEG SEGMENTW DW 8120;数据定义X DW 40Y DW 16Z DW 480RESULT DW 2 DUP(?)D_SEG ENDSS_SEG SEGMNET PARA STACK STACK DW 100 DUP(?)S_SEG ENDSC_SEG SEGMENT ASSUME CS:C_SEG,DS:D_SEGSTART:MOV AX,D_SEG;填入段地址 MOV DS,AX MOV AX,X;X+120 ADD
10、AX,120 IMUL Y;(X+120)X Y MOV CX,AX;乘积暂时存BX:CX MOV BX,DX MOV AX,W;将W带符号扩展 CWD SUB AX,CX;实现W(X+120)X Y SBB DX,BX;结果在DX:AX中 ADD AX,200;实现W(X+120)X Y+200 ADC DX,0;结果在DX,AX中 IDIV Z;最后除以Z,结果商在AX,余数在DX中 MOV RESULT,AX;存放结果到数据区 MOV RESULT+2,DX MOV AH,4CH;返回到DOS INT 21HC_SEG ENDS END START;汇编结束,例1:BCD码转换为二进制数
11、设AX寄存器中存放着4位BCD码(09999),将其转换成二进制数并仍存于AX中,BCD码即用4位二进制数表示一个十进制数的编码。所以AX=9827H表示值为9827该程序算法是:(万位数0+千位数)10+百位数10+十位数10+个位数 W10 DW 10;十进制数权值;子程序名:BCDTO2。入口参数:AX=BCD码。出口参数:AX=二进制数。BCDTO2 PROC NEAR PUSH BX PUSH CX PUSH DX MOV BX,AX;保存AX中的BCD码到BX MOV AX,0;结果单元清零 MOV CX,4;共处理4位BCD码,RETRY:PUSH CX MOV CL,4 ROL
12、 BX,CL;1位BCD码移到BX中的低半字节 POP CX MUL W10;累加和AX 10 DX:AX PUSH BX AND BX,000FH;取出BX中的1位BCD码 ADD AX,BX;累加到AX中 POP BX LOOP RETRY POP DX POP CX POP BX RETBCDTO2 ENDP,例2:二进制数转换为BCD码编程将AX中的二进制数转换成4位BCD码,转换的结果放在AX中(设AX中的数值小于十进制数10000)。算法:将AX中的二进制数除以1000得到的商是千位上的BCD码,所得余数除以100得到的商是百位上的BCD码,所得余数再除以10得到的商是十位上的BC
13、D码,最后所得的余数是个位上的BCD码。W1000 DW 1000,100,10,1;十进制数千,百。十,个位权值;子程序名:AX2TOBCD。入口参数:AX=二进制数。出口参数:AX=压缩BCD码,AX2TOBCD PROC NEAR;保护现场 XOR BX,BX;BCD码暂存单元清零 MOV SI,OFFSET W1000;权值首地址送SI MOV CX,4;循环次数4CXRETRY:PUSH CX MOV CL,4 SHL BX,CL MOV DX,0;DX:AX组成被除数 DIV WORD PTRSI;除以权值,商、余数在AX、DX中 OR BX,AX;压缩BCD 码 MOV AX,D
14、X;余数送AX POP CX ADD SI,2;地址加2,指向下一权值 LOOP RETRY MOV AX,BX;BCD码由BXAX;恢复现场 RETAX2TOBCD ENDP,例3:二进制数转换为ASCII码 AX中的二进制数最大数值为65535,转换为ASCII码需5个字节单元。程序首先将AX中的数除以10,所得余数为个位上的数,加上30H变为相应的ASCII码,所得的商再作为被除数除以10,得到的余数为十位上的数,加上30H变为相应的ASCII码,所得的商再作为被除数除以10,得到的余数为百位上的数,直到被除数小于10时,得到最后的一位数。ASCBUFDB 5 DUP(0);子程序名;B
15、INTOASC.入口参数;AX 二进制数。出口参数:无。,BINTOASCPROCNEARMOVCX,10;除数送CXLEASI,ASCBUF+4;SI指向ASCII码个位数地址BTOA1:CMPAX,10;二进制数小余10吗?JBBTOA2;小余10转BTOA2XOR DX,DX;被除数高字清0DIVCX;除以0ORDL,30H;余数变ASCII吗MOVSI,AL;存最高位的ASCII码DEC SI;ASCII码地址减1 JMP BTOA1BTOA2:OR AL,30H MOV SI,AL;存最高位的ASCII 码 RETBINTOASC ENDP,例5:在字节数组中找出第一个非零元素,并显
16、示它的下标.MODEL SMALL.DATAARRAY DB 0,0,0,25H,0,0,34H,36H,45HCOUNT EQU 9.CODESTART:MOV AX,DATA MOV DS,AX MOV CX,COUNT MOV DI,1NEXT:INC DI;DI为元素下标 CMP ARRAYDI,0;从0号元素起,逐个与0比较 LOOPZ NEXT JNE OK;ZF0,即有非零单元素,转OK MOV DL,0;没有找到非零元素,显示一个0OK:MOV DX,DI OR DL,30H;将下标字符转换成ASCII码SHOW:MOV AH,02H INT21H MOV AX,4C00H;显示下标 INT21H;返回DOS.STACK ENDSTART,例6:在目的串中指定位置上插入字符串;子程序名:STR_INSERT;入口参数 DS:BX指向源串,ES:BP指向目的串,ES:DX指向目的串中插入源串的位置。每个串的前两个字节内为16位的串长度。;出口参数 在目的串指定位置上插入了源串STR_INSERT PROC FAR;保护现场 MOV SI,BP;当前目的串首地址 SI AD
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1