微机原理与接口技术:11第4章 汇编语言程序设计4.5 习题4_第1页
微机原理与接口技术:11第4章 汇编语言程序设计4.5 习题4_第2页
微机原理与接口技术:11第4章 汇编语言程序设计4.5 习题4_第3页
微机原理与接口技术:11第4章 汇编语言程序设计4.5 习题4_第4页
微机原理与接口技术:11第4章 汇编语言程序设计4.5 习题4_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

交通信息与控制工程系教案(理论教学用)课程名称微机原理与接口技术第11次第5周2学时上课教室WM1310课程类型专业基础课授课对象自动化专业章节名称4.5.4程序设计举例教学目的和要求了解简单的汇编语言程序设计概念;了解顺序程序、多分支程序、循环程序和子程序设计。了解使用汇编语言设计数值计算的程序设计;了解多模块程序设计的基本概念;了解软件实验内容以及过程。讲授主要内容及时间分配程序设计概念;(25min)顺序程序设计;(15min)多分支程序设计;(20min)循环程序设计;(15min)子程序设计。(15min)数值分析;(35min)多模块程序设计;(40min)软件实验的介绍;(15min)教学重点与难点重点:1.简单的汇编语言程序设计概念;2.顺序程序、多分支程序、循环程序和子程序设计。难点:1.顺序程序、多分支程序、循环程序和子程序设计。重点:1.数值分析程序的汇编语言程序设计;2.多模块程序设计。难点:1.多模块程序设计。要求掌握知识点和分析方法了解简单的汇编语言程序设计概念;掌握顺序程序、多分支程序、循环程序和子程序设计。启发与提问汇编语言与C语言在程序设计上的异同?使用汇编程序设计牛顿迭代法计算方程解的原理是什么?多模块程序设计方法与单模块程序的主要区别?教学手段多媒体作业布置思考题:1.如何使用多重循环设计排序程序?主要参考资料备注注:教案按授课次数填写,每次授课均应填写一份。重复班授课可不另填写教案。长安大学讲稿(第十一讲)讲授内容如何读懂简单的汇编程序。判断下面程序段的功能:DatSegmentD1DB‘ABCDEFG’DatENDSCODESEGMENTASSUMECS:CODE,DS:DatSTART:MOVAX,DatMOVDS,AXLEABX,D1MOVCX,6NEXT:MOVAL,[BX]XCHGAL,DLMOVAH,2INT21HLOOPNEXTMOVAH,4CHINT21HCODEENDSENDSTART程序设计的一些编程技巧表处理程序设计表的处理表的用途十分广泛:求平方值、立方值需要使用平方值表和立方值表,程序实现分支要用到跳转表等。对表的处理通常包括查询、插入、删除、排序等几个方面。将一新的内容插入到表中某个单元以前或以后,需要先将插入位置以后的数据后移,然后再将数据插入,同时表元素的个数也应做相应的修改(增加);需要将表中某些内容删除时,为保持表的完整,应将被删内容以后的数据前移,并修改表元素个数。例数据或程序的加密和解密。为了使数据能够保密,可以建立一个密码表,利用XLAT指令将数据加密。程序接收键入的一个数字,如果是0~9之间的一个数,加密后存入MIMA单元。密码表可选择为原数字:0,1,2,3,4,5,6,7,8,9密码数字:7,5,9,1,3,6,8,0,2,4加密程序描述如下:DATA SEGMENTMITAB DB'7591368024';加密密码表CONT EQU$-MITABJMITAB DB'7384915062';解密密码表MIMA DB?DATA ENDSCODE SEGMENTASSUME CS∶CODE,DS∶DATASTAR:MOV AX,DATAMOV DS,AXMOV AH,1INT 21HAND AL,0FHLEA BX,MITABXLAT MITABMOV MIMA,ALCODEENDSENDSTAR解密程序如何编写?2.查找、排序应用举例例有一个100个字数据组成的数据表,其元素已按从小到大的顺序排列好了。现要求在此表上进行查找元素,具体的规则是:若表内有此元素,则结束;否则,按顺序将此元素插入表中的适当位置上并修改表长。当发现表中无此元素时,应将其插在表中的适当位置上,即插在大于(或等于)前一个元素且小于(或等于)后一个元素的位置上,并将其后的元素依次后移。DATA SEGMENTLTH DB100 ;数据表长TAB DW5FH,…,?;有序数据表TEH DW'X' ;设给定的元素是XDATA ENDSSTACK SEGMENTPARASTACK'STACK'DB 100DUP(?)STACK ENDSCODE SEGMENTASSUME CS∶CODE,DS∶DATA,ES:DATASYART:MOV AX,DATAMOV DS,AXMOV ES,AXMOV BX,OFFSETTAB;BX指向数据表MOV AX,TEM ;取出给定的元素MOV CX,LTH ;取出表长的值LOP: CMPAX,[BX];在表中进行查找 JE SOP;若找到,则转SOP JL INST;若给定元素小于表内元素,转INST插入 INC BXINC BX LOOPLOP MOV[BX],AL;给定元素始终大于(或等于)表内元素 JMP JUST;应将给定元素插在表的末尾INST:MOVAH,[BX];取出表中元素暂存于AH MOV[BX],AL;插入给定的元素 INC BXPUSHBXINCBXPUSHCXINCBXK:PUSH[BX]K1:POP[BX]INCBXINCBXINCBXINCBXLOOPKLOOPK1POPCXPOPBXMOV[BX],AX;插入给定的元素JUST: INCLTHCODEENDS END START例顺序查找法。如果要查找的内容与表之间没有什么规律可循,则只好从表首开始逐个比较、查找,即采用顺序查找(SequentialSearch)的方法。顺序查找的查找过程为:从表中第1个记录开始,逐个进行记录的关键字和给定值的比较,若某个记录的关键字和给定值比较相等,则查找成功,找到所查记录;反之,若直至最后一个记录,其关键字和给定值都不等,则表明表中没有所查记录,查找不成功。设一组数据存放在内存以SSEG为首址的连续单元中,用DB定义,可描述如下:SSEGDB40H,79H,24H,30H,33H,1AH,0EH根据上述顺序查找的基本思想,可写出如下的程序:SEQ_DATASEGMENTSSEGDB40H,79H,24H,30H,33H,1AH,0EH,6DH,87H,9BH;定义数据表XXDB?;设定待查找的元素SEQ_DATAENDSSTACKSEGMENTPARASTACK'STACK' DB100DUP(?)STACKENDSSEQ_CODESEGMENT ASSUMECS:SEQ_CODE,DS:SEQ_DATA ASSUMEES:SEQ_DATA,SS:STACKSEARCHPROC FARSTART:MOV AX,SEQ_DATAMOV DS,AX MOVAL,XX;设任给的数据元素在XX单元中 MOVCX,10H;取表长 MOVBX,OFFSETSSEG;BX指向表的首地址 MOVAH,0LOP1:CMPAL,[BX] JE AT INC AH INC BX L00P L0P1 MOVAL,0FFH;若查找不到,0FFH送ALRETAT: MOVAL,AH;查找到时,AH中为对应的十六进制数RETSEARCH ENDPSEQ_CODE ENDS ENDSTART例折半查找法。折半查找(BinarySearch)的查找过程是:对一个有序表,先确定待查记录所在的范围(区间),然后逐步缩小范围直到找到或找不到该记录为止。如已知如下11个数据元素的有序表:(02,11,17,20,35,51,60,77,83,89,97)现要查找关键字为20和85的数据元素。假设指针L和H分别指示待查元素所在范围的下界和上界,指针M指示区间的中间位置,即M=[(L+H)]/2。在此例中,L和H的初值分别为1和11,即[1,11]为待查范围。查找K=85的过程:0211172035516077838997↑L↑M↑HBUF[M]<K,令L=M+1:0211172035516077838997↑L↑M↑HBUF[M]<K,令L=M+1:0211172035516077838997↑L↑H ↑MBUF[M]>K,令H=M-1:0211172035516077838997↑H↑L此时,因为下界L大于上界H,则说明表中没有关键字等于K的元素,查找不成功。从上述例子可见,折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等于给定值或者查找区间的大小小于零时(表明查找不成功)为止。NAME BINARY_SEARCHIHGBUF_DAT SEGHENTBUFFER DB02,11,17,20,35,51,60,77,83,89,97COUNT EQU$-BUFFER;存放查找次数或未找到标记PTRN DW?CHAR EQU‘20';关键字'A'BUF_DAT ENDSCODESEGMENTASSUME CS∶CODE,DS∶BUF_DATSTART: MOV AX,BUF_DAT MOV DS,AX MOV ES,AX MOV SI,OFFSETBUFFER ;区间上限送SI MOV CX,COUNT MOVDX,1;记录查找次数 MOV AX,SI ADD AX,CX ;最后一个数的地址加1 MOV DI,AX ;下限送DI MOV AL,CHARCONTL:MOV BX,SI ADD BX,DI SHR BX,1 ;BX中为M CMP AX,[BX] ;关键字与BUF[M]比较 JZ FOUND ;找到转FOUND PUSHF ;保护标志CMP BX,SI ;M=上限否JZ NOFID ;相等未找到POPFJL LESS ;关键字<BUF[M]MOV SI,BX ;M作上限JMP NEXTLESS:MOV DI,BX ;M作下限NEXT:INC DX ;查找次数加1JMP CONTLNOFID:MOV DX,0FFFFH;未找到标记设为0FFFFHFOUND:MOV AX,DX MOV PTRN,AX;结果送PRTN单元CODEENDSENDSTART代码转换程序将ASCII表示的数转换为二进制码。ASCII码存放在以ASC为首地址的内存单元,转换结果在Binary。“0-9””A-F“相应的ASCII是41H-46H“0-9””A-F“相应的ASCII码减去37H同时要判断数据区数据是否在相应的范围内。DATASEGMENTASCDB‘2’,’B’,’A’,’6’,9’,NumDB6BinaryDB6DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS,CODESTART:MOVAX,DATAMOVDS,AXMOVCX,0MOVCL,NumPUSHCXMOVSI,OFFSETASCMOVDI,OFFSETBinaryMOVAX,0MOV,DX,0CLDK1:LODSMASC;装入一个ascii码进入ALCMPAL,’0JLERROR;小于0,跳转CMPAL,’9JGK2;大于9跳转SUBAL,30HJMPK3K2:CMPAL,’A’JLERROR;小于’A’,跳转CMPAL,’F’JGERROR;大于F,跳转SUBAL,37HK3:STOSBCODEENDSENDBIGIN让学生判断对错,并增加,删除错误的语句。例将从键盘输入的ASCII码转换成压缩的BCD码存储。在微机中,从键盘上输入的十进制数的每一位数码(即0~9中任一个),都是以它的ASCII码表示的;要向CRT输出的十进制数的每一位代码也是用ASCII码表示的。十进制数的ASCII码转换为BCD码的方法是把高4位变为0;若是以组合方式存储转换后的BCD码,则要把两位并在一个存储单元中,可将地址高的字节左移4位,再与地址低的字节组合在一起。程序描述如下:DATASEGMENTASCBUFDB20,0,20,DUP(?)BCDBUFDB20DUP(?)DATAENDSSTACKSEGMENTPARASTACK'STACK'STAPNDB100DUP(?)STACKENDSCOSEDSEGMENTASSUMECS∶COSEG,DS∶DATA,ES∶DATA,SS∶STACKStart:MOVAX,DATAMOVDS,AXMOVDX,OFFSETASCBUF MOVAH,0AHINT21H MOVSI,OFFSETASCBUF MOVDI,OFFSETBCDBUFMOVCX,ASCBUF+1;实际读入的字符数 RORCX,1 ;右移最低位进CF,若数据个数为偶数则转移 JNCNEXTROLCX,1 LODSB ;取一数进AL,指针SI+1 ANDAL,0FH ;转换成BCD码STOSB ;送入内存单元,DI+1 DECCX ;数据个数减1 RORCX,1 ;数据个数除2NEXT:LODSBAND,AL,0FHMOVBL,AL ;转换一个ASCII码到BCD码LODSBPUSHCX ;保护CL的内容AND,AL,0FHMOVCL,4SALAL,CL;再转换一个ASCII码到BCD码存入高四位POPCXADDAL,BL;两个BCD码合为一个字节STOSBLOOPNEXT;CX-1,CX≠0转NEXT,重复,直到CX=0结束COSEENDSENDGO需要说明的是,输入缓冲区中,已存放的ASCII码的个数可能是偶数,也可能是奇数。若是奇数,则先把地址最低的一个ASCII码转换为BCD码(高四位为0),然后把剩下的偶数个ASCII码按统一的方法处理。程序中的指令RORCX,1的作用是用于判断已存放的ASCII码的个数是否奇偶。具体方法是将CX的最低位右移进CF,若CF=0,则为偶数,否则为奇数。例BCD码转换成ASCII码。BCD码的十进制数在CRT上显示时,首先应将其转换为ASCII码。下述程序自动在CRT上输出1~98之间的十进制数。由于是显示1~98之间的数,因此,不论是哪一个数,其数字均在0~9之间,而不会出现A~F的情况。BCD码转换成ASCII码采用的是BCD码+30H的方法。STACKSEGMENTPARASTACK'STACK'STPDB100DUP(?)STACKENDSDATASEGMENT;定义缓冲区BUFRDB3DUP(?)DATAENDSCOSEGSEGMENTASSUMECS∶COSEG,DS∶DATA,ES∶DATASTART:MOV AX,DATAMOVDS,AXMOVBL,0GOON:MOV SI,OFFSETBUFMOV DL,0DH ;输出回车MOV AH,2INT 21HMOV DL,0AH ;输出换行MOV AH,2INT 21HMOV AL,BL ;产生0~98之间的数据INC ALDAA CMP AL,99H JNC OVER;若数字大于98,结束程序 MOV BL,AL PUSH BX;保护BL,以便下个循环在此数上加1 MOV DL,AL;暂存入DL,以备转成ASCII码用 MOV CL,4 SHR AL,CL;右移四次 OR AL,30H;高位十进数转成ASCII码 MOV [SI],AL;存到缓冲区 INC SI MOV AL,DL;恢复原十进制数 AND AL,0FH OR AL,30H ;低位十进制数转成ASCII码 MOV [SI],AL INC SI MOV AL,'$' MOV [SI],AL ;'$'存入缓冲区,9号调用要求的 MOV DX,OFFSETBUFR MOV AH,9 INT 21H ;缓冲区数据输出显示 MOV CX,0FFFFHAGN:DEC CX ;延时后再显下一个数JNE AGNJMP GOONOVER:COSEGENDSEND START例二进制数转换为ASCII码,设CX寄存器中有一个带符号的二进制数,现将其以十进制形式输出到CRT。CX中的数是十六进制数,所表示的数的范围在-32768~+32767之间。程序应先检查CX中数的符号位,以决定输出“+”或“-”。若是负数,应先求补,得到原码,然后再将其转换为十进制数。转换的思路:转换方法是先将其减10000,看其中包含几个10000,那么它的十进制数的万位数字就是包含的一万的个数,不够减时再用余下的数减1000,统计其中包含1000的个数,得到千位上的数字,依此类推,求出百位、十位的数字,剩下的就是个位数字了。转换后的十进制数在缓冲区的存放格式如图9-1所示。有了十进制数字后,要在CRT显示出来,还要将其转换成ASCII码才能输出。程序描述时采用子程序的形式:DATASEGMENTCOUNTDW0F1DBHBUFDB9DUP(?)DATAENDSSTACKSEGMENTPARASTACK'STACK'DB100DUP(?)STACKENDSCOSGESEGMENTASSUMECS:CODE,DS:DATA,ES:DATA,SS:STACKSTARTPROC FARMOV AX,DATAMOV DS,AXMOV ES,AXMOV CX,COUNT;CX中为待输出的二进制数CALL PTDNRETSTARTENDP;在显示器上输出16位二进制带符号数的子程序;入口参数:CX中为待输出的数据;所用子程序:CHANGPTDNPROCPUSHAXPUSHBXPUSHDXPUSHSI ;保护现场MOV BX,OFFSETBUF ;BX指向缓冲区MOV AL,0DHMOV [BX],AL;回车符存入缓冲区以便显示时回车INC BXMOV AL,0AHMOV [BX],AL;换行符存入缓冲区INC BXMOV AL,CHOR AL,AL;查看符号位JNS PLUS ;正数转PLUS NEG CX ;负数求补MOV AL,'-' MOV [BX],AL;缓冲区存入负号JMP GOONPLUS:MOV AL,'+' MOV [BX],AL;缓冲区存入正号GOON:INC BXMOV SI,10000CALL CHANG;求万位数,并转换为ASCII码存入缓冲区 MOV SI,1000 CALL CHANG;求千位数 MOV SI,100CALL CHANG;求百位数MOV SI,10CALL CHANG;求十位数MOV AL,30HADD AL,CLMOV [BX],AL;求个位数INC BXMOV AL,'$' ;$送入缓冲区尾,9号功能调用所要求MOV [BX],ALMOV DX,OFFSETBUF MOV AH,9;9号功能调用输出显示 INT 21H POP SI POP DX POP BX ;恢复现场 POP AX RETPTDNENDP;本子程序统计CX寄存器所包含权(在SI中)的个数,并把这个个数转换成;ASCII码;入口参数:SI为权码,CX中为给定的数,BX指向ASCII码结果缓冲区;出口参数:结果缓冲区的当前单元存放转换完的ASCII码,并且调整BX指;向缓冲区的下一个单元CHANGPROC MOV DL,0 ;DL存放权的个数,初值0AGAIN:SUB CX,SI JC DOWN ;不够减转DOWN INC DL ;够减DL加1 JMP AGAIN ;再减权DOWN:ADD CX,SI;恢复CX MOV AL,30H ADD AL,DL MOV [BX],AL;转ASCII码并存入缓冲区 INC BX;指针调整 RETCHANGENDPCODE ENDS ENDSTART用汇编语言编写数值分析程序数值分析二分法求解方程例用二分法求方程x3-x-1在区间[0,10]内的一个实根,精度为1。基本思想:设函数f(x)在区间[a,b]上连续,且f(a).f(b)<0,根据连续函数的性质可知方程f(x)=0在[a,b]内一定有实根,并称[a,b]为方程f(x)=0的有根区间。为明确起见,不妨假定它在[a,b]内有惟一的实根x*。把区间[a,b]二等分,分点为x0=(a+b)/2,计算函数值f(x0),如果f(x0)=0则实根为x0=(a+b)/2,否则,f(x0)或者与f(a)异号,或者与f(b)异号。如f(x0)f(a)<0说明根在区间[a,x0]内,这时取a1=a,b1=x0如f(x0)f(b)<0说明根在区间[x0,b]内,这时取a1=x0,b1=b不管出现哪一种情况,新的有根区间[a1,b1]的长度为原有根区间[a,b]的一半。在新的有根区间[a1,b1]上重复上述二分步骤,得下列有根区间序列其中,每个区间仅为前一个区间的一半,二分k次以后的有根区间[ak,bk]的长度是在实际应用中,一般令有根区间[ak,bk]的中点x0=(ak+bk)/2,为x*的近似值,则在二分过程中,得到下列以x*为极限的近似根序列x0,x1,…,xk由于对于预先给定的精度,只要这时,xk就是满足精度要求的近似值。程序描述如下:DATA SEGMENTAREAL DB0AREAH DB10HELP DB'ROOTX=$'DISP DB10DUP(?)DATA ENDSSTACK SEGMENTPARASTACK'STACK' DB100DUP(?)STACK ENDSCODE SEGMENT ASSUMECS∶CODE,DS∶DATA,ES∶DATA,SS∶STACKSTARTPROC FAR PUSHDS MOVAX,0 PUSHAX MOVAX,DATA MOVDS,AX MOVES,AX MOVAL,[AREAL] ;将区间下限送入AL中 MOVAH,[AREAH] ;将区间上限送入AH中LOP: SUB AH,AL CMP AH,1 ;判断是否已达到精度 JLE EXIT ;达到则结束 ADD AH,AL ;未达到则恢复区间继续使用二分法 MOV BH,AH ADD BH,AL PUSH AX ;保存AX数据 XOR AX,AX MOV AL,BH CBW MOV BL,2 IDIV BL MOV BH,AL ;将区间中点送入BH POP AX ;恢复AX数据 CALL FUNCTION ;求入口参数为AL的函数值,出口参数CL标识函数 ;值的正负 MOV DL,AL ;保存AL数据 MOV DH,CL ;保存CL数据 MOV AL,BH ;求区间中点的函数值 CALL FUNCTION MOV CH,DH CMP CH,CL ;比较两函数值是否同号 JZ NEXT1 MOV AL,DL ;不同号则修改区间上限 MOV AH,BH JMP LOPNEXT1: MOV AL,BH ;同号则修改区间下限 JMP LOPEXIT: PUSH AX MOV DX,OFFSETHELP MOV AH,09H INT 21H POP AX CBW ;将区间下限扩展为16位数 XOR CX,CX MOV CX,AX CALL PTDN ;显示结果 RETSTARTENDP输出16位二进制带符号数的子程序PTDN与例完全一样,这里不再赘述;输出函数函数值正负的子程序;入口参数:AL为自变量;出口参数:CL为1表示函数值为负;反之为正FUNCTIONPROCPUSH AXPUSH BXPUSH DXCBWMOV BX,AX ;保存AX的值IMUL AX ;求的值IMUL BXSUB AX,BXSUB AX,1MOV CX,AX ;将结果送入CXROL CX,1 ;保存函数值的符号位AND CX,01HPOP DXPOP BXPOP AXRETFUNCTION ENDPCODEENDSENDSTART牛顿法求解方程例用牛顿法求方程x3-x-1=0在附近的一个实根,精度为1。基本思想:牛顿法是方程求根问题的一个极其基本的、十分重要的算法,它的基本思路是将非线性方程f(x)=0逐步线性化而形成迭代公式。设已知方程f(x)=0的近似根xk,将函数f(x)在点xk处作一阶泰勒展开,则有于是方程f(x)=0可近似地表示为上式是个线性方程,记其根为xk+1,则xk+1就可理解为方程的一个新的近似根,即这就是著名的牛顿迭代公式,相应的迭代函数是程序描述如下:DATA SEGMENTAREAL DB0AREAH DB10HELP1 DB'ROOTX=$'HELP2 DB'SIMPLEITERATIVEFAILED!$'HELP3 DB0AH,0DH,'PRESSANYKEYTOQUIT!$'DISP DB10DUP(?)DATA ENDSSTACK SEGMENTPARASTACK'STACK' DB100DUP(?)STACK ENDSCODE SEGMENT ASSUMECS:CODE,DS:DATA,ES:DATA,SS:STACKSTARTPROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV ES,AX CALL ITERATIVE;调用牛顿迭代子过程 MOV DX,OFFSETHELP3 MOV AH,09H INT 21H MOV AH,07H INT 21H RETSTARTENDP;用牛顿法求方程实根的子程序,并显示最终结果ITERATIVEPROCPUSH AXPUSH BXPUSH CXPUSH DXMOV BX,10 ;赋初值MOV CX,1LOP:MOV AX,BXCALL FUNCTION ;原函数的函数值CALL DFNCTION ;原函数导数的函数值PUSH AXMOV AX,BXMOV BX,DXXOR DX,DXIDIV BX ;两函数值之比POP BXPUSH BXSUB BX,AX ;迭代后自变量的值INC CXCMP CX,10000 ;是否超过规定的迭代次数JZ NORESULTPOP AXSUB AX,BXCMP AX,1 ;是否已小于规定精度JZ RESULTCMP AX,-1 ;是否已小于规定精度JZ RESULT ;结束迭代ADD AX,BXJMP LOPNORESULT:POPAX ;无结果MOV DX,OFFSETHELP2MOV AH,09HINT 21HJMP EXITRESULT:MOV DX,OFFSETHELP1 ;显示最终结果MOV AH,09HINT 21HMOV CX,BXCALL PTDNEXIT:POP DXPOP CXPOP BXPOP AXRETITERATIVEENDP输出16位二进制带符号数的子程序与前例完全一样,这里不再赘述。;求函数函数值的子程序;入口参数:AX为自变量;出口参数:BX为函数值FUNCTIONPROCPUSH AXMOV BX,AXIMUL ALIMUL BLSUB AX,BXSUB AX,1MOV BX,AXPOP AXRETFUNCTIONENDP;求函数导函数函数值的子程序;入口参数:AX为自变量;出口参数:DX为函数值DFNCTIONPROCPUSH AXMOV DX,3IMUL ALIMUL DLSUB AX,1MOV DX,AXPOP AXRETDFNCTIONENDPCODEENDSENDSTART多模块程序设计的基本概念在汇编语言程序设计中,源程序所涉及的标识符(变量、标号、段名和过程名等)都在本程序中定义,它与本程序之外的标识符不发生任何关系,这种程序设计称为单模块程序设计。下面将介绍多模块程序设计方法,也称为模块化程序设计方法。所谓模块,从功能上讲它可以是整个大程序中较为独立的一个部分,从源程序结构形式上讲它是由END结束的一个完整程序。一个源模块可以单独汇编,形成自己的目标模块。最后,由连接程序将各个目标模块连接成一个可执行程序。采用模块化程序设计有下面一些优点:(1)一个复杂程序可以分成若干个模块,可由不同人员分头完成;(2)每个模块的任务明确,便于理解;(3)单个模块易于编写和调试;(4)便于程序的维护和修改;(5)可以直接利用已有的模块。采用模块化程序设计时,必须合理分割模块,严格定义各模块的输入、输出参数和各模块间的通信方式。在单模块程序设计时,模块内所用到的段、变量及标号等各种标识符都必须在本模块内给予定义,否则汇编时将会给出错误信息。多模块程序设计时,由于各个模块都是整个程序的一个部分,因此,各模块之间不仅会有数据上的传递,而且会出现各模块间的变量、标号等标识符的交叉引用。多模块之间段的连接1.SEGMENT语句提供的连接信息段定义的完整语句为段名 SEGMENT[定位类型][组合类型]['类别']段名 ENDS模块间的交叉访问模块间的交叉访问是指一个模块中要引用另一个模块中定义的变量、标号等标识符。例如,主模块中要调用的过程名是在另一个子模块中定义的,子模块中要用到的变量可能是在主模块中定义的。这样,一个源模块中定义的标识符就可能有两类:一类是供本模块使用的,我们称它们为局部标识符;另一类是同时可供本模块和其他模块使用的,我们称这类标识符为外部标识符或全局标识符。那么,如何告诉汇编程序本模块中哪些标识符是全局的(也就是可以被其他模块引用的),哪些标识符是要引用外部的(也就是本模块中没有定义的),以及出现了交叉访问后,汇编语言程序编程又应注意些什么问题。1.伪指令PUBLIC和EXTRN1)伪指令PUBLIC伪指令PUBLIC的功能是指明本模块中所定义的标识符有哪些是可以提供其他模块调用的外部标识符。格式如下:PUBLIC 标识符,标识符,…其中,PUBLIC是伪指令操作码助记符,其后的标识符就是本模块内定义的可供其他模块调用的标识符,它可以是变量名,也可以是标号或过程名。2)伪指令EXTRN伪指令EXTRN的功能是指出本模块中用到的哪些标识符是由其他模块定义的。格式如下:EXTRN 标识符:类型,标识符:类型,…其中,EXTRN是伪指令操作码助记符,其后的标识符就是本模块中要引用的外部标识符。这里,标识符必须指出其类型,这是在汇编时为了生成正确的机器码所必需的。变量的类型可以是BYTE、WORD或DWORD,标号的类型可以是NEAR或FAR。各模块中语句由PUBLIC和EXTRN提供的标识符必须互相呼应。连接时,连接程序将检查各模块中EXTRN语句中的每个标识符是否与PUBLIC语句中的标识符相配合。若EXTRN语句中出现的标识符在PUBLIC语句中找不到,说明该标识符未定义,连接程序将给出错误信息。模块中的外部标识符没有被其他模块引用,这是允许的。此外,模块1与模块2的代码段连接后是一个段,所以,在模块1中要用到的标号EX1虽不在同一模块中,但却是NEAR类型。标号EX2在模块3中定义,连接后它与模块1的代码段不在同一段,因而EX2为FAR类型。【例】模块间交叉定义示例一。语句PUBLIC和EXTRN提供的标识符必须互相呼应。模块1:EXTRN VAR3:WORD,EX1:NEAREXTRN EX2:FARPUBLIC VAR1,VAR2DATA SEGMENTVAR1 DB ?VAR2 DW ?DATA ENDSCODE SEGMENT PUBLIC 'CODE'START:CODE ENDSEND START模块2:EXTRNVAR1:BYTE,VAR2:WORD,VAR5:WORDPUBLIC EX1,VAR3DATA SEGMENTVAR3 DW ?DATA ENDSCODESEGMENTPUBLIC'CODE'EX1: CODE ENDSEND模块3:EXTRN VAR4:BYTEPUBLIC VAR5,EX2DATA SEGMENTVAR5 DW ?DATA ENDSCODE3 SEGMENTEX2L: CODE3 ENDSEND2.调用插入伪指令INCLUDEINCLUDE伪指令用来告诉MASM程序,将语句INCLUDE指出的文件完整地、全部地插入到它所在的位置。该文件是由汇编语言编写的源程序文件,包括宏库文件。语句INCLUDE的格式如下:INCLUDE[驱动器名:][目录路径]文件名.扩展名例如,INCLUDEA:\ASM\WWD.ASM实验一:清零程序一、实验目的

掌握8088汇编语言程序设计和调试方法,熟悉键盘操作。

二、实验内容

把RAM区内4000H-40FFH单元的内容清零。实验二拆字程序一、实验目的

掌握汇编语言设计和调试方法。

2、实验内容

把4000H单元的内容拆开,高位送4001H低位,低位送4002H低位,4001H、4002H的高位清零,一般本程序用于把数据送显示缓冲区时用。实验三数据区移动一、实验目的

掌握RAM中的数据操作二、实验内容

把4100H源RAM区首址内的16字节数据传送到4200H目标RAM区。实验四多分支程序设计一、实验目的

掌握汇编语言的编程,熟悉程序跳转的设计方法。二、实验内容

编写程序,根据送入的数据转移运行。三、设计思想

多分支结构相当于一个多路开关,在程序设计中通常是根据某寄存器或某单元的内容进行程序转移。在设计多分支转移程序时,如果分支太多,则平均转移速度太慢,本实验采用转移地址表实现多分支转移,可以提高平均转移速度。实验五多字节减法运算一、实验目的

掌握汇编语言的编程,熟悉多文件、多模块汇编语言程序设计的方法。二、实验内容

1.编写程序,完成多字节减法运算。要求程序能够显示运算数据和结果数据(以16进制形式)。2.程序采用多文件、多模块的设计方法。整个程序应由4个文件组成,分别为EX2.ASM(主模块)、EX21.ASM(多字节二进制数对16进制数ASCII码转换、显示)、EX22.ASM(多字节减法子程序)、PP2.ASM(回车换行子程序,由主模块的INCLUDE伪指令引用)。习题44.5下面两条语句汇编后,两字节存储单元NUM1和NUM2中的内容分别是多少NUM1DB(12OR4AND2)GE0EH【分析】由于AND优先级高于OR,因此先计算4AND20100AND0010=0000再计算12OR0,结果为12D由于0EH=1110=14DGE(大于等于)运算,12DGE14D,结果为“假”。且可以由DB知道NUM1为字节型逻辑常量,所以NUM1=00HNUM2DB(12XOR4AND2)LE0EH【分析】由于AND优先级高于XOR运算,因此先计算4AND2,结果为0000B再计算12XOR01100XOR0000=1100结果为12.LE(小于等于)运算,12DLE0EH,即12DLE14D,结果为“真”所以NUM2=0FFH答:NUM1=0NUM2=0FFH下列指令执行后,字存储单元DA2中的内容是多少?DA1EQUBYTEPTRDA2DA2DW0ABCDH………………SHLDA1,1SHRDA2,1【分析】DA1EQUBYTEPTRDA2表示DA1等于DA2开始的一个字节单元的内容,其中BYTE为字节,PTR表示强制类型转换DA2DW0ABCDH给DA2分配一个字的存储空间,并初始化为0ABCD,由此可知,DA1则为DA2的低位地址开始的一个字节的内容,即CDH=11001101SHLDA1,1对DA1进行逻辑左移,最高位移入CF,CF=1,最低位补0所以DA1=10011010SHRDA2,1DA2=0ABCDH=1010101111001101对DA2进行逻辑右移,最高位补0,最低位移入CF,CF=10101010111100110答:DA2=55E6H(初始答案55CDH)7.对于下面的数据定义,各条MOV指令单独执行后,有关寄存器的内容是什么?NUMB1DB?NUMB2DW20DUP(?)NUMB3DB“USB”【分析】先画出内存单元分配图示,参考表4-1数值返回运算符的功能(1)MOVAX,TYPENUMB1TYPE表示变量占用存储单元的字节数,这一属性是由数据定义伪指令DB、DW、DD规定的。返回变量的字节数,此处NUMB1为DB,所以等效于MOVAX,1AX=0001H(2)MOVAX,TYPENUMB2等效于MOVAX,2AX=0002H(3)MOVCX,LENGTHNUMB2LENGTH返回变量中所定义的元素个数(CX)<-20,返回DUP前面的数值(4)MOVDX,SIZENUMB2SIZE返回变量所占的总字节数由于NUMB2为字类型,且有20个元素,因此SIZENUMB2的值为40,所以DX=40(5)MOVCX,LENGTHNUMB3LENGTH返回变量中所定义的元素个数USB用ASCII码表示,占用三个字节,即CX=38.假设程序中的数据定义如下:PNUMDW?PNAMEDB16DUP(?)COUNTDD?PLETHEQU$_PNUM问PLETH的值是多少?它表示什么意义?【分析】先画出内存单元分配图示有问题9,程序中如何实现对各个段寄存器和IP、栈顶的初始化?【分析】ASSUME伪操作只是指定某个段分配给哪一个段寄存器,它并不能把段地址装入段寄存器中,所以在代码段中,还必须把段地址装入相应的段寄存器中。但是,代码段不需要这样做,代码段的这一操作是在程序初始化时完成的12.编写程序,不用乘法计算Z=10*X+Y/Y,用移位运算。【解】.modelsmall

.586p

.data

x

db?

y

db?

z

db?

.code

movax,@data

movds,ax

moval,x

movcl,5

salal,cl

;10*x

movbl,y

movcl,4

sarbl,cl

;y/8

addal,bl

;10*x+y/8

movz,al

;move10*x+y/8toz

movah,4ch

int21h

endstart16.编写程序,将自定义的三个符号数X、Y、Z的最大者送入MAX字单元。【解】.modelsmall.586p.dataxDB?yDB?zDB?maxDB?.codemovax,@datamovds,ax;loaddatasegmentmoval,xcmpal,y;comparexandyjnb@f;ifxisnotbelowy,jumptofronttocomparemoval,y;otherwiseyabov

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论