第5章汇编语言程序设计一.EXE文件编程格式允许源程序使用多个逻辑段,适合编写大型程序,最终能生成.EXE文件例:将N1和N2两个单字节数以28为模求和→SUM单元5.1汇编源程序的编程格式.486DATASEGMENTUSE16N1DBxxN2DBxxSUMDB?DATAENDSSTACK_SEGMENTSTACK‘STACK’USE16DB128DUP(?)STACK_ENDSBEG:MOVAX,DATAMOVDS,AXMOVAX,STACK_MOVSS,AXMOVSP,128MOVAL,N1ADDAL,N2MOVSUM,ALMOVAH,4CHINT21HCODEENDSENDBEG可省CODESEGMENTUSE16ASSUMECS:CODE,DS:DATA,SS:STACK_说明:.EXE文件中堆栈段的设置本例以“STACK_”为段名的逻辑段,选用了“STACK”链接参数,DOS自动认为“STACK_”段为堆栈段。所以,DOS将自动给SS:SP赋初值因此,源程序给SS:SP赋初值的三条语句是多余的。链接程序要求:.EXE文件中的源程序必须有堆栈段,否则链接时将给出警告信息Warningnostacksegment但这不代表源程序有错,仅仅是警告而已如果源程序中不设置堆栈段(在链接时,会给出错误信息),DOS将自动给程序分配最少128字节的堆栈区,故源程序中,如果没有大量数据压栈的话,可以不设置堆栈段,从而简化程序。二.COM文件的编程格式1.汇编语言规定:COM文件的源程序只能有一个段:代码段,不允许有堆栈段在代码段偏移地址=100H处,必须是程序的启动指令程序中使用的数据可以放在代码段的开始或结尾.486.486CODESEGMENTUSE16CODESEGMENTUSE16ASSUMECS:CODEASSUMECS:CODEORG100HORG100HBEG:JMPSTARTBEG:MOVAL,N1N1DBXXADDAL,N2N2DBXXMOVSUM,ALSUMDB?MOVAH,4CHSTART:MOVAL,N1INT21HADDAL,N2N1DBXXMOVSUM,ALN2DBXXMOVAH,4CHSUMDB?INT21HCODEENDSCODEENDSENDBEGENDBEG2.例:上例,写成COM格式源程序3.COM文件的生成设上例的文件名为N1ADDN2.ASM编辑生成N1ADDN2.ASM调用TASM.EXE生成N1ADDN2.OBJTASMN1ADDN2调用TLINK.EXE生成N1ADDN2.COMTLINKN1ADDN2/t注意:链接参数为小写字母t三.EXE文件、COM文件的内存映像INT20H…...数据段代码段堆栈段DS=ESCS:IPSS:SPPSP用户程序EXE文件内存映像1.EXE文件的内存映像DOS把EXE文件调入内存之后,自动在目标程序上方(低地址处)生成一个有256字节的数据块——程序段前缀(PSP)DOS令DS=ES=PSP段基址,即DS≠用户数据段段基址,ES≠用户附加段段基址DOS令CS:IP=代码段启动指令的逻辑地址三.EXE文件、COM文件的内存映像INT20H…...数据段代码段堆栈段DS=ESCS:IPSS:SPPSP用户程序EXE文件内存映像1.EXE文件的内存映像DOS令SS:SP=用户堆栈段(如果有堆栈段的话)栈顶的逻辑地址,所以:用户程序必须给DS赋值,使DS=用户数据段段基址;用户程序必须给ES赋值,使ES=用户附加段段基址FS=GS=0,如果用户程序使用了FS、GS附加段,则必须给FS、GS赋初值三.EXE文件、COM文件的内存映像INT20H…...代码段堆栈段00H00HCS=DS=ES=SSIP=100HSPPSP64K-256COM文件内存映像2.COM文件内存映像COM文件调入内存后,DOS也在其上方生成一个PSPCS=DS=SS=ES=PSP段基址,即用户程序的代码段、数据段、ES附加段和堆栈区都在一个64k的逻辑段中DOS自动使IP=100H,自动执行偏移地址为100H处的那条指令三.EXE文件、COM文件的内存映像INT20H…...代码段堆栈段00H00HCS=DS=ES=SSIP=100HSPPSP64K-256COM文件内存映像2.COM文件内存映像DOS自动使SP=FFFEH,且SS:[SP]=SS:[SP+1]=0,这就意味在COM文件中代码段以下,FFFEH以上这一片存储单元都是用户的堆栈区FS=GS=0四.程序段前缀—PSPPSP是一个有256字节的数据块,由DOS在装载可执行文件时自动生成。DOS通过PSP向用户程序传递数据,PSP是程序运行不可缺少的部分每一个可执行文件都伴随有自己的PSP五.返回DOS的基本方法对于EXE文件和COM文件,返回DOS最常用的方法是调用“INT21H”的4CH功能。除此之外:1.对于COM文件还有以下3种方法可以返回DOS,即:直接执行INT20H;调用INT21H的0号功能;执行RET指令。如果此时SP仍然等于FFFEH的话(程序中规范的使用堆栈,在执行RET之前把进栈的数据全部弹出,则SP必然等于FFFEH),CPU将无条件转入PSP的首单元,执行那里的INT20H,返回DOS。2.对于EXE文件的编程格式,还有一种返回DOS的方法,就是在需要返回DOS的时候,设法使CPU转到PSP首单元,执行那里的INT20指令。为此,源程序必须采取下面的3项措施,缺一不可:把代码段包含在一个远过程之中;在给DS赋初值之前,用下列3条指令把PSP首单元的物理地址压入栈顶,即:PUSHDSMOVAX,0PUSHAX在采取了以上两条措施之后,程序在需要返回DOS的地方执行一条RET指令即可返回DOS。因为这条RET指令是远过程中的返回指令,它将从栈顶弹出4个字节,即把PSP首单元的物理地址反弹到CS:IP之中,从而使CPU转移到PSP首单元,执行那里的INT20H,再返回DOS。综上所述,虽然返回DOS有好几种方法,但是调用INT21H的4CH功能,是返回DOS的最常用的方法,它的优点是简单、通用,而且有利于组织批处理文件。BIOS/DOS调用模式:MOVAH,功能号设置入口参数INTn分析出口参数BIOS/DOS功能调用子程序调用结束后一般都有出口参数,这些出口参数常放在寄存器中,通过出口参数可以知道功能调用的成功与否。其中n值因子程序不同而可能不同,比如:ROMBIOS有n=5~1FH,DOS有n=20H,21H,23~2AH,2EH,2FH,33H和67H等几种情况。有的n只对应一个子程序,有的n对应很多子程序,5.2DOS系统I/O功能调用在DOS功能子程序调用中,我们把通过INT21H来实现的子程序调用成为DOS系统功能调用。调用模式:MOVAH,功能号设置入口参数INT21H分析出口参数AH=?执行1#子程序执行2#子程序IRET21H型中断服务程序=1=2[功能号01H]等待键入一个字符,有回显,响应Ctrl_C入口参数:无。出口参数:AL=按键的ASC码,若AL=0,表明按键是功能键、光标键,需再次调用此功能,才能返回按键的扩展码。[功能号02H]显示一个字符,响应Ctrl_C入口参数:DL=待显字符的ASC码。出口参数:无。本功能在屏幕的当前位置显示一个字符,光标右移一格,如果是在一行末尾显示字符,则光标返回下一行的开始格。如果是在屏幕的右下角显示字符,光标返回时屏幕要上滚一行。试验表明,该项功能要破坏AL寄存器的内容。[功能号07H]等待键入一个字符,无回显,不响应Ctrl_C。入口参数:无。出口参数:AL=按键的ASC码,若AL=0,需再次调用该功能才能在AL中得到按键的扩展码。[功能号09H]显示字符串,响应Ctrl_C。入口参数:DS:DX=字符串首地址,字符串必须以‘$’(即ASC码24H)为结束标志。出口参数:无。该项功能从屏幕当前位置开始,显示字符串,遇到结束标志‘$’时停止,‘$’字符并不显示。实验表明,9号功能也破坏AL寄存器的内容。[功能号08H]等待键入一个字符,无回显,响应Ctrl_C。入口参数:无。出口参数:AL=按键的ASC码,若AL=0,需再次调用该功能才能在AL中得到按键的扩展码。[功能号0AH]等待键入一串字符,送用户程序数据缓冲区入口参数、出口参数如图所示。程序员预置可容纳的字符个数(包括回车键)0AH功能写入实际接收的字符个数(不包括回车键)数据缓冲区BUF+0+1+2...+n键入字符串的实际存储区域①0AH要求键入的字符串以“回车”作为结束标志,换句话说,按下回车键后,此功能调用结束,光标返回当前行始格。“回车”符留在缓冲区当中。②对数据缓冲区的格式有如下要求:缓冲区要设置在用户程序数据段,调用前,缓冲区首址偏移量应赋给DX寄存器。缓冲区首单元应预置“允许接受的字符个数”(包括回车符在内)。用户键入回车后,由0AH功能把实际键入的字符个数(不包括回车符)写入BUF+1单元。键入的字符串从BUF+2单元开始依次存放。因此,缓冲区的容量要大于或等于键入串的长度+2(注意:键入的字符串长度应包括回车符)。缓冲区不接受超长字符,并发出声响以示警告0AH在接收字符的过程中,有回显,响应Ctrl_C,按下退格键可删除屏幕及缓冲区中的当前字符。下面的程序段给出了0AH功能调用的示范,它允许用户键入15个字符(包括回车键)。假设数据段BUFDB15DB?DB15DUP(?)代码段…...MOVAH,0AHMOVDX,OFFSETBUFINT21H…...[功能号0CH]清除键盘缓冲区,然后调用由AL指定的功能。入口参数:AL允许是:01H键入一个字符,有回显,响应Ctrl_C。06H字符I/O。07H键入一个字符,无回显,不响应Ctrl_C。08H键入一个字符,无回显,响应Ctrl_C。0AH键入一串字符,写入用户数据区。其他入口参数应根据相关的功能,另行设置。[功能号4CH]该功能是指,终止当前程序的运行,并把控制权交给调用它的程序。由被终止程序打开的全部文件都被关闭,该项功能还把程序占用的内存空间交还给DOS另行分配。该项功能允许被终止的程序传送一个“返回码”给调用它的程序。假若被终止的程序是由DOS命令调入的,那么返回码可以被DOS批处理命令中的“IFERRORLEVEL”子命令识别。入口参数:AL=返回码(或者不设置)。出口参数:无。说明:当用户程序执行1,2,8,9,0AH,0BH,OCH功能调用时,如果键入Ctrl_C或者Ctrl_Break,DOS将自动调用INT23H中断处理程序,从而强行使用户程序中断,我们称为响应Ctrl_C。例:人机会话程序。问题:如何设置程序运行所需的数据?有以下几种方法数据设置在程序的数据段程序运行时通过人机会话临时键入程序装入时通过命令行参数给出本例学习前两种方法,并以此学习DOS功能调用。Limai?(Y/N)Whatisyourname?1.会话内容及设计思路Linai;前者是程序给出的询问信息,后者是用户键入的回答N;程序复制的姓名和回答提示Limai;再次问答Linai?(Y/N)Whatisyourname?Y2.框图:显示询问信息等待键入姓名串复制姓名串等待用户认可Y/NY返回DOS9#功能0AH#功能9#1#NDATASEGMENTUSE16MESG1DB0DH,0AHDB‘Whatisyourname?$’MESG2DB‘?(Y/N)$’BUFDB30DB?DB30DUP(?)DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DA:DATABEG:MOVAX,DATAMOVDS,AXAGAIN:MOVAH,9MOVDX,OFFSETMESG1INT21H;询问姓名MOVAH,0AHMOVDX,OFFSETBUFINT21H;接收键入字符串MOVBL,BUF+1MOVBH,0.486