南京邮电大学微型计算机原理与接口技术5-01章.ppt

上传人:sh****n 文档编号:11648837 上传时间:2020-04-30 格式:PPT 页数:118 大小:699.82KB
返回 下载 相关 举报
南京邮电大学微型计算机原理与接口技术5-01章.ppt_第1页
第1页 / 共118页
南京邮电大学微型计算机原理与接口技术5-01章.ppt_第2页
第2页 / 共118页
南京邮电大学微型计算机原理与接口技术5-01章.ppt_第3页
第3页 / 共118页
点击查看更多>>
资源描述
汇编语言程序设计Ch.5汇编语言程序设计5.1汇编源程序的编程格式5.2DOS系统I/O功能调用5.3BIOS键盘输入功能调用5.5分支程序5.6循环程序5.7子程序及其调用5.8宏指令与条件汇编5.9代码转换5.10数值计算和数据处理5.12模块化程序设计,.486DATASEGMENTUSE16MESGDBA,0DH,0AH,$DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXDS初值;以上设置MOVAH,4CHINT21H;返回DOSCODEENDSENDBEG;汇编结束语句,例:将N1和N2两个单字节数以28为模求和SUM单元.,5.1汇编源程序的编程格式,1.EXE文件编程格式允许源程序使用多个逻辑段,适合编写大型程序,最终能生成.EXE文件.,.486DATASEGMENTUSE16N1DBxxN2DBxxSUMDB?DATAENDSSTACK_SEGMENTSTACKSTACKUSE16DB128DUP(?)STACK_ENDS,BEG:MOVAX,DATAMOVDS,AXMOVAX,STACK_MOVSS,AXMOVSP,128MOVAL,N1ADDAL,N2MOVSUM,ALMOVAH,4CHINT21HCODEENDSENDBEG,CODESEGMENTUSE16ASSUMECS:CODE,DS:DATA,SS:STACK_,说明:.EXE文件中堆栈段的设置a本例以“STACK_”为段名的逻辑段,选用了“STACK”链接参数,DOS自动认为“STACK_”段为堆栈段。所以,DOS将自动给SS:SP赋初值,因此,源程序给SS:SP赋初值的三条语句是多余的。,b链接程序要求:.EXE文件中的源程序必须有堆栈段,否则链接时将给出警告信息:Warningnostacksegment但这不代表源程序有错,仅仅是警告而已,c如果源程序中不设置堆栈段(在链接时,会给出错误信息),DOS将自动给程序分配最少128字节的堆栈区,故源程序中,如果没有大量数据压栈的话,可以不设置堆栈段,从而简化程序。,.486DATASEGMENTUSE16N1DBxxN2DBxxSUMDB?DATAENDSSTACK_SEGMENTSTACKSTACKUSE16DB128DUP(?)STACK_ENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATA,SS:STACK_BEG:MOVAX,DATAMOVDS,AXMOVAX,STACK_MOVSS,AXMOVSP,128MOVAL,N1ADDAL,N2MOVSUM,ALMOVAH,4CHINT21HCODEENDSENDBEG,2.COM文件的编程格式(1)汇编语言规定:COM文件的源程序只能有一个段:代码段,不允许有堆栈段;在代码段偏移地址=100H处,必须是程序的启动指令;程序中使用的数据可以放在代码段的开始或结尾.,.486.486CODESEGMENTUSE16CODESEGMENTUSE16ASSUMECS:CODEASSUMECS:CODEORG100HORG100HBEG:JMPSTARTBEG:MOVAL,N1N1DBXXADDAL,N2N2DBXXMOVSUM,ALSUMDB?MOVAH,4CHSTART:MOVAL,N1INT21HADDAL,N2N1DBXXMOVSUM,ALN2DBXXMOVAH,4CHSUMDB?INT21HCODEENDSCODEENDSENDBEGENDBEG,(2)上例写成COM格式源程序,(3)COM文件的生成设上例的文件名为N1ADDN2.ASM编辑生成N1ADDN2.ASM调用TASM.EXE生成N1ADDN2.OBJTASMN1ADDN2调用TLINK.EXE生成N1ADDN2.COMTLINKN1ADDN2/t注意:链接参数为小写字母t,DOS系统I/O功能的调用,DOS操作系统由四个部分组成,其中:IBMDOS.COM:是磁盘文件管理程序IBMBIO.COM:是基本I/O设备处理程序这两个模块中都有若干子程序,供应用程序调用,可调用的子程序集中存放在“21H型中断服务程序”中,用户程序调用这些子程序就称为“DOS系统功能调用”,BIOS/DOS调用模式:MOVAH,功能号设置入口参数INTn分析出口参数,BIOS/DOS功能调用,1.调用模式MOVAH,功能号设置入口参数INT21H分析出口参数,.2DOS系统I/O功能调用,在DOS功能子程序调用中,我们把通过INT21H来实现的子程序调用成为DOS系统功能调用。,功能号01等待键入一个字符,有回显,响应Ctrl_C。入口参数:无;出口参数:AL=按键的ASC码.若AL=0,表明按键是功能键、光标键,需再次调用此功能,才能返回按键的扩展码。,功能号07等待键入一个字符,无回显,不响应Ctrl_C。入口参数:无;出口参数:AL=按键的ASC码.若AL,需再次调用该功能才能在AL中得到按键的扩展码。.,功能号08等待键入一个字符,无回显,响应Ctrl_C。入口参数:无;出口参数:AL=按键的ASC码,若AL0,需再次调用该功能才能在AL中得到按键的扩展码。,2键盘功能的调用,功能号0AH等待键入一串字符,送用户程序数据缓冲区入口参数、出口参数如图所示。,使用0AH号功能的几点说明:要求键入的字符串以“回车”作为结束标志,换句话说,按下回车键后,此功能调用结束,光标返回当前行始格。“回车”符留在缓冲区当中。,缓冲区要设置在用户程序数据段,调用前,缓冲区首址偏移量应赋给DX寄存器;缓冲区首单元应预置“允许接受的字符个数”(包括回车符在内,最多255个);,DOS的操作:接受的键入的字符串从BUF+2单元开始依次存放。因此,设置的缓冲区容量要不小于键入串的长度+2;用户键入回车后,把实际键入的字符个数(不包括回车符)写入BUF+1单元;缓冲区不接受超长字符,并发出声响以示警告。,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键入一串字符,写入用户数据区。其他入口参数应根据相关的功能,另行设置。,功能号02H显示一个字符,响应Ctrl_C入口参数:DL=待显字符的ASC码。出口参数:无。本功能在屏幕的当前位置显示一个字符,光标右移一格,如果是在一行末尾显示字符,则光标返回下一行的开始格。如果是在屏幕的右下角显示字符,光标返回时屏幕要上滚一行。,3.显示功能的调用,注意:该项功能破坏AL寄存器的内容。,功能号09H显示字符串,响应Ctrl_C。入口参数:DS:DX=字符串首地址,字符串必须以$为结束标志。(ASC码24H)出口参数:无。该项功能从屏幕当前位置开始,显示字符串,遇到结束标志$时停止,$字符并不显示。,注意:该项功能破坏AL寄存器的内容。,功能号4CH该功能是指,终止当前程序的运行,并把控制权交给调用它的程序。由被终止程序打开的全部文件都被关闭,该项功能还把程序占用的内存空间交还给DOS另行分配。该项功能允许被终止的程序传送一个“返回码”给调用它的程序。假若被终止的程序是由DOS命令调入的,那么返回码可以被DOS批处理命令中的“IFERRORLEVEL”子命令识别。入口参数:AL=返回码(或者不设置)。出口参数:无。,说明:当用户程序执行1,2,8,9,0AH,0BH,OCH功能调用时,如果键入Ctrl_C或者Ctrl_Break,DOS将自动调用INT23H中断处理程序,从而强行使用户程序中断,我们称为响应Ctrl_C。,4.其它功能的调用,例:人机会话程序。问题:如何设置程序运行所需的数据?有以下几种方法数据设置在程序的数据段程序运行时通过人机会话临时键入程序装入时通过命令行参数给出本例学习前两种方法,并以此学习DOS功能调用。,Limai?(Y/N),Whatisyourname?,(1)会话内容及设计思路,Linai;前者是程序给出的询问信息,后者是用户键入的回答,N;程序复制的姓名和回答提示,Limai;再次问答,Linai?(Y/N),Whatisyourname?,Y,(2)框图:,N,DATASEGMENTUSE16MESG1DB0DH,0AHDBWhatisyourname?$MESG2DB?(Y/N)$BUFDB30DB?DB30DUP(?)DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DA:DATABEG:MOVAX,DATAMOVDS,AXAGAIN:MOVAH,9MOVDX,OFFSETMESG1INT21H;询问姓名MOVAH,0AHMOVDX,OFFSETBUFINT21H;接收键入字符串MOVBL,BUF+1MOVBH,0,.486,;实际键入的字符个数BXMOVSI,OFFSETBUF+2MOVBYTEPTRBX+SI,$;用$作为串结束符MOVAH,2MOVDL,0AHINT21H;光标下移一行MOVAH,9MOVDX,OFFSETBUF+2INT21H;复制键入的字符串MOVAH,9MOVDX,OFFSETMESG2INT21H;给出认可信息MOVAH,1INT21H;等待键入CMPAL,Y;比较JNEAGAINMOVAH,4CHINT21H;返回DOSCODEENDSENDBEG,.3BIOS键盘输入功能调用(自学),主板EPROM中固化有基本I/O系统程序BIOS,它是最接近硬件的驱动程序,BIOS中的许多子程序可被用户程序调用,调用这些子程序称为BIOS功能调用。,结构化程序设计顺序结构分枝结构循环机构子程序,顺序结构,.486DATASEGMENTUSE16SIGNDBADATAENDSCODESEGMENTUSE16ASSUMECS:CODEBEG:MOVAX,DATAMOVDS,AXMOVAH,2MOVDL,SIGNINT21HMOVAH,4CHINT21HCODEENDSENDBEG,1分枝结构,5.5分支程序,例1.二进制数显示将BX寄存器中的内容以二进制数格式屏显,DOS功能调用BIOS功能调用:(本例令BX=5678H),2.示例,N,数BX,16次CX,C=0,1DL,调显示程序,CX-1CX=0,0DLBX左移一位,Y,N,Y,返DOS,解:486CODESEGMENTUSE16ASSUMECS:CODEBEG:MOVBX,5678HMOVCX,16LAST:MOVDL,0ROLBX,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTMOVAH,4CHINT21HCODEENDSENDBEG,例2.复合分支举例(书例自学)某科室9人,统计月收入在800元900元间的人数,并用十进制数显示。,解:月收入是无符号数,本例对一批数处理使用间接寻址。,月收入在800元900元间的解释:800月收入900,486DATASEGMENTUSE16NUMDWXX,XXDATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVBX,OFFSETNUMMOVCX,9MOVDL,0LAST:CMPWORDPTRBX,800JBNEXT;900转INCDLNEXT:INCBXINCBXLOOPLAST,ADDDL,30HMOVAH,2INT21HMOVAH,4CHINT21HCODEENDSENDBEG,例3.多分支段内转移要求:键入0,转P0程序段键入1,转P1程序段键入9,转P9程序段,思路:用比较指令配合直接转移指令实现CMP键入字符,0JEP0CMP键入字符,1JEP1,用转移地址表配合间接转移指令实现,486DATASEGMENTUSE16TABDWP0,P1,P9;汇编后自动装入相应的偏移地址MESGDB0DH,0AH,strike09:$DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXAGA:MOVAH,9MOVDX,OFFSETMESGINT21HMOVAH,1INT21HCMPAL,0JCAGACMPAL,9JAAGASUBAL,30HMOVZXBX,ALADDBX,BX;2BXBXMOVSI,OFFSETTAB,JMPBX+SI;DS:BX+SIIPP0:P1:P9:CODEENDSENDBEG,1.循环程序的结构,5.6循环程序,多体循环,2.结束循环的方法(编程技巧)用寄存器做循环计数器用主存单元做循环计数器用循环结束标志结束循环,ASC码是由7位二进制数表示的,所以可以把ASC码看成无符号数。,例.设从BUF单元开始,存有若干个ASC码。找出其中表示ASC码的最大数值送屏幕显示。,解法1486DATASEGMENTUSE16BUFDBQWERTYUIOP123COUNTEQU$-BUF;统计串长度MAXDBMAX=,?,0DH,0AH,$DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAL,0LEABX,BUFMOVCX,COUNTLAST:CMPBX,AL;比较JBENEXTMOVAL,BX;大数ALNEXT:INCBXLOOPLAST;循环计数MOVMAX+4,AL,MOVAH,9MOVDX,OFFSETMAXINT21H;显示结果MOVAH,4CHINT21H;返回DOSCODEENDSENDBEG,解法2486DATASEGMENTUSE16BUFDBQWERTYUIOP123FLAGDB1;设置串结束标志MAXDBMAX=,?,0DH,0AH,$DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAL,0LEABX,BUFLAST:CMPBYTEPTRBX,-1JEDISP;是,转CMPBX,ALJNANEXTMOVAL,BXNEXT:INCBXJMPLASTDISP:MOVMAX+4,AL,MOVAH,9MOVDX,OFFSETMAXINT21H;显示结果MOVAH,4CHINT21H;返回DOSCODEENDSENDBEG,5.7子程序及其调用,子程序是相对独立的程序,当程序中要多次完成某一操作时,为了简化整体程序,增强程序可读性,常常把“完成某一操作”设计成一个子程序,供调用。,向子程序传递参数的方法通过寄存器传递参数利用堆栈区传递参数利用主存单元传递参数,子程序用PROC/ENDP定界,子程序分为:段内子程序、段间子程序、无参数子程序、有参数子程序,例.无参数子程序,CODESEGMENTCALLCRLFCALLCRLF,CRLFPROCMOVAH,2MOVDL,0DHINT21HMOVAH,2MOVDL,0AHINT21HRETCRLFENDPCODEENDS,例.用寄存器传递参数,数据段:MESG1DBPleaseEnter09:$MESG2DBStrikeanykey,0DH,0AH,$,例.设N1=1122H,N2=3344H,N3=5566H用子程序调用的方法实现3个数的累加和,解法1:编程技巧:把数据单元的偏移地址传送给计算累加和的子程序,CODESEGMENTUSE16ASSUMECS:CODEASSUMEDS:DATA,SS:STACK_BEG:MOVAX,DATAMOVDS,AXMOVSI,OFFSETNUM;参数指针SICALLCOMPUTEXYZ:CALLDISPEXIT:MOVAH,4CHINT21H;-COMPUTEPROCMOVBX,0ADDBX,SI+0;BX+N1BXADDBX,SI+2;BX+N2BXADDBX,SI+4;BX+N3BXRET;返断点XYZCOMPUTEENDP,DISPPROC;显示BX内容MOVCX,16LAST:MOVDL,0RCLBX,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTRET;返断点EXITDISPENDPCODEENDSENDBEG,解法2:编程技巧:调用前先把数据压栈,计算累加和的子程序从堆栈中取数,完成累加和。,.486DATASEGMENTUSE16NUMDW1122H;N1DW3344H;N2DW5566H;N3DATAENDSSTACK_SEGMENTSTACKSTACKUSE16DB100DUP(?)STACK_ENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATA,SS:STACK_,程序清单:,BEG:MOVAX,DATAMOVDS,AXMOVSI,OFFSETNUM;N1,N2,N3压栈PUSHWORDPTRSI+0PUSHWORDPTRSI+2PUSHWORDPTRSI+4CALLCOMPUTEXYZ:CALLDISPEXIT:MOVAH,4CHINT21H;-COMPUTEPROCMOVBP,SPMOVBX,0ADDBX,BP+2ADDBX,BP+4ADDBX,BP+6RET6;返断点XYZ,清栈COMPUTEENDP,;-DISPPROC;显示BX内容MOVCX,16LAST:MOVDL,0RCLBX,1ADCDL,0MOVAH,2INT21HLOOPLASTRET;返断点EXITDISPENDPCODEENDSENDBEG,解法3:编程技巧:数据放在代码段,利用主存单元传递数据,COMPUTEPROCMOVBP,SP;栈针BP;断口地址NUMSIMOVSI,BP+0MOVBX,0;BX+N1BXADDBX,CS:SI+0;BX+N2BXADDBX,CS:SI+2;BX+N3BXADDBX,CS:SI+4;弹出原来的断口地址POPAXMOVAX,OFFSETXYZPUSHAXRET;返回断点XYZCOMPUTEENDP,;显示BX内容DISPPROCMOVCX,16LAST:MOVAL,0RCLBX,1ADCAL,0MOVAH,0EHINT10HLOOPLAST;返回断点EXITRETDISPENDPCODEENDSENDBEG,Thesimpler,thebetter!,Thesimpler,thebetter!,Thesimpler,thebetter!,5.8宏指令与条件汇编,子程序调用可以简化程序,但是如果子程序的参数太多,调用时太麻烦,汇编语言提供了另一种简化的途径宏指令。,宏指令是汇编语言提供的伪指令!是用户自行设计的程序.,宏指令有:无参数宏指令、有参数宏指令,宏指令应该先定义后调用,宏指令的定义,可以不在任何逻辑段之中,习惯上放在源程序首部,(1)宏定义语句的格式宏指令名字MACRO宏体ENDM,1.无参数宏指令的定义与调用,(2)宏指令调用宏指令先行定义之后,在代码段的任何位置,书写“宏指令名字”即完成了调用。,(3)宏指令的“汇编”汇编时,汇编程序自动用宏体取代宏调用。,例:486CRLFMACRO;实现回车换行MOVAH,0EHMOVAL,0DHINT10HMOVAL,0AHINT10HENDMCODESEGMENTUSE16ASSUMECS:CODEBEG:MOVAH,2MOVDL,AINT21HCRLF,汇编时,自动用宏体替换宏指令拷贝一份到这儿,2.有参数的宏指令及其调用格式:宏指令名字MACRO哑元1,哑元2,哑元n宏体ENDM,调用格式:宏指令名字实元1,实元2,实元n,注意:实元表是一串用逗号(或空格)间隔的立即数,寄存器操作数或者是没有PTR说明符的存储器操作数。汇编时,汇编程序自动地把实元一一对应的赋给哑元。,例.定位显示彩色字符串要求置显示器为彩色文本方式,并在:0行5列显示黑底绿色HELLO12行36列显示黑底红色WELCOME!24行66列显示黑底黄色BYE_BYE,解:.486DISPMACROY,X,VAR,LENGTH,COLORMOVAH,13HMOVAL,1MOVBH,0;选择0页显示屏MOVBL,COLOR;属性字(颜色值)BLMOVCX,LENGTH;串长度CXMOVDH,Y;行号DHMOVDL,X;列号DLMOVBP,OFFSETVAR;串有效地址BPINT10HENDM,EDATASEGMENTUSE16SS1DBHELLOSS2DBWELCOME!SS3DBBYE_BYEEDATAENDSCODESEGMENTUSE16ASSUMECS:CODE,ES:EDATAMOVAX,EDATAMOVES,AXMOVAX,3INT10HDISP0,5,SS1,5,2;0行5列显示绿色HELLODISP12,36,SS2,8,4;12行36列显示红色WELCOMEDISP24,66,SS3,7,0EH;24行66列显示黄色BYE_BYESCAN:MOVAH,1INT16HJZSCAN;等待用户键入,无键入转,MOVAX,2INT10H;恢复8025黑白文本方式MOVAH,4CHINT21HCODEENDSENDBEG,分析:BIOSINT10H的13H子功能,要求待显字符串在附加段,串首址ES:BP对哑参数的赋值是在调用指令中完成的子程序调用能减小目标程序的体积,而宏指令调用则不能减小目标程序的体积宏指令可以嵌套,3.LOCAL伪指令如果宏体中有分支、转移,则必然有标号,2次以上调用这样的宏体,就会出现标号重复定义的错误,为此汇编语言又提供了一条LOCAL伪指令。,应用:用LOCAL定义的标号称为“局部标号”,它是宏体中所有标号的集合。局部标号可以和代码段中其他标号重名。宏指令仅被调用1次时,不必使用LOCAL伪指令。,例.分组显示8,16,32位二进制数,解:.486CRLFMACRO;光标返回下一行始格MOVAH,0EHMOVAL,0DHINT10HMOVAL,0AHINT10HENDM,格式:LOCAL标号1,标号2,标号n,;分组显示VAR中的NN位二进制数DISPMACROVAR,NNLOCALL1,L2MOVCH,NN/4L1:MOVCL,4L2:MOVAL,0ROLVAR,1ADCAL,0MOVAH,0EHINT10HDECCLJNZL2MOVAL,INT10HDECCHJNZL1CRLFENDM,CODESEGMENTUSE16ASSUMECS:CODENUMDB88HBEG:MOVEBX,12345678HDISPBH,8;显示BH中的8位数DISPBX,16;显示BX中的16位数DISPEBX,32;显示EBX中的32位数DISPNUM,8;显示NUM单元中的8位数MOVAH,4CHINT21HCODEENDSENDBEG,4.条件汇编语句:条件汇编是汇编语言提供的伪指令、伪语句。高版本的汇编语言提供了许多格式的条件语句,此处仅介绍最常用、最基本的格式。,格式1:IF条件语句集合ELSE语句集合2ENDIF,格式2:IF条件语句集合ENDIF,说明:IF/ENDIF是一对定界语句,“条件”为逻辑表达式或关系表达式。,格式1功能:如果条件成立,汇编语句集合1;如果不成立,汇编语句集合2。格式2功能:如果条件成立,汇编语句集合,否则不汇编。,5.9代码转换,常见的代码转换有:二进制数显示,二进制数十进制数显示,二进制数十六进制数显示,BCD码数二进制数,1.二进制数显示,解:486CODESEGMENTUSE16ASSUMECS:CODEBEG:MOVBX,5678HMOVCX,16LAST:MOVDL,0ROLBX,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTMOVAH,4CHINT21HCODEENDSENDBEG,DISPPROCMOVCX,16LAST:MOVDL,0RCLBX,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTRETDISPENDPCODEENDS,DISPPROCLAST:MOVDL,0RCLEBX,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTRETDISPENDPCODEENDS,通用的二进制数显示子程序,MOVBX,12HRALEBX,24MOVCX,8CALLDISP,MOVBX,1234HRALEBX,16MOVCX,16CALLDISP,MOVEBX,12345678HMOVCX,32CALLDISP,例.把键盘输入的一位数(09),转换成等值二进数显示,显示的格式要求如下:,A,PleaseEnter,PleaseEnter,9,=00001001B,思路:键盘缓冲区中是键入字符的ASC码。09的ASC码为30H39H。二进制数每一位代码的判断:,本程序采用两种格式设计源程序:一种是EXE文件编程格式,另一种是COM文件编程格式。,程序框图:,AL-30HBL=屏幕,8CX,0屏幕,1屏幕,CX-1CX,B屏幕,返回DOS,N,N,给出操作提示键盘输入AL,AL=09?,CF=?,CX=0?,BL左移一位,Y,显示错误信息,Y,0,1,.486DATASEGMENTUSE16MESG1DBPleaseEnter!,0DH,0AH,$MESG2DB-Error!$DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAH,9MOVDX,OFFSETMESG1INT21H;显示操作提示MOVAH,1INT21H;等待键入CMPAL,39HJAERROR;9转CMPAL,30HJBERROR;0转SUBAL,30HMOVBL,AL;BL=09的二进制数,EXE格式程序清单,MOVAH,2MOVDL,=INT21HCALLDISPMOVAH,2MOVDL,BINT21HJMPEXITERROR:MOVAH,9MOVDX,OFFSETMESG2INT21H;显示错误信息EXIT:MOVAH,4CHINT21H,;-DISPPROC;显示BL中的二进制数MOVCX,8LAST:MOVDL,0RCLBL,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTRETDISPENDPCODEENDSENDBEG,COM格式程序清单.486CODESEGMENTUSE16ASSUMECS:CODEORG100HSTART:JMPBEGMESG1DBPleaseEnter!,0DH,0AH,$MESG2DB-Error!$BEG:MOVAH,9MOVDX,OFFSETMESG1INT21H;显示操作提示MOVAH,1INT21H;等待键入CMPAL,3AHJNCERROR;9转CMPAL,30HJCERROR;0转SUBAL,30H,MOVBL,AL;BL=09的二进制数MOVAH,2MOVDL,=INT21HCALLDISPMOVAH,2MOVDL,BINT21HJMPEXITERROR:MOVAH,9MOVDX,OFFSETMESG2INT21H;显示错误信息EXIT:MOVAH,4CHINT21H,;-DISPPROC;显示BL中的二进制数MOVCX,8LAST:MOVDL,0RCLBL,1JNCNEXTMOVDL,1NEXT:MOVAH,2INT21HLOOPLASTRETDISPENDPCODEENDSENDSTART,2.二进制数十六进制数显示,思路:,编程方法:,;二进数ACSII码N2_16ASCPROCMOVSI,OFFSETBUF;输出缓冲区地址SIMOVCOUNT,2LAST:ROLEDX,4ANDDL,0FHCMPDL,10JCNEXTADDDL,7NEXT:ADDDL,30HMOVSI,DLINCSI;地址加1DECCOUNT;计数JNZLASTRETN2_16ASCENDPCODEENDSENDBEG,MOVDL,9AHSALEDX,24CALLN2_16ASC,;二进数ACSII码N2_16ASCPROCMOVSI,OFFSETBUF;输出缓冲区地址SIMOVCOUNT,4LAST:ROLEDX,4ANDDL,0FHCMPDL,10JCNEXTADDDL,7NEXT:ADDDL,30HMOVSI,DLINCSI;地址加1DECCOUNT;计数JNZLASTRETN2_16ASCENDPCODEENDSENDBEG,MOVDX,89ABHSALEDX,16CALLN2_16ASC,例.设从BNUM单元开始,有4个16位的二进制数,要求把它们转换成16进制数,并送屏幕显示。,程序清单.486DATASEGMENTUSE16BNUMDW0001001000110100B;1234HDW0101011001111000B;5678HDW0001101000101011B;1A2BHDW0011110001001101B;3C4DHBUFDB4DUP(?),H$;输出缓冲区COUNTDB4DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATA,BEG:MOVAX,DATAMOVDS,AXMOVCX,4MOVBX,OFFSETBNUMAGA:MOVDX,BXSALEDX,16CALLN2_16ASCMOVAH,9MOVDX,OFFSETBUFINT21H;显示一个16进数ADDBX,2;地址加2LOOPAGAMOVAH,4CHINT21H,;二进数十六进数ACSII码N2_16ASCPROCMOVSI,OFFSETBUF;输出缓冲区地址SIMOVCOUNT,4LAST:ROLEDX,4ANDDL,0FHCMPDL,10JCNEXTADDDL,7NEXT:ADDDL,30HMOVSI,DLINCSI;地址加1DECCOUNT;计数JNZLASTRETN2_16ASCENDPCODEENDSENDBEG,3.二进制数十进制数,方法:比较法,恢复余数法,除法,8位二进制数最大为11111111,等值的十进制数为255,因此,比较法的关键是:判断某二进制数(假设为BEN单元的内容)包含几个100,几个10,几个1。,(1)8位二进制数十进制数比较法:,DL+1DL(BEN)-10BEN,(BEN)=100?,N,Y,(BEN)=10?,N,Y,DL+1DL(BEN)-100BEN,DL+30H屏幕0DL,DL+30H屏幕(BEN)+30H屏幕返回DOS,程序清单.486CMPDISPMACRONNLOCALLAST,NEXT;DL清0MOVDL,0LAST:CMPBEN,NN;比较JBNEXTINCDL;DL加1SUBBEN,NNJMPLASTNEXT:ADDDL,30HMOVAH,2INT21H;显示ENDM,CODESEGMENTUSE16ASSUMECS:CODEBENDB10101110B;=174BEG:CMPDISP100CMPDISP10CMPDISP1MOVAH,4CHINT21HCODEENDSENDBEG,(2)恢复余数法(请自学)(3)“除权值求商”的算法分析,把11110101B十进制数245,算法:依次用权值100,10,1去除上次的余数,直到余数为0时停止。每次除法所得的商数顺序排列,即为十进制数。,例.将NUM单元中的16位二进制数,转换成十进制数显示。,思路:16位二进制数:最大为11,其等值的十进制数为65535,故应判断NUM单元的数包含几个10000,几个1000,几个100,几个10,几个1设计一个XXYY并显示商值的宏指令供调用,XX为32位,YY为16为二进制数。,程序清单486DIVIDEMACROXX,YYMOVAX,XXMOVDX,0MOVCX,YY;CX为除数DIVCX;AX=商,且1010B,DX=余数MOVAH,0EHADDAL,30HINT10HENDMCODESEGMENTUSE16ASSUMECS:CODENUMDW65530;汇编后为二进制数BEG:DIVIDENUM,10000DIVIDEDX,1000,DX,AX为被除数,本题在代码段中设置数据,这是COM格式?EXE格式?如果改为:BEG:MOVBX,OFFSETNUMDIVIDEBX,10000是错误的,为什么?,DIVIDEDX,100DIVIDEDX,10DIVIDEDX,1MOVAH,4CHINT21HCODEENDSENDBEG,显示一位商值,不能颠倒,分析:,应写成:DIVIDECS:BX,10000,(4)“除十取余”的算法分析把11110101十进制数245,算法:N被(10)10除,商再被(10)10除,直到商数为0时止。每次所得的余数按倒序方式排列显示。,编程技巧:每次除法的余数栈,除法结束后,再从堆栈中依次弹出余数+30H屏。,8位32位二进制数转换成十进制数,通用的除法求余框图:(书p119程序,自学)设N为待转换的8位32位二进制数,EAX=商,EDX=余数,且余数肯定1010B统计除法的次数,4.BCD码二进制数例.4位BCD码数二进制数显示,算法:设4位BCD码数列为:N3N2N1N0,等值二进制数=N31000+N2100+N110+N0=(010+N3)10+N2)10+N1)10+N0,编程考虑:4位BCD码最大为9999H,等值的二进制数最大为16位(超过8位),而且D15位肯定为0分离出BCD千位N3,百位N2,十位N1,个位N0设计一个AX10+BXAX的子程序供调用,首次调用时,令AX=0,BX=N3,共调用4次,则AX中即为等值的二进制数。,本例数据放在代码段!本例:因为AX的D15=0,是正的有符号数,所以可用IMUL指令。,1.程序模块化的作用在设计大型程序时,为了加快设计速度,把一个大程序分解成若干个有独立功能的子模块分别设计,最后链接成一个大的可执行文件。,2.模块的层次结构,符号名是标号、变量名、过程名的“统称”,在模块化设计中,往往会有模块之间的调用和转移,因此在一个模块中也会出现另一个模块中的标号、过程名等;又由于在进行模块化程序设计时,容易出现符号名相重的问题,所以在链接时就出现了错误.,3.符号名的引用(模块间的参数传送),如何解决上述的问题呢?汇编语言提供了3条支持模块化程序的伪指令。,(1)PUBLIC伪指令(公用符号名说明语句)格式:PUBLIC符号名,符号名如:PUBLICNEXT,MESG,应用:PUBLIC伪指令应出现在定义了这些符号名的模块上方。,功能:通知链接程序,用PUBLIC说明的这些符号是公用的,它们要被其他模块引用。,注意:段定义语句中的PUBLIC段参数和PUBLIC伪指令是两回事。PUBLIC段参数:通知链接程序,把不同模块中都有PUBLIC属性的同名段,按照指定的链接顺序,组成一个大的逻辑段。,功能:通知汇编程序,用EXTRN说明的这些符号是外部符号名,这些符号及其属性已经在其他模块定义过了,本模块引用。如果不用EXTRN伪指令说明,汇编时给出错误信息:symbolnotdefined符号没定义,应用:EXTRN伪指令,放在引用这些符号名的模块的上方。,(2)EXTRN伪指令(外部符号名说明语句)格式:EXTRN符号名:属性,符号名:属性如:EXTRNNEXT:FAR,MESG:BYTE,(3)INCLUDE伪指令格式:INCLUDE盘符:路径文件名.扩展名,应用:宏指令共享和子程序共享时使用。,功能:将指定路径上的文件,拷贝一份到本语句的下方,供汇编程序汇编源程序时使用。,5.12.2模块化程序的设计考虑1.合理划分模块尽量减少模块间的调用2.模块之间性质相同的逻辑段,要不要组合?,要组合,需采取2项措施待组合的逻辑段:选用相同的段名,选用PUBLIC参数,缺一不可。,如:各模块之间的代码段,要不要组合成一个统一的代码段?各模块之间的数据段,要不要组合成一个统一的数据段?这一问题要优先考虑。无外乎两种选择:,不组合待组合的逻辑段:选用不同的段名,或者不选用PUBLIC段参数,或者链接参数缺省即可。,3.模块之间的转移与调用如果不同模块之间的代码段最后要组合成一个统一的代码段,那么模块之间的转移和调用就是段内转移和段内调用(近过程调用).,如果不同模块之间的代码段,链接后仍然是各自独立的代码段,那么模块之间的转移、调用均为段间转移和段间调用(远过程调用).,4.不论采用组合形式,还是非组合形式,模块之间只要出现符号名引用,都必须用PUBLIC、EXTRN语句对符号名进行说明.,键入“1”,屏幕中央显示“WelcomeToBeijing!”,底部显示“Pleasestrikeanykey”,击任意键之后,再显示菜单。,5.12.3模块化程序设计举例设计一个简易的旅游菜单程序,主菜单界面如下:,键入“2”,屏幕中央显示“WelcomeToNanjing!”,底部显示“Pleasestrikeanykey”,击任意键之后,再显示菜单。,5.12.3模块化程序设计举例设计一个简易的旅游菜单程序,主菜单界面如下:,键入“3”,返回DOS。,5.12.3模块化程序设计举例设计一个简易的旅游菜单程序,主菜单界面如下:,1.编程(见书p159),分3个模块:主模块显示主菜单,完成菜单项选择。子模块1:显示“WelcomeToBeijing!”子模块2:显示“WelcomeToNanjing!”3个模块都有各自的数据段、代码段链接后,各模块的数据段不组合,各自独立各模块的代码段不组合,各自独立,2程序的框架结构,EXTRNBEG1:FAREXTRNBEG2:FARPUBLICBEG,EXTRNBEG:FARPUBLICBEG1,EXTRNBEG:FARPUBLICBEG2,DATA0SEGMENTDATA0ENDSCODE0SEGMENTBEG:MOVAX,DATA0MOVDS,AX显示菜单键入1转BEG1键入2转BEG2CODE0ENDSENDBEG,DATA1SEGMENTDATA1ENDSCODE1SEGMENTBEG1:MOVAX,DATA1MOVDS,AX显示欢迎词JMPBEGCODE1ENDSEND,DATA2SEGMENTDATA2ENDSCODE2SEGMENTBEG2:MOVAX,DATA2MOVDS,AX显示欢迎词JMPBEGCODE2ENDSEND,注意:解法1的特点是:主模块、子模块1、子模块2的汇编结束语句不同;模块之间:数据段段名不同,没有PUBLIC段参数,所以各模块数据段是独立的;模块之间:代码段段名不同,没有PUBLIC段参数,所以各模块代码段是独立的,因此模块间的转移是段间转移;各模块上方用PUBLIC、EXTRN说明了符号名的引用情况。,解法1主模块.486PUBLICBEGEXTRNBEG1:FAR,BEG2:FARDISPMACROYYXX,VARMOVAH,2MOVBH,0MOVDX,YYXXINT10HMOVAH,9MOVDX,OFFSETVARINT21HENDMDATA0SEGMENTUSE16NEQU28DUP()L1DBN,MENU,0DH,0AHDBN,0DH,0AHDBN,1.BeiJing,0DH,0AHDBN,2.NanJing,0DH,0AHDBN,3.RetrunDOS,0DH,0AHDBN,0DH,0AHL7DBN,Chioce(1,2,3):$DATA0ENDS,CODE0SEGMENTCODEUSE16ASSUMECS:CODE0,DS:DATA0BEG:MOVAX,DATA0MOVDS,AXMOVAX,2INT10HDISP0500H,L1AGA:DISP0B00H,L7MOVAH,1INT21HCMPAL,3JEEXITCMPAL,1JEBEG1CMPAL,2JEBEG2JMPAGAEXIT:MOVAH,4CHINT21HCODE0ENDSENDBEG,解法1子模块1.486PUBLICBEG1EXTRNBEG:FARDISPMACROYYXX,VAR同解法1主模块ENDMDATA1SEGMENTUSE16MESG1DBWelcomeToBeiJing!$ENDMESGDBPleasestrikeanykey$DATA1ENDS,CODE1SEGMENTCODEUSE16ASSUMECS:CODE1,DS:DATA1BEG1:MOVAX,DATA1MOVDS,AXMOVAX,2INT10HDISP0C1EH,MESG1DISP171DH,ENDMESGMOVAH,1INT21HJMPBEGCODE1ENDSEND,解法1子模块2.486PUBLICBEG2EXTRNBEG:FARDISPMACROYYXX,VAR同解法1主模块ENDMDATA2SEGMENTUSE16MESG2DBWelcomeToNanJing!$ENDMESGDBPleasestrikeanykey$DATA2ENDS,CODE2SEGMENTCODEUSE16ASSUMECS:CODE2,DS:DATA2BEG2:MOVAX,DATA2MOVDS,AXMOVAX,2INT10HDISP0C1EH,MESG2DISP171DH,ENDMESGMOVAH,1INT21HJMPBEGCODE2ENDSEND,以上解法,每一个模块中都定义了一条宏指令DISP,该指令完成光标定位与字符串显示,宏指令的名称、结构、参数都相同。能不能只定义一次,使各模块共享呢?可以!为此目的,汇编语言设计了一条INCLUDE伪指令。,怎样使用INCLUDE伪指令达到共享的目的呢?需要预先做一项准备工作:把要共享的宏指令单独组织成一个文件(注意:只编辑不汇编),存放在指定的目录下,然后在调用模块中用INCLUDE伪指令说明即可。,3另一种编程方法采用宏指令共享技术,书中的例(P165)将DISP宏指令单独组织成一个文件,文件名为“DISPLAY.MAC”,该文件和主模块文件以及两个子模块文件都存放在同一个目录下,因此,INCLUDE伪指令可以不必写出该文件的盘符和路径。,解法3:共享的宏文件DISPLAY.MACDISPMACROYYXX,VARMOVAH,2MOVBH,0MOVDX,YYXXINT10HMOVAH,9MOVDX,OFFSETVARINT21HENDM;-解法3主模块.486PUBLICBEG,MESG1,MESG2,ENDMESGEXTRNBEG1:NEAR,BEG2:NEARINCLUDEDISPLAY.MACDATASEGMENTUSE16NEQU28DUP()L1DBN,MENU,0DH,0AHDBN,0DH,0AHDBN,1.BeiJing,0DH,0AHDBN,2.NanJing,0DH,0AHDBN,3.RetrunDOS,0DH,0AHDBN,0DH,0AHL7DBN,Chioce(1,2,3):$,MESG1DBWelcomeToBeiJing!$MESG2DBWelcomeToNanJing!$ENDMESGDBpleasestrikeanykey$DATAENDSCODESEGMENTPUBLICUSE16ASSUMECS:CODE,DS:DATABEG:MOVAX,DATAMOVDS,AXMOVAX,2INT10HDISP0500H,L1AGA:DISP0B00H,L7MOVAH,1INT21HCMPAL,3JEEXITCMPAL,1JEBEG1CMPAL,2JEBEG2JMPAGAEXIT:MOVAH,4CHINT21HCODEENDSENDBEG,解法3子模块1.486PUBLICBEG1EXTRNMESG1:BYTEEXTRNNEXT:NEARINCLUDEDISPLAY.MACCODESEGMENTPUBLICUSE16ASSUMECS:CODEBEG1:MOVAX,2INT10HDISP0C1EH,MESG1JMPNEXTCODEENDSEND,解法3子模块2.486PUBLICBEG2,NEXTEXTRNMESG2:BYTEEXTRNENDMESG:BYTEEXTRNBEG:NEARINCLUDEDISPLAY.MACCODESEGMENTPUBLICUSE16ASSUMECS:CODEBEG2:MOVAX,2INT10HDISP0C1EH,MESG2NEXT:DISP171DH,ENDMESGMOVAH,1INT21HJMPBEGCODEENDSEND,5.12.4模块化程序的可执行文件生成方法,模块化程序可执行文件的生成步骤如下:,分别对各个模块进行编辑和汇编生成各自的目标文件(共享的宏文件只编辑不汇编),假设解法3的目标文件为:主模块.OBJ,子模块1.OBJ,子模块2.OBJ。,然后用链接程序进行链接。例如:TLINK主模块子模块1子模块2生成的可执行文件与第一个目标文件同名,本例的可执行文件为主模块.EXE。,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!