实验六子程序设计实验一、实验目的1.掌握过程调用指令与过程返回指令的用法;2.掌握主程序与子程序之间的参数传送方法;3.掌握调用子程序时堆栈的变化情况及利用压栈、出栈保护现场的方法;4.掌握嵌套及递归子程序的设计方法。二、实验要求1.仔细阅读教材中有关子程序设计的章节;2.学会编写子程序说明文件;3.学会设置断点检查堆栈指针的变化及堆栈内容;4.学会用DEBUG中的P命令调试子程序;5.学会在子程序设计中保护所用到的寄存器。三、实验内容1.采用一般子程序设计方法和递归子程序设计方法,编写计算Xn的子程序要求:X值与n值由键盘输入,计算结果以十六进制形式在屏幕上显示。2.编写程序,完成一位十六进制数的加、减、乘、除运算。要求:从键盘输入参加运算的一位十六进制数,运算结果以十六进制形式在屏幕上显示,加、减、乘、除运算要用子程序编写。四、解题思路1.对于实验内容1,X值和n的值可以利用INT21H的1号功能从键盘上输入,计算结果利用INT21H的2号功能从键盘上输出。可以用递归子程序实现Xn(次幂)的计算;2.对于实验内容2,键盘输入的数和运算符号,输入的运算符号和’+’,’-’,’*’,’/’比较,与那个符号相等就转去执行相应的子程序。子程序的结果可以都把出口条件设置为相同的寄存器,这样便于程序输出结果。五、编程实现5.1内容1子程序说明文件如下:(1)子程序名:CIMI;(2)子程序功能:计算X^n;(3)入口条件:X的值放在DL中;(4)出口条件:X^n值在AX中;(5)受影响的寄存器:AX,BX和标志寄存器F。程序清单如下:DSEGSEGMENTRLTDW0DSEGENDSSSEGSEGMENTSTACKSKTOPDB100DUP(0)SSEGENDSCSEGSEGMENTASSUMECS:CSEGASSUMEDS:DSEGASSUMESS:SSEGSTART:MOVAX,DSEGMOVDS,AXMOVAX,SSEGMOVSS,AXMOVSP,SIZESKTOPMOVAH,01H;输入XINT21HSUBAL,30HMOVDL,AL;保存X在DL中PUSHDXMOVDL,'^';输出符号‘^’MOVAH,02HINT21HPOPDXMOVAH,01H;输入nINT21HSUBAL,30HMOVBL,AL;保存n在BL中XORBH,BH;BH清零PUSHDXMOVDL,'=';输出‘=’号MOVAH,02HINT21HPOPDXMOVAL,DL;默认的入口条件AL存X数据CALLCIMI;调用子函数MOVRLT,AX;保存结果在RLT单元MOVBL,AL;保存结果便于输出MOVBH,ALMOVCL,4SHRBH,CLMOVDL,BH;输出结果高四位CMPDL,9JNASHU1ADDDL,7SHU1:ADDDL,30HMOVAH,02HINT21HMOVDL,BL;输出结果低四位ANDDL,0FHCMPDL,9JNASHU2ADDDL,7SHU2:ADDDL,30HMOVAH,02HINT21HMOVAH,4CHINT21HCIMIPROCNEAR;子程序清单ANDBX,BXJZCIMI1DECBXCALLCIMI;递归调用MULDLRETCIMI1:MOVAL,1RETCIMIENDPCSEGENDSENDSTART运行结果如下如图6-1图5-1内容1的运行结果5.2实验内容2子程序设计思路:设计四个子程序,分别完成两数相加、相减、相乘、相除的功能。子程序说明文件1:(1)子程序名:JIA;(2)子程序功能:计算两个数a,b之和;(3)入口条件:a的值放在BH中,b的值放在BL中;(4)出口条件:结果值在AL中;(5)受影响的寄存器:AX,BX。子程序说明文件2:(1)子程序名:JIAN;(2)子程序功能:计算两个数a,b之和;(3)入口条件:a的值放在BH中,b的值放在BL中;(4)出口条件:结果值在AL中;(5)受影响的寄存器:AX,BX。子程序说明文件3:(1)子程序名:CHENG;(2)子程序功能:计算两个数a,b之和;(3)入口条件:a的值放在AL中,b的值放在BL中;(4)出口条件:结果值在AL中;(5)受影响的寄存器:AX,BX。子程序说明文件4:(1)子程序名:CHU;(2)子程序功能:计算两个数a,b之和;(3)入口条件:a的值放在AX中,b的值放在BL中;(4)出口条件:结果值在AL中;(5)受影响的寄存器:AX,BX。程序清单如下:DSEGSEGMENTRLTDW0DSEGENDSSSEGSEGMENTSTACKSKTOPDB100DUP(0)SSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGASSUMESS:SSEGSTART:MOVAX,DSEGMOVDS,AXMOVAX,SSEGMOVSS,AXMOVSP,SIZESKTOPMOVAH,01HINT21HSUBAL,30HMOVBH,AL;输入第一个数据保存在BH中MOVAH,01HINT21HMOVCH,AL;输入符号保存在CH中MOVAH,01HINT21HSUBAL,30HMOVBL,AL;输入第二个数据保存在BL中CMPCH,'+';输入的是‘+’转JZJIA1CMPCH,'-';输入的是‘-’转JZJIAN1CMPCH,'*';输入的是‘*’转JZCHENG1CALLCHU;否则认为是输入‘/’顺序执行JMPOUT1JIA1:CALLJIAJMPOUT1JIAN1:CALLJIANJMPOUT1CHENG1:CALLCHENGJMPOUT1OUT1:MOVCL,04HMOVBH,ALMOVBL,ALMOVDL,'=';输出‘=’MOVAH,02HINT21HSHRBH,CLMOVDL,BHADDDL,30H;输出结果高四位MOVAH,02HINT21HANDBL,0FHMOVDL,BL;输出结果低四位ADDDL,30HMOVAH,02HINT21HMOVAH,4CHINT21HJIAPROCNEAR;子程序JIA实现两数相加ADDBH,BLMOVAL,BHRETJIAENDPJIANPROCNEAR;子程序JIAN实现两数相减SUBBH,BLMOVAL,BHRETJIANENDPCHENGPROCNEAR;子程序CHENG实现两数相乘MOVAL,BHMULBLRETCHENGENDPCHUPROCNEAR;子程序CHU实现两数相除MOVAL,BHXORAH,AHDIVBLRETCHUENDPCSEGENDSENDSTART运行结果如图5-2:图5-3内容2运行结果六、实验总结遇到的问题1.实验内容以十六进制输出结果时,大于9的数和小于9的数的输出有区别,这里我用了一个有条件跳转语句实现该功能;2.第一道题用递归子函数编写的,比较简单。但是开始时我在加入显示’^’,’=’的时候,没有保护AL中的内容,以至于后面运行结果出乱。