汇编语言程序设计实验报告学院:计算机科学与技术专业:计算机科学与技术班级:计科131姓名学号实验组实验时间指导教师肖敏成绩实验项目名称实验五:8086汇编语言子程序程序设计实验目的熟悉子程序的设计方法实验原理对汇编源程序进行汇编、链接,在Debug环境下完成调试和运行。实验内容1、熟悉子程序的结构及注意事项2、掌握子程序的设计、调试方法实验环境1.硬件:微型计算机1台2.软件:MASM软件实验步骤实验一.使用子程序设计编程实现求数组ARY元素之和:编辑下面的源程序到文件lab5.asm中:CODESEGMENTORG100HASSUMECS:CODE,DS:CODE,SS:CODEMAINPROCFARMOVAX,CODEMOVDS,AXMOVTABLE,OFFSETARYMOVTABLE+2,OFFSETCOUNTMOVTABLE+4,OFFSETSUMMOVBX,OFFSETTABLECALLPROADDMOVAX,4C00HINT21HMAINENDPPROADDPROCNEARPUSHAXPUSHCXPUSHSIPUSHDIMOVSI,[BX]MOVDI,[BX+2]MOVCX,[DI]MOVDI,[BX+4]XORAX,AXNEXT:ADDAX,[SI]ADDSI,2LOOPNEXTMOV[DI],AXPOPDIPOPSIPOPCXPOPAXRETPROADDENDPARYDW1,2,3,4,5,6,7,8,9,10COUNTDW10SUMDW?TABLEDW3DUP(?)CODEENDSENDMAIN使用相应的文本编辑器建立文件LAB5.asm,内容如上所示。二.生成可执行文件:1.汇编:C:\masmmasmlab5;2.连接:C:\masmlinklab5;三.请写出此程序中的变量ary,count,sum的EA,并判断此程序的功能:四.用debug调试此程序时,第一条指令的段内EA是多少?此程序数据段内偏移地址为0的字单元数据为多少?其对应的机器指令是什么?-L;加载程序文件lab5.exe-R;查看IP与CS寄存器的内容-DDS:0;查看当前数据段内偏移地址为0的字单元数据-U;查看机器指令实验二:编写一个子程序,实现在屏幕的指定位置,用指定颜色,显示一个用0结尾的字符串源程序如下datasegmentstrdb'displaystring',0dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovdh,8movdl,21movcl,3movsi,offsetstrcallshow_strmovax,4c00hint21h;----------------------------show_strprocnearpushaxpushcxpushdxpushespushsipushdimovax,0b800hmoves,axdecdhmoval,160muldhadddl,dlmovdh,0;计算显示在屏幕位置addax,dxmovdi,axmovah,clx:movcl,ds:[si]movch,0jcxzfmoval,clmoves:[di],axincsiincdiincdijmpxf:popdipopsipopespopdxpopcxpopaxretshow_strendp;------------------------codeendsendstart实验三:编写一个子程序,实现将word型数据以十进制形式显示出来源程序如下:assumecs:codedatasegmentdb10dup(0)dataendsstacksegmentdb16dup(0)stackendscodesegmentstart:movax,datamovds,axmovax,stackmovss,axmovsp,16movdx,0c1hmovax,76f3hmovsi,0calldwtocmovdh,8movdl,3movcl,2callshow_strmovah,01hint21hmovax,4c00hint21h;子程序:dwtoc;功能:将dword型数据转变成表示十进制的字符串,字符串以0结尾;参数:(ax)=dword型数据的低16位;(dx)=dword型数据的高16位;ds:si指向字符串首地址;返回:无dwtoc:movcx,0pushcxs_dwtoc:movcx,10;除数calldivdw;余数在cx中addcx,30hpushcx;保存余数的ASCII形式;判断是否商为0,如果高低16位都为0,则返回movcx,dxjcxzok_dxz;;高位不为0,则直接跳回,继续执行运算jmpshorts_dwtoc;商的高位为0ok_dxz:movcx,axjcxzok_axzjmpshorts_dwtoc;商的低位为0ok_axz:;赋值到ds:[si]movdx,si;保存si,si为字符串的首地址loop_dtoc:popcxmovds:[si],cljcxzend_dwtocincsijmpshortloop_dtocmovsi,dxend_dwtoc:movsi,dxretdtoc:;先把一个0放进堆栈,在后面s2从堆栈中取出的时候,可以根据cx为0跳转movcx,0pushcxs1_dtoc:movdx,0movcx,10divcxmovcx,dx;dx余数addcx,30hpushcx;保存在堆栈movcx,ax;ax为商,当商为0的时候,各位的值就已经得到了,就可以跳出循环jcxzok1_dtocjmpshorts1_dtocok1_dtoc:movch,0s2_dtoc:;从堆栈中取出popcxjcxzok2_dtocmovds:[si],clincsijmpshorts2_dtocok2_dtoc:retshow_str:pushaxpushbxpushcxpushdxpushespushsi;计算好字串开始显示的地址Y=160*(行数-1)+列数*2-2,B800:Y;循环将参数里的字串写进显卡内存,并检测到0就返回;bx=160*(行数-1)movbh,dhsubbh,1moval,160mulbhmovsi,ax;si为根据行数算出来的偏移值;ax=列数*2-2movbl,dlmoval,2mulblsubax,2;根据列数算出来的偏移值addsi,ax;行数和列数的和存在SI中了movax,0b800hmoves,axmovbx,si;将si的值保存在bx中,bx为显存显示偏移值movsi,0;题目要求。。。movdl,cl;保存字体颜色属性movch,0s:movcl,ds:[si]moves:[bx],cljcxzokmoves:[bx+1],dlincsiaddbx,2jmpshortsok:popsipopespopdxpopcxpopbxpopaxret;子程序:divdw;要求:进行不会除法溢出的除法运算,被除数为dword,除数为word,结果为dword;参数:(ax)=被除数dword型的低16位;(dx)=被除数dword型的高16位;(cx)=除数;返回:(dx)=结果的高16位;(ax)=结果的低16位;(cx)=余数divdw:movbx,ax;缓存ax——被除数的低16位movax,dx;ax=H,被除数的高16位movdx,0divcx;ax为商,dx为余数=rem(H/N)*65536pushax;结果的商,也就是最后要放在dx中的movax,bx;dx为rem(H/N)*65536,为高16位,ax为低16位,再进行一次除法运算divcx;ax为商——最后结果的低16位,dx为余数——为最后结果,应赋给cxmovcx,dxpopdxretcodeendsendstart实验结果实验一:变量ary,count,sum的EA分别是00140,00154,00156此程序的功能是数列求和实验二:实验三:实验总结这次实验,感觉难度最大的就是做2个子程序的设计,在网上向好友请教了N回!还犯了一些低级的错误,如将16位的寄存器的内容传送到字符型数字串里去,这很明显是不对的,在逆序时寄存器的高16位会直接把正常的数字字符冲掉,还有就是将当我直接将字型单元的内容传送字型单元时,编译器会报错,不过提示是它后面的指令错误。转换后的数字串的末尾如果不是0的话,在调用输出子程序时会出现BUG,于是又在转换子程序里加了条指令,在第一次转换出来后,在数字串的末尾添加一个终止标志0。指导教师意见签名:年月日