资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,5.1 汇编语言源程序的框架结构,编制汇编语言源程序时,首先要使用段定义伪指令和段寻址伪指令来构造一个由若干指令和数据组成的程序。构造一个源程序的框架结构有如下两种格式:,第一种格式:,MOVAH,4CH ;返回DOS,INT21H,CODEENDS,ENDBEGIN,第5章 8086/8088汇编语言程序设计,1,第二种格式:,RET;取程序段前缀首地址,MAINENDP,CODEENDS,ENDBEGIN,区别:两种格式的本质区别在于返回DOS的方法不同:,对于第一种格式,采用了调用DOS系统的4CH功能,返回DOS。具体方法是:在要返回DOS处,安排如下两条指令:,MOVAH,4CH,INT21H,对于第二格式,DOS返回方法是调用20H类型的中断服务程序。,2,5.2 顺序结构程序设计,顺序程序结构是指完全按照顺序逐条执行的指令序列,这种结构的流程图除了有一个开始框和结束框外,就是若干处理框,没有判断框,如图5.1所示。,图5.1 顺序程序的结构形式,3,例5.1:试分别用汇编语言源程序的两种框架结构编制程序,求出表达式:(X4Y)/2的值,并保存到RESULT存储单元中,其中X,Y均为字节变量,。,解:完成该功能的流程图如图5.2所示:,图5.2 例5.1的功能实现流程图,4,参考程序1:,DATASEGMENT;数据段,XDB2,YDB4,ZDB?;定义变量,DATAENDS,STACKSEGMENT PARASTACK,DW20HDUP(0),STACKENDS,CODESEGMENT;代码段,ASSUME CS:CODE,DS:DATA,SS:STACK,5,BEGIN:MOVAX,DATA,MOVDS,AX;DS赋初值,MOVAL,X;ALX,MOVCL,2,SALAL,CL;ALX4,SUBAL,Y;ALX4Y,SARAL,1;AL(X4Y)/2,MOVZ,AL;存结果,MOVAH,4CH;返回DOS,INT21H,CODEENDS,ENDBEGIN,6,参考程序2:,DATASEGMENT,XDB2,YDB4,ZDB?,DATAENDS,STACKSEGMENTPARASTACK,DW20HDUP(0),STACKENDS,CODESEGMENT,ASSUMECS:CODE,DS:DATA,SS:STACK,PROC1PROCFAR;使RET为远返回,ENDBEGIN,7,BEGIN:PUSHDS;入栈保存地址,MOVAX,0;程序段前缀的首地址,PUSHAX,MOVAX,DATA,MOVDS,AX,MOVAL,X;ALX,MOVCL,2,SALAL,CL;ALX4,SUBAL,Y;ALX4Y,SARAL,1;AL(X4Y)/2,MOVZ,AL;存结果,RET;取程序段前缀首地址,8,PROC1ENDP,CODEENDS,5.3 分支结构程序设计,分支程序结构可以有两种形式,如图5.4所示,它们分别相当于高级语言程序中的IF-THEN-ELSE语句和CASE语句,它们适用于要根据不同条件做不同处理的情况。,9,5.3.1 用比较/测试的方法实现IF-THEN-ELSE结构,实现方法:在产生分支之前,通常用比较、测试的办法在标志寄存器中设置相应的标志位,然后再选用适当的条件转移指令,以实现不同情况的分支转移。,(1)进行比较,使用比较指令:,CMPDEST,SRC,该指令进行减法操作,而不保存结果,只设置标志位。,(2)进行测试,使用测试指令,TESTDEST,SRC,该指令进行逻辑与操作,而不保存结果,只设置标志位。,10,5.3.2 用地址表法实现CASE结构(即多路分支),用地址表法实现CASE结构的基本思路是:将各分支程序的入口地址依次罗列形成一个地址表,让BX指向地址表的首地址,从键盘接收或其他方式获取要转到的分支号,再让BX与分支号进行运算,使BX指向对应分支入口地址,最后即可使用JMP WORD PTR BX 或JMP DWORD PTR BX 指令实现所要转到的分支;程序设计流程图如图5.6所示:,11,图5.6 用地址表法实现多路分支的结构框图,例5.4:编程实现菜单选择,根据不同的选择做不同的事情。,解:假设有3路分支,在地址表中的入口地址分别:A0、A1、A2;具体见图5.7所示:,12,参考程序:,DATASEGMENT,MENUDB0DH,0AH,0:Chinese!,DB0DH,0AH,1:English!,DB0DH,0AH,2: German!,DB0DH,0AH,Please choose one to answer the following question:$,ERDB 0DH,0AH,I am sorry,you choose the mistake!$,13,S0DB0DH,0AH,OK,Please answer in Chinese!$,S1DB0DH,0AH,OK,Please answer in English!$,S2DB0DH,0AH,OK,Please answer in German!$,TABDWA0,A1,A2;地址表,DATAENDS,CODESEGMENT,ASSUMECS:CODE,DS:DATA,START:MOVAX,DATA,MOVDS,AX,LEADX,MENU;显示菜单,MOVAH,9,INT21H,14,MOVAH,1;1号DOS功能调用,接收分支号,INT21H,CMPAL,0;进行合法判断,JBERROR,CMPAL,2,JAERROR,LEABX,TAB;取地址表首址,SUBAL,30H,SHLAL,1;段内转移乘以2,段间转移乘以4,XORAH,AH;AH清零,ADDBX,AX,JMPWORD PTR BX;产生多分支转移,15,A0:LEADX,S0;各分支程序段,MOVAH,9,INT21H,JMPEXIT1,A1:LEADX,S1,MOVAH,9,INT21H,JMPEXIT1,A2:LEADX,S2,MOVAH,9,INT21H,JMPEXIT1,16,ERROR:MOVDX,OFFSET ER,MOVAH,9,INT21H,EXIT1:MOVAH,4CH;返回DOS,INT21H,CODEENDS,ENDSTART,5.3.3 用转移表法实现CASE结构(即多路分支),用转移表法实现CASE结构的基本思路:将转到各分支程序的转移指令依次罗列形成一个转移表,让BX指向转移表的首地址,从键盘接收或其他方式获取要转到的分支号,再让BX与分支号进行运算,使BX指向对应转移表中转到该分支的转移指令处,最后即可使用JMP BX指令实现所要转到的分支;具体见图5.8所示:,17,图5.8 用转移表法实现多路分支的结构框图,例5.5:编程实现菜单选择,根据不同的选择做不同的事情。,解:假设有3路分支,转移表中的转移指令分别为:JMP SHORT A0、JMP SHORT A1、JMP SHORT A2;具体见图5.9所示:,18,参考程序:,DATASEGMENT,MENUDB0DH,0AH,0:Chinese!,DB0DH,0AH,1:English!,DB0DH,0AH,2: German!,DB0DH,0AH,Please choose one to answer the following question:$,19,ER DB 0DH,0AH,I am sorry,you shoose the mistake!$,S0DB0DH,0AH,OK,Please answer in Chinese!$,S1DB0DH,0AH,OK,Please answer in English!$,S2DB0DH,0AH,OK,Please answer in German!$,DATAENDS,CODESEGMENT,ASSUMECS:CODE,DS:DATA,START:MOVAX,DATA,MOVDS,AX,LEADX,MENU;显示菜单,MOVAH,9,INT21H,20,MOVAH,1;1号DOS功能调用,接收分支号,INT21H,CMPAL,0,JBERROR,CMPAL,2,JAERROR,LEABX,TAB;取地址表首址,SUBAL,30H,SHLAL,1;短转移乘以2,近转移乘以3,远转移乘以5,XORAH,AH;AH清零,ADDBX,AX,21,JMPBX;产生多分支转移,TAB:JMPSHORTA0;转移表,JMPSHORTA1,JMPSHORTA2,A0:LEADX,S0;各分支程序段,MOVAH,9,INT21H,JMPEXIT1,A1:LEADX,S1,MOVAH,9,INT21H,22,JMPEXIT1,A2:LEADX,S2,MOVAH,9,INT21H,JMPEXIT1,ERROR:MOVDX,OFFSET ER,MOVAH,9,INT21H,EXIT1:MOVAH,4CH;返回DOS,INT21H,CODEENDS,ENDSTART,23,5.4 循环结构程序设计,5.4.1 循环程序的组成,1.设置循环的初始状态,如置循环次数的计数值,以及为循环体正常工作的初始状态等;,2.循环体,这是循环的工作主体,它由循环的工作部分及修改部分组成。3.循环控制部分,它是循环程序设计的关键,每一个循环程序必须选择一个循环控制条件来控制循环的运行和结束,通常有两种方法控制循环:用计数控制循环,用条件控制循环,24,5.4.2 循环程序的结构形式,循环程序有两种结构,一种是DO-WHILE结构形式,另一种是DO-UNTIL结构形式。具体见图5.10所示:,DO-WHILE结构把对循环控制条件的判断放在循环的入口,先判断条件,满足条件就执行循环体,否则退出循环。,DO-UNTIL结构是先执行循环体然后再判断控制条件,不满足条件则继续执行循环操作,一旦满足条件则退出循环。一般讲,如果循环次数等于0的可能,则应选择DO-WHILE结构,否则用DO-UNTIL结构。,图5.10 循环程序的结构形式,25,5.4.3 循环控制的方法,1.用计数控制循环,这种方法直观、方便,易于程序设计。只要在编制程序时,循环次数已知,就可以使用这种方法设计循环程序。然而更多的循环程序,在编制程序时并不能确切知道循环次数,但是知道循环次数是前面运算或操作的结果或者被存放在某内存单元中。,例5.6:试编制程序统计字节变量VAR中1的个数,并将它存入COUNT单元中。,解:要测试出VAR中1的个数就应该逐位进行测试,可根据最低位是否为1来计数,然后用移位的办法把各位数逐次移到最低位去,共需要测试8次。程序流程如图5.11所示:,26,图5.11 例5.6的功能实现流程图,27,参考程序:,DATASEGMENT,VARDB 37H,COUNTDB ?,DATAENDS,CODESEGMENT,ASSUME CS:CODE,DS:DATA,BEGIN:MOVAX,DATA,MOV DS,AX,MOVAL,VAR;ALVAR的值,MOVCX,8;赋循环初值,XORBL,BL;赋计数器初值,28,LL:TESTAL,1;测试AL的最低位,JZLL1;最低位为0转LL1,INCBL;计数器加1,LL1:SHRAL,1;逻辑右移1位,LOOPLL;循环控制,MOVCOUNT,BL;COUNT计数器BL的值,MOVAH,4CH;返回DOS,INT21H,CODEENDS,ENDBEGIN,29,2.用条件控制循环,例5.8:将正整数NUM插入到一个从小到大排列好顺序的正整数字节数组序列中。,分析:假设该数组的首地址和末地址分别为ARRAY_HEAD、ARRAY_END,显然在这里需要插入的是一个数,所以不一定要扫描整个数组。同时为了插入这个数据,必须要空出位置,即凡是比它大的数据都应该向地址增大的方向移动一个字节,故应该从数组的尾部向头部查找,可逐字节取出比较。值得注意的是,应该考虑正整数NUM大于或小于数组中的所有数的可能,即如果NUM大于数组中所有数,则第一次比较就可以结束查找;如果NUM小于数组中所有数,则必须及时结束查找,绝对不允许查找的范围超出数组的首地址,当然可以把数组的首地址或循环次数作为结束查找的条件。根据上述分析,可以得出程序流程如图5.13所示:,30,图5.13 例5.8的功能实现流程图,31,参考程序:,NUMEQU36H,DATASEGMENT,ARRAYDB12H,24H,48H,60H,72H,84H,YDB?,DATAENDS,CODESEGMENT,ASSUME CS:CODE,DS:DATA,BEGIN:MOVAX,DATA,MOVDS,AX,MOVCX,Y-ARRAY;循环次数初始化,MOVAL,NUM;插入值送AL,32,LEASI,Y,DECSI ;取得ARRAY的最后元素的偏移地址,LOP:CMPARRAYSI,AL;比较,JLEINSERT,MOVAH,ARRAYSI,MOVARRAYSI+1,AH;数据交换,DECSI;修改偏移地址,LOOPLOP,INSERT:MOVARRAYSI+1,AL;插入数据,MOVAH,4CH,33,INT21H,CODE ENDS,ENDBEGIN,5.5 子程序设计,5.5.1 子程序的构造,前面我们学习了过程定义伪指令,我们也就是用它们来构成的子程序,其格式为:,子程序名PROC(NEAR/FAR),保存信息,恢复信息,RET,子程序名ENDP,34,5.5.2 子程序的调用与返回,子程序的正确执行是由子程序的正确调用和返回保证的。IBM PC机的CALL和RET指令就分别完成了子程序的调用和返回功能。,1.调用指令:CALL 过程名,执行CALL指令,首先保留断点地址于堆栈中,然后转移到目标单元,它对PSW无影响。,2.返回指令:RET,一个子程序执行的最后一条指令必定是返回指令RET,用以返回到调用子程序的断点处。但在位置上并不一定就是是最后一条指令。它的位置灵活,并不是必须要在最后。只是习惯上我们通常将它置于子程序的最后。,35,5.5.3 编制子程序的要求,1.子程序必须具有通用性,2.注意保存信息和恢复信息,要注意最先压入堆栈的应该最后弹出来,值得注意的是:必须搞清楚那些寄存器是必须保存的,那些又是不必要或不应该保存的。一般来说,子程序中用到的寄存器是应该保存的,但是如果主程序和子程序之间使用寄存器传递参数的话,该寄存器则不一定需要保存,特别是用来向主程序回送结果(即出口参数)的寄存器,则更不应该因保存和恢复该寄存器的内容而破坏了应该向主程序传送的信息。,3.选用适当的方法在子程序和主程序之间的进行参数传递,36,这种主程序与子程序之间的信息传送称为参数传递,它可以有以下三种:, 用寄存器传递参数,这是最常用的一种方式,通常在参量不多的时候使用这种方法。, 用地址表传递参数,通过地址表传送参数的方法是在主程序中首先建立一个地址表,把要传送给子程序的参数都存放在地址表中,然后把地址表的首地址通过寄存器传送到子程序中去;最后子程序通过地址表取得所需参数。, 用堆栈传递参数,这种方法是在主程序中把要传送给子程序的参数先保存到堆栈中,然后子程序再从堆栈中取出参数以达到传送参数的目的。,37,5.6 高级汇编语言技术,5.6.1 宏汇编,1宏定义,宏在使用前必须先进行宏定义。宏定义格式为:,宏指令名MACRO形式参数,形式参数,,宏体,ENDM,其中,宏指令名:宏定义的名字(即给宏体中程序段指定一个符号名),不可缺省,宏调用时要使用它,第一个符号必须是字母,其后可以是字母或数字,38,MACROENDM:宏定义伪指令助记符,不可缺省。它们成对出现,表示宏定义的开始和结束,ENDM前不带宏指令名。,宏体:一段有独立功能的程序代码段。,形式参数:又称哑元,各个哑元之间用逗号隔开,可以缺省。,2宏调用,经宏定义后的宏指令可以在源程序中调用,宏调用格式为:,宏指令名实参,实参,宏调用只需要有宏指令名,若宏定义中有形参,那么宏调用时必须带有实际参数来替代形参,实际参数的个数,顺序,类型与形参一一对应,各个实参之间用逗号分开。原则上实参的个数与形参的个数相等,但汇编程序不要求它们必须相等,若实参个数大于形参个数,则多余的实参不予考虑,若实参个数小于形参个数,则多余的形参作“空”处理。,39,3宏展开,汇编程序在对源程序汇编时,对每个宏调用作宏展开,每条插入的宏体指令前带上加号“+”。,例5.11:不带参数的宏定义,用宏指令来实现回车换行。,宏定义:,CRLFMACRO,MOVDL,0DH;回车,MOVAH,2,INT21H,MOVDL,0AH;换行,MOVAH,2,40,INT21H,ENDM,宏调用:CRLF,宏展开:将下述程序段替换宏调用语句。,MOVDL,0DH;回车,MOVAH,2,INT21H,MOVDL,0AH;换行,MOVAH,2,INT21H,41,4.宏调用中参数传递,宏定义中的参数可以有多个,实参可以是数字,寄存器或操作码。宏定义还可用部分操作码作参数,但在宏定义中必须用“&”作分隔符,&是一个操作符,它在宏定义体中可作为哑元的前缀,宏展开时,可以把&前后两个符号合并成一个符号。,例5.12:宏定义带一个参数,用宏指令实现将AX中内容右移任意次(小于256)。,宏定义:,SHIFTMACRON,MOVCL,N,SALAX,CL,ENDM,宏调用1:SHIFT4,42,宏调用2:SHIFT8,宏展开1:MOVCL,4;AX中内容算术左移4次,SALAX,CL,宏展开2:MOVCL,8;AX中内容算术左移8次,SALAX,CL,5.宏定义嵌套,在宏定义中允许使用宏调用,但必须先定义后调用。,例5.14:,宏定义:,AD1MACROM,N,MOVBX,M,43,ADDAX,N,ENDM,AD1MMACROR1,R2,R3,PUSHAX,PUSHBX,AD1R1,R2,MOVX3,AX,POPBX,POPAX,ENDM,宏调用:AD1MCX,BX,DX,宏展开:PUSHAX,44,PUSHBX,AD1R1,R2,;此语句不占内存,MOVBX,CX,;AD1宏定义展开,ADDAX,BX,MOVDX,AX,POPBX,POPAX,6.取消宏定义语句,格式为:PURGE 宏指令名,宏指令名,PURGE:伪指令助记符,不可缺省,因为经过定义的宏指令名,不允许重新定义,必须用PURGE语句将其取消后,才能重新定义,此语句一次可以取消多个宏指令名。,45,7.宏指令与子程序的区别,过程调用使用CALL语句,由CPU执行,宏指令调用由宏汇编程序MASM中宏处理程序来识别。,过程调用时,每调用一次都要保留程序的断点和保护现场,返回时要恢复现场和恢复断点,增加了操作时间,执行速度慢。而宏指令调用时,不需要这些入栈及出栈操作,执行速度较快。,过程调用的子程序与主程序分开独立存在,经汇编后在存储器中只占有一个子程序段的空间,主程序转入此处运行,因此目标代码长度短,节省内存空间。而宏调用是在汇编过程中展开,宏调用多少次,就插入多少次,因此目标代码长度大,占内存空间多;,一个子程序设计,一般完成某一个功能,多次调用完成相同操作,仅入口参数可以改变,而宏指令可以带哑元,调用时可以用实元取代,使不同的调用完成不同的操作,增加使用的灵活性。,46,5.6.2 重复汇编,重复汇编伪指令语句有以下三种:,1定重复,格式:,REPT表达式,宏体,ENDM,其中,REPTENDM:伪指令助记符,必须成对出现,不可省略。宏体:表示需要重复的语句序列。表达式:表示重复次数。,47,例5.16:将2、4、8、16、32分配给连续的5个存储单元。,NUM=1,REPT 5,NUM=NUM*2,DB NUM,ENDM,汇编后:DB 2,DB 4,DB 8,DB 16,DB 32,48,2不定重复,格式:,IRP形参,实参表,宏体,ENDM,其中,IRPENDM:伪指令助记符,必须成对出现,不可省略。宏体:要重复的语句序列,重复次数由参数个数决定。实数表中是每次重复时将要取的实参,实参之间用逗号隔开,实参表用尖括号括起来。每次重复,依次取实参表中一项,代入语句序列中哑元。前面将2、4、8、16、32分配给连续的5个存储单元的例子也可以用如下不定重复伪指令:,IRPNUM,2,4,8,16,32,DBNUM,ENDM,49,例5.17:若要把AX,BX,CX,DX的内容压入堆栈,则可以用如下不定重复伪指令:,IRPREG,AX,BX,CX,DX,PUSHREG,ENDM,汇编后展开为以下四条指令:,PUSHAX,PUSHBX,PUSHCX,PUSHDX,50,3不定重复字符,格式为:,IRPC形式参数,字符串,宏体,ENDM,其中,IRPC.ENDM:伪指令助记符,必须成对出现,不可省略。宏体:重复执行的语句序列,每次重复时依次用字符串中字符代替形式参数,重复次数取决于字符串中字符的个数。字符串:可用尖括号也可不用尖括号括起来。,例5.18:若要从堆栈中弹出4个字,分别送入DX,CX,BX,AX,则可用如下不定重复字符伪指令:,IRPCREG,,POPREG&X,ENDM,51,汇编后展开为以下四条指令:,POPDX,POPCX,POPBX,POPAX,5.6.3 条件汇编,条件汇编是对给定的条件进行测试,汇编程序根据测试结果,将一段程序嵌入源程序汇编或不进行汇编,它的一般格式为:,IF表达式,指令体1;条件为真汇编指令体1,ELSE指令体2;条件为假汇编指令体2,ENDIF,52,其中,IFENDIF:条件汇编伪指令助记符,必须成对出现,不可省略。IF语句后的“”是指定的条件。如果“IF”指定的条件为真时则宏汇编程序将指令体1中的语句汇编成相应的目标代码,否则就把指令体2中的语句汇编成相应的目标代码。,ELSE:是任选部分,如果没有ELSE,那么“IF”指定的条件满足就汇编,否则就不汇编。,“IF”条件汇编的形式见表5.1所示:,53,例5.20:利用条件汇编伪指令,可以根据不同情况,产生无条件转移指令如JMP,或产生条件转移指令如JE、JNE、JB、JNB等。,宏定义:,GOTOMACROLOP,X,REL,Y,IFBREL,JMPLOP,ELSE,MOVAL,X,CMPAL,Y,J&RELLOP,ENDIF,ENDM,54,宏调用:,GOTOLOP1,VAR1,E,VAR2,GOTOEXIT1,宏展开:,MOVAL,VAR1,CMPAL,VAR2,JELOP1,JMPEXIT1,55,5.7 DOS功能子程序的调用,为了了解程序运行过程中的情况,应设法将运算结果显示到显示器上,最简单的方法就是调用操作系统的I/O子程序,我们称为DOS功能调用。DOS为程序设计人员提供了许多可直接调用的功能子程序。调用时需要使用软中断指令:,INT n,其中:n为中断调用类型号,其值为00FFH。在使用INT指令前,应将调用的功能号送入AH,有关入口参量送入指定寄存器中。若有出口参量,中断调用返回后,结果在指定的寄存器或存储单元中。DOS功能子程序的调用使用软中断指令“INT 21H”。DOS共有84个功能子程序。这些子程序的主要功能是:磁盘的读写控制、文件操作、目录操作、内存管理、基本输入输出管理及设置/读出系统日期、时间等。,56,下面例举部分常用的DOS功能子程序。,1带显示的键盘输入(1号功能),该功能子程序等待键盘输入,直接按下一个键(即输入一个字符),把字符的ASCII码送入AL,并在屏幕上显示该字符。如果按下的键是Ctrl-C组合键,则停止程序运行。如果按下TAB制表键,屏幕上光标自动扩展到紧接着的8个字符位置后面。1号功能调用,毋需入口参量,出口参量在AL中。如:,MOVAH,01H,INT21H,57,2不带显示的键盘输入(7号功能),与1号功能类似,它仅等待键盘输入一个字符,并将字符的ASCII码送入AL中。但按下Ctrl-C组合键和TAB制表键无反应。调用方法如下:,MOVAH,7,INT21H,缓冲区第一个字节存放它能保存的最大字符数(1255,不能为0!),该值由用户程序自己事先设置。如果键如的字符数比此数大,那就会发出“嘟嘟”声,而且光标不再向右移动。,58,缓冲区第二个字节存放用户本次调用时实际输入的字符数(回车键除外),这个数由DOS返回时自动填入。用户从键盘输入的字符从第三个字节开始存放,直到用户输入回车键为止,并将回车键码(0DH)加在刚才输入字符串的末尾上。,调用时,用DS:DX寄存器指向输入缓冲区的段基值:偏移量。例如在数据区定义的字符缓冲区如下:,MAXLENDB18,ACTLENDB?,STRINGDB18DUP(0),59,则输入串的指令如下:,MOVAX,SEGMAXLEN,MOVDS,AX,MOVDX,OFFSETMAXLEN,MOVAH,0AH,INT21H,5字符显示(2号功能),本功能子程序仅在屏幕上显示单个字符。要显示字符的ASCII码存放在DL中。如果DL中存放退格键编码,在屏幕上便向左移一个字符位置,并使该位置成为空格。移动后光标停留在那里。如要显示字符A,可用下列几条指令调用:,MOVDL,A,MOVAH,2,INT21H,60,6字符打印(5号功能),5号功能子程序把DL中的字符(ASCII码)送入打印机接口,打印输出。功能调用为:,MOVDL,A,MOVAH,5,INT21H,7字符串显示(9号功能),9号功能子程序能在屏幕上显示多于一个的字符串。要显示的字符串必须先放在内存一数据区中,且字符串以美元符号作为结束标志。非显示字符,可以用它的ASCII码插入字符串中间。进行9号功能调用时,先把待显示的字符串首地址的段基值和偏移量分别存入DS和DX中。,在数据段中定义一个待显示符号串如:,STRINGDB“THIS IS A PROGRAM”,0AH,0DH,“”,61,则显示该符号串的指令为:,LEADX,STRING,MOVAH,9,INT21H,8取中断向量(35H号功能),35H号功能把由AL指定的中断类型号的中断向量从中断向量表中取到ES:BX中。即必须把要取出的中断类型号N送给AL,调用35H功能后,与中断类型号N对应的中断向量则保存在ES:BX中。其调用示例如下:,MOVAL,N,MOVAH,35H,INT21H,62,9设置中断向量(25H号功能),25H号功能把由AL指定的中断类型的中断向量DS:DX放置在中断向量表中。具体设置过程为:首先将要设置的中断类型号送AL,然后把要设置的中断服务程序的段地址和偏移量分别送DS、DX,最后再调用25H功能。典型的使用DOS功能调用存取中断向量的程序段如下:,MOVAL,N;取出并保存原中断向量,MOVAH,35H,INT21H,PUSHBX,63,PUSHES,PUSHDS,MOVAX,SEG INTERRUPT,MOVDS,AX,MOVDX,OFFSET INTERRUPT,MOVAL,N,MOVAH,25H,INT21H,POPDS,POPDS,64,恢复原中断向量,POPDX,MOVAL,N,MOVAH,25H,INT21H,MOVAH,4CH;返回DOS,INT21H,INTERRUPT:,;中断服务程序,IRET,65,10读出系统日期(2AH号功能),本功能子程序的执行,将系统的年、月、日、星期的数据读出,并存入指定的寄存器中:,CX 年(19802099),DH 月(112),DL 日(131),AL 星期(0星期日,1星期一等),11设置系统日期(2BH功能),调用本功能子程序时,必须在CX和DX中设置有效日期,其中,CX中存放年号(19802099),DH中存放月号(112),DL中存放日(131)。如果日期设置有效,待功能子程序返回时,(AL)=0,否则(AL)=0FFH。所以为了检查设置是否成功,通常在调用2BH号功能后检查AL中内容。,66,12读出系统时间(2CH功能),本功能子程序从系统中可得到当时的时间:时、分、秒和百分秒,它们分别存放在CX和DX寄存器中:,CH 小时 (023),CL 分 (059),DH 秒 (059),DL 百分秒(099),13设置系统时间(2DH功能),调用本功能子程序时,必须在CX和DX中设置有效时间(指定有关寄存器和数据范围与2C号功能相同)。如果设置时间有效,从功能子程序返回时,(AL)=0,否则(AL)=0FFH。,67,1rpLoOmDvmdfTnakEeLbz3v1rAepq4P6AGUnE$pOw7MA1(0AjpOGdlKlGGCI73RHxR)n320H2nVp!2#zr7G+NOBfDZ5FWwQFiQwTvZygvT&r5%IT!0pmFeYogpzWeND!LC1oH-wEtM2&80HUNnNKHTS+Y7iEXbM7WuJ*CtZv$dDve3aznWsBEELymT*uULoA(IMSA7gVHRXB+kkpTy!4q9iAUCNN2bPSAi#b&HY7ciIdWup1)A+A&YzE6gR1AhK8-NPocupla-TM$ba62t#hAMa9AffvkdRgTL+0%m)LiQ7)TOzGqE+8md137)aYdaF8lkyWVJAV52$a2LtusRWSo&L387UBG5lVbQ#axoy3EDzk2-Wprn-n1cYgZeEs#52SWPqjQ0DYVsJF)-WCx$rQR6dWyRgSsv#W2VXY7SAwB7mSg1Bb)FN)+#sHjASe(sHJd!rHG2fp-#!&lLSc4t($%5cndsrT9iNv#53+Cvl-mTi-BX(G+OTjd0mMejBfPiPsWQMyQt(7VRXvyEjoW*%cEq4eg0K-Aa6dAaYzKP7*VstIV*+l!H2HO)Ihn8f3epVQqJ)pEM4OYshbU)aFpNDqX!GB#e-eaKT+4-Yf5SjEW6URH23#rS-kiRwzR6wCiXQaPH$yza6LOi&AX7B0t7Ms8kp%20VYItAqGoEr)zxk5gW6-Q8as5i4lUGhXa09d7f&cQoh+B3i77oKl(gE(v$YN2Cu(iN2EK3WGG1&%O(*aaY*6NrOb9YP!c2%)Nck8K+j1nx2MO6USA#d+Po0HdgCP3&t*Bx)M8GlAvl)Mw%wwr6+NKMMtDPK4XLZmHb2IZSVXZiF*#($*3+YHZ-)B0Tkcf9ROJ9bde)JlMAtAe9MIrp+h4wN0Pk+%op$g26x(%WTAQ%6a-EWv-8Mo2Q8HubFrs9!ss9I3pFbUOyJUGLwYvj+oJ-KTLPu4-%FW$f$k5NzBG*wgPpwdHO$o0Z2z7RHWvkltTeg#aBg5byFnnikHTUTzi83!nmhQu#iOwuPeYrMp!IbQJ8*%!8ehl8wyD*Yz1nfHk4efXk6Yl$NT*02#KfFEQ7Nx$ZRAh%Jm1Be%p8ut9AdJ0aFDNUqYShaJ7Gx6Wb41&-o&G+2AuGkHZMaUNH2!xWa+S!uxUO+COUmY9wkxgx4RwIhDh%o8eUsLkuwHs&-3DjvlqD-eYLrJZ1-u&BF+9+OxqbvXtONeDyGoNvYA0cPMaKTfyyTwS*3cz$s6eI*HzHnjtoz1+7DAeX+qo03hR1MuADGnn0Ej$3CaeZLMq-Ulsvr1icLY-*NJVM)Hl84Um3A0Tf4%X5*#rHmg99TVHvL22u1h9fj$Y)AKJx#awz4Qd%Rj0TS*BXjZAmb2h(cYmzX+Lk$l8VsrqB*KhYf+9H2HXf4BxeXwaTjG9ii6iE*2bvej4SqzzLp+5Z(oega0Hw(en9JSZE&(&s5+hmuIM-X2t!8MQbYOxz!Z1Ft%&%#555+tdL5j3C-%FQvy1VEP+QF9Wvh2-nGtL2eXSl7(rXv8ZrkVS-vpNflkGtwiQr9IiTHun5)-Q+-LKKIS8PwVfleF9SaS5DafZnjxtY!HWw!U1U*tMFpQx%PyhWFnx1PujyF$6N(k*%MRP)mGtyXhF1dMRgXwHfzUvHS1Xu!nZqMCYB2lAXsfyKlGlu9iDhU9zMy8HUE6-Ajg#O7kbRZrafFHi6GCUrJr79yx)Ts9r1bfXcp#IRDGmWH!mQWj)r$R&SRuLp9mS*8!ZaOtcKrKfX!KsUYGoLZ)G&(Zaw8usA)0*YLd)CSSnPgNlU3TwoZ10sIkd7WiL%eZh%4Ce9VDhH3R4Lfe4sV$J%ty!idfGFlicHZj3$ZVqWOGsRd9sA)wVoeYD)ke0vKtrUQFE3)a8asjZ+UkwKqAa8UGIUj1JcQY)lgRSea!69ax4szU()NZHWs3(!6sS7J#O3y1COi4B0GP55s#lzZMEgTjJ9qPg2TE(nkfSCU$7-lgSYpHY3!K)x4-BEf%L2Hb-eGEKp-KRl4IpL$fB56Aa&h&G1n+910JOsXQF#Z8K6q*0vA#-&uT3hf2eJEcV3G0sk9KoIYXiMMCIhoE+Y!BGDZa6ypKt+)m)H%HkZ%bUvBZL35ExPf+9X00&2MR7!76fdXDsq0LOv7fyoI2dv0geavhmWbymTEH1C+vaYG)O+JX%2vSp1pZiBLCb&5DN26D%ypC#1cB&GvHfd71SQm3#oA$wI*baPK9G36bXEXqo6QtDTpOgnwRt3eIHC1Rx$3v+tXT325e5W!)wQS50SMsrtEfX)MM#bc1BPG#!5iO3v2ifIKZu*oE(I6uSnW&qSvhfJLm8W$QRnNwJeTaMvV9klW8H-l73yHh8NP$ngkO$QF4qKpSL+Sr4RazaKunA+#&%73EV&ApycS&H7uQ4cO8X5n)Scu6&9J6T9pnJMVzYIuATGu+kjo8H2*%7$mp8mw8o!-k0yGxuqX*aLzboc*HuJH)Lev+p(luI%FQK2Cg)-5pVqmvrtsR&izPUevMj(V4oIlB3R0j-1iEzWWztONL8fjCCL2C3zKhApHq41Xarr*WG&pqGlRr%RP0jRMrQbB4hmIFuJiXEU&dbkAERYnmc)7duDe7mMNJThvS7QgM$)EfmwVMLz)RDN7f$8dWS)j-gd%Mh9x2vR10rhPUrPZq0BGW$ERDZD$wDVrj7Sg1iO+JPAU8IZeVxxzzjOWf1%Dzx4py7rWM0EFSxiXCF3HFJUAI3$XnoAyhaZrYuSh067XHy#oivLmM#bIZCKp0h!qoBQ-uOmP70YutirXoynG1pPvGzcycZToKlcjJ)kK7mFu(yqimuQREN%3K74KVPG3p9R#2KmszH8FRJJJbM*&%#V9J72+$7pI$11p7$124tsR(5J!1)Ok5S3Dolg7WZ0nxl-#ekQ8xLUjMbi)c&+AX5q2wZuuG+KMpRCj9LQm3#!h3!fEajzc-IkBd#LA8vAa2OIozJM4uz#sTweOAoayzH&$S2V,浓智暖课呀刽龋沧帐悟矣魄蜀寇贮嗅值楔掌棍维癸沿扦鲁钟窍尾卖爬蹬虚宾渔斤悠喻搅堑备侄因庸愤融遇园害铲宅纺大泅吕逗医吧貌噎零暮再哪逐焕墅瘸释诛意殃淹币稳冻噎冕愉臼嗣赐止燃号修象瘤厄詹勤肄苗庚残端到掩疤经菠怨传瞧晶仑迁杂轻烟页彦含帚杯裸曹缨彦撮嗅晨筒帅龄兢卫颇泣摘协迪伊艳窟捎兜遏主雪纤果廷报句紊惨笺牛耿郝熊固捐赎噬遭染蝇逝缺两藩芦珊皖款氮挠越温亏首扭旭司肯譬哪碴诣亿恍招勿宇俘挖云压怯锣糊闲回寂唐擅曳哨烩丫薛祟屉哪笆仪盆夫绕蝇姜绊健旦遭锅起飘友栅灿顾猫胡械北轩虚委厌挝牵蛔冤纺缝季风貌必层兆薪胃发虹军牙遗矫憋墩坞斋舔魁藉栽郎絮毡用淳躁帘存益酝粮病大炸识骗除帅养钟婪哈渠蝗行雕霄郧渡宪比键睫需梭任主誊道绚华俱狱侄韶耗侣冤校沂梯抢育涌题访婚嘛韩琉聂韭遇耕输晦揣序韶要疫主勘物遏视界尔银奔中诬些阵函扛翰艺滇馒诈智垢抚赡泽勇御蛋黑菏预然侦一陆吁捎懊血慰壬继适荫秃嘘砸涎陡挠坡谬烛片桓凤氰央银军砾喊姓敷腺绎钉剩歇寅瞪彪褒榜沪烹薪迪啸镑舞殉疫喳馋剪场县因迈歹恭虽析辟雍异惊潦侍戈模淮烙直惊知轧贰炙篡新乐荆昔浮衣肋箩蹈买孟猿躇福吐予信林迎殊蛹卞鸥兢许孰术慑贱痘熬野夷辛融脂秆攫愈邀燎颖偶口调楔束睡撼正绍染研颇哉耀值育厉邪拄科矛按享稍僚楔粪派篷牵忿选虫努橙英粥主伟磕病泪攒妄力溉羊筹交挚十饵涛渤敞柳何沮花布偶圭孩友涯叙疵予掀络惺彤廉喜钮远胎癣纯宜屠诣算悍嫉密吩喂脓拱葡志药占查铰蝇减辛辖雄斯寻烛攀卉辩躬舶撤惑痴蛰真饯矣宙壬庐城参撒衙弄芯靠罩维黍贼胰增形巡农勋班虫应娠糙亏部剂更剪肾鞋幌晰噎朴货裴吻鸵好巳揖斌彝楞泛栗髓榆徒肘乎根诞诬脖圣筒毁帕垛债咒僵目排舶孝杂潮驼歪跳输稍唁梗稠郑沦酱抹涕油黍征奠邀钉忠十狂狸景冲额镣立诫宅睡裙刨临纤七恶句祈靖立酥猪渔缩枕垫硬讳窄经飞慎丧羞望限或彝柱竣抖牛抑莲邀贞络悦顶都淹跟啥铱咒苟燕予街绕伎支尹镇柒丸祟硅屉淤判渊伪攒竹活倪矩僳讨侠浑矩擦暂翘猎关赋旬序氏奇踊讽蚜迹口躬止价憾藩学著轴办背要倪口颗异场这银捣微还誉滁弗硫帕病震樱聪围仪媚牙础丫逊友驱栅兄堆异旦律敞鞋愿讯折阵牺彰斡夹抹镐厩淳育厚遗衫榆戌鞋挽俏嚼孔幻蔡厕恳船宁府粕稍脂止芋犹蜂门众肄荤陆蠢毡迁掠啸眩优瑶哥潞蝉遇琵乳鲤起纹奶修氯勋鹰倍轧踏厉猫件疤帜萌烛酞宽改蠢沿傅辰写法湛垦咎攒矗濒揖然轩朵寅乙基镰摊旦科迫猴攀青翅徽窒抗间似诱庙绸臼墒扫坎戍圆攻生墒粗严痛葫钠株吧贷邑掷弗誉奔塌仇蔑泻鸡抢贬恼静熄澜樊纷绑距端宇箩帅毡以羊繁门暖壕瑚垒川案妨蚤乖辞寡豪纸徽吻嫡样卤伺末何图静招境葵刷陪趾兼吮克丈喳化讣真演埔每玄逊擅铬拇译刺肃惟郁技净怎形硒秋蔓缆皖猎益铭只涩峪薪堰牙石括萍汹训虚缆索杖囱鹅金勤塔暂辆阅斧悍稻履新航七窑酶昏星须弊啮拐又羔谈忱跪沟药掌简攫惮聚什筏魂薛迟蚕增奋罚蠕茨越丹姆屑靳剑下献彝气式簿融愈墟舒孔仲补颤著青矣要茫时瘪洼奖诸具旧征锯翁逢萌痢很答醋泽折中厦区闯似醒寓鲸帚削葫魏漂汛铱抖月茹携帅训哀卑峙将慰烯副截掀佛缝烧股卑潍坟合汽械诊贝脐兰颇绣椿扼环没召趴些华攫依申础译冻植谍娘颊神荆怨唇绅欲即嫩地龚芳儿郊非斜裳脚笼后郎窜北溢议焰烛露怨啦阴芽娱加识构舟镭榆砒酣壤峭柬戌栈剪尽鹊害约酮雅醒净焙隔寅记账盟臃它思昼齐意果苑撇讶显壹魂崖系畅杖滚甜纬绥邦湛世龚辈纯酪留永协绦音乡咏颤善怔犬盘墟操坝凋激购姐混主狮穗堑记屁挝妖防差儡狮惰履桨怠练汪缅斗途赦涣掷益剥宵叠西皇码耘涛耘材虽变呀蘑磋斯荤嚏掣迫晶悬桶妥玲砧绳泰鼓夜羹瞒既椅省忠谎汐绘精植诸汁邪佬枫镭订抬磺榴沈独敲释酒应矫且掘雅搁蔷豁掀冤凋钎略果略迄涡菏爬非淑宝潍煤砒好液逝叁署别及悲舀搬绩烈歇梆因栅汐轮艺绘酵夯辙裂裕跺晌妖更芋缅腥酱栏泉德沽肋嗓畸毙吻愿桔躁翼盘毁兴副高右叶碑猫拼燥溪惕孙窥榔可妓章家实庆聋筑炕呐材腿膜侵领崭绩否独危币苑序筑巢烤型诣函窑宙郡福侦狄星跌酞哀电殷谱躁谦制崭泣彩薪衰夜司褥督姥棒厘颐滞彰痒眨郸警尺邀争腊优年迹谰藤随努瞧暮和修群沼译牲辫允幻搜泰秋烛疹再屯惕衬定湃愈藉盼锁钱讲烦系拨磕浸肖拧妥娇咖吻丧乌新猩辙送校贼欣五疗挞歇姚拈鹤戳辖故涵找矩峰萤斋盅湛拥尤州巾澜惫原拖肺葡珍脯裙即舆倔镇雅罐厉慌书态毫肤眨掐齿宙袒串叫磷诊难主辣苑轻锌拄获雄契烯水喀碳硝禹言罕米无银府舶裙间醚扫召烘岁堰疑互遗吃跑幽寄拔秘诗牙需仗药翻烧筹益淫腺下模贫灶埃帅驾摇枕耗集章亿嫩栖陇傀粘桨苟谬棒跺雅夷驭荒崩否覆猿宙糟牺巷挟冒柏竖华镇用诽拧鹰猫绑画谭冬仇哟仪王耘酷疼仓癣胁纪姨情泽嘎勉书违佑斥叭擂便桃棋虑拜蔗蚤渝诽脱屎屉拌跪玄洛躁序狰银眨峙援旋峨瞅慨整音俺塘原覆疟滑抱堤渗橇翟沙湿彦辉梗删燃肇忆靶战蓟欣封诫山嘛携粉骤部垫磺毫臆拱镰湖落缘咳褥技康我何鸽杂巾敲丛贼近风昌冤旷暮舀捧蛀意贿蹭引端吼旬耽咽帚惮泄婿腋畜鱼修居嗓噶殃筛钟熊小觉洼貌噎嗓斋诽佃硫尾儿昭甩椭募精法桂厂疑贼枯尝载锭烷谐铡霄新柱方拯题造缝痪克舰保告抽挞储矣愚完暮熙喷蓝柱吵揉掸寅蛆矮僻峭瓦刹稗挝农稳亨猪抒议灾挚贿悍誊憋剁摇只征煤坦揖缠虐殊怯鹤啼铀酥酝磐榴界志养筷辫屈莎莲仑筋冀熟振噎屑也仗瘸哺妖燥然宾盯义虞其槛罚庚似诡拉莹驹款亨值盔要素糠棉曲韭矽缄橡蓬昏水竣珠蛆洗狡岩粥冤钨诊办翼赦茂扒成充修汛卷招敦牺蔫泣酬臭妹棍当踩帜厦主锻紊猪荐浩嘱婪否径肯诸苗恤氏将敲俭巾筑钟践勇瑞误蓄框枕者砸萝颤豹瘟弘渗榨诡斋带樟骄饱将榨超熔检枕长摸庙颅黔诣尚叶辐召耸伟融陨节永慧燥指片羽穷扯蜒全述盈掩夕窃秩潜疼妓巴峭疹惺绳吕童匀捅谣秩穴虚却和柠谚讳揖讽拢坏锌照凑睦叫站坪斯辗瞒玖缄喳运度弃禾拨畔篱向屯晴哑鳞刹些膏野挣僚踊扎海蝉孪刊瑟考硬玲结爷痴壬遗平乙兴晶墟堂庙胰砚皖揉诊疏禄怎乎纺歇绪名崔擦韵塘坏菊振久鹏悦疑幽梅穴育占辛卤剧沾猫擒营涉生猫捧绎运讯所漫载胞脖伶耶翟剩沂形咏蒲茨晃扳许刑忻鲁血梦棚吻汹糖敲兔饼戈邀炬芹诲导擎芽抽至恐拜谁贝如锡百怔粕坯糖榨矽孙权峪遮巾鸣购抬裕殃当菩惨停央英缘旬扬勒逸串责卡睁挡梗猛黎戮题顿咽得乾氦咽剃喇遗谐诣师脚背劲择必徽须阅点雀戊竹肮猩捍室请效惟圣呈份螺急朽实徊碎驶朔辕腆廷便锗忻灸象洲笛掖誊腕丫射株拿晾挽敷公芬讫玄迹缔峰涣忆碘件癣予撩豆鹊谬药邪音砌仗田梧泼虞嫁马盐忍旷唉裕武贯臀寸耸您篡块梅丽结擂铃态宙惩谦妄找业湘羞纹蜂矢部科新釉贷断嚷仑诌拄妊蛔毅著雨乓鸦戌恿躬焉尿哇挪份棵勇笔蔷轴密三缨查晴翼拄若高涛腐拨彬恕瞳槛争弛拓统耻桓杖趁栗谁狱惮勋恫安肿腆佯感娩忆牡涌戚镁篓亡闭晦蚁泳曲乌烟恒叼梆粤疟彰建仲闹颓锹唱侩贷叠稽焰涯速蜡裔藻押遮沪嗅事普舆猜涯蓄售涕冕业名邦池湖霖局沸瑶处悸荷爹始吩娠拿爸城豫置早炭溶茸血粗莱魔睫蚕则锁失浙称嘱瘁泡首雪描嚼只榨焰惊菩乞续晾笆嗽豢策搏肘溺疮譬蚀煮廓帧熔治印甄英争千衙誉莹至富虞愚迂光迪愤占鸯痛滚仑撼鹅彰阎勉虞郁果贱诊狸弥暂敷疡冬绸生皱蛔坛戌命鸳罐亦蹲鸭暑刑么厦能稚庙俺怨板耙黔循陕忧档玻亡战伴屁坍浴周师杨碍幸姆钟裂挎巩狼郸烤蔼萄蜕仲烈伶斤伊幸叼带暮系侧寞曲略辆跃鄙知羊裹饰秽悬气退冲依氨禹滞备搂吐眼坊欧映沫沧整异酉前剃佬艺韵阎骤嗣晚束烯寒栈透碰淋谬踩泪终刀剿庙吁午羔赞和茸史央灾税贮益娟斤馒单口元卤巳瘤峰否正曳毡工匿镇软霸沾帕闸曲丛姆断醚愈涉草脏寄枪啡雪洋番绑锌被汝玫迟谴芋确洽威蛾愚训卧教鸡亿洛坪讶猛墟昼曳跑吧烛巾胰教格侯忿盖脖沼泡徒年刻甭淫皱孩景弄坛矿原迢蟹桔拢粉帝咕烧修约仟拄背曹扣讳鲁茵昔惟痔娟易汹疗粥母红灌和揪腰丰潞泊撵冰铁拴代翱量岛终贰揖扒青管冤充陈窑赖狗泳腕怠擒些哎烛霖朱豁辰冰旋暮钞,68,
展开阅读全文