1、山东大学汇编语言上机实验实验五子程序设计2.6显示学生名次表rank编制一个程序,要求接受键盘输入的一个班的学生成绩,并存放于一个50字的grade数组中,其中grade+i保存学号为I+1的学生成绩。然后根据grade中的学生成绩,把学生成绩依次填入50字的rank数组中,其中rank+i的内容是学号为i+1的学生的名次。再按学号顺序把名次从终端上显示出来。本题要做的主要工作和例2.2的内容是完全一样的,只是增加了由用户键入学生成绩及输出学生名次两个部分的内容,因此这三个部分可以用子程序结构来完成。子程序结构划分的层次图如图2.17所示,可以看出,main为主要模块,其下一层的三个模块为程序
2、的三大部分。现将各模块说明如下:1.模块名:main 为总模块输入:从键盘输入一个班的学生成绩输出:显示一个班的学生成绩功能:根据输入的学生成绩,计算并显示学生名次。算法如下:一个学生名次等于成绩高于该学生的人数+1.2.模块名:input输入:以学号为序型键盘输入一个班的学生成绩。各个成绩之间用逗号隔开,最后以回车符号结束。输出:把一个班的学生成绩存入grade数组。功能:接受一个班的学生成绩。调用子模块decibin把键盘输入的一个十进制数转换为二进制数。调用子模块crlf完成回车,换行功能。3.模块名:rankp输入:从grade数组取得一个班的学生成绩。输出:以学号为序计算出该班每个学
3、生的名次存入rank数组。功能:计算一个班的学生成绩。算法为:一个学生的名次等于成绩高于该生的学生人数加1.4,。模块名;output输入:把rank数组取得一个班的学生名次。输出:把一个班的学生名次以学号为序在总端上显示出来。功能:先是一个班的学生名次。调用子模块decibin把键盘输入的一个十进制数转换为二进制数。调用子模块crlf完成回车,换行功能。5:模块名:decilin输入:从键盘输入一个十进制数。输出:把该数转换成二进制数并存入BX寄存器中。功能:从键盘输入一个十进制数转换成二进制数并存入BX寄存器中。6.模块名:crlf输出:向终端发出回车换行符。功能:完成一次回车换行操作。7
4、.模块名:binidec输入:从BX寄存器取得一个二进制数。输出:在终端屏幕显示一个十进制数。功能:把BX寄存器中的二进制数转换为十进制数,并在终端显示出来。调用子模块DCE_DIV用来作除法运算并显示字符。8.模块名:dec_div输入:从BX寄存器中的二进制数除以相应的十的幂,并在屏幕显示一位商。余数保存在BX寄存器中。有了以上的层次图及模块说明,对程序的全貌有了基本了解。在图2.18中,我们给出了除rankp以外的其余各个子程序的程序框图。Rankp的框图与图2.4相同。图2.19是程序清单,图2.20是本例的运行情况。;PROGRAM TITLE GOES HERERank;*data
5、rea segmentgrade dw 50 dup(?)rank dw 50 dup(?)count dw ?mess1 db Grade? $mess2 db 13,10,Input Error!,13,10,$mess3 db Rank: $datarea ends;*prognam segment;-main proc far assume cs:prognam,ds:datareastart:;set up stack for return push ds sub ax,ax push ax;set DS register to current data segment mov ax
6、,datarea mov ds,ax;MAIN PART OF PROGRAM GOES HERE call input call rankp call output retmain endp;-input proc near lea dx,mess1 mov ah,09 int 21h; mov si,0 mov count,0enter: call decibin inc count cmp dl, je store cmp dl,13 je exit2 jne errorstore: mov gradesi,bx add si,2 jmp entererror: lea dx,mess2
7、 mov ah,09 int 21hexit2: mov gradesi,bx call crlf retinput endp;-rankp proc near mov di,count mov bx,0loop1: mov ax,gradebx mov word ptr rankbx,0 mov cx,count lea si,gradenext: cmp ax,si jg no_count inc word ptr rankbxno_count: add si,2 loop next add bx,2 dec di jne loop1 retrankp endp;-output proc
8、near lea dx,mess3 mov ah,09 int 21h; mov si,0 mov di,countnext1: mov bx,ranksi call binidec mov dl, mov ah,02 int 21h add si,2 dec di jnz next1 call crlf retoutput endp;-decibin proc near;procedure to conver decimal on keybd to binary.;result is left in BX register. mov bx,0;get digit from keyboard,
9、convert to binarynewchar: mov ah,1 int 21h mov dl,al sub al,30h jl exit1 cmp al,9d jg exit1 cbw;(digit is now in AX);multiply number in BX by 10 decimal. xchg ax,bx mov cx,10d mul cx xchg ax,bx;add digit in AX to number in BX add bx,ax jmp newcharexit1: retdecibin endp;-binidec proc near;procedure t
10、o convert binary number in BX to decimal;on console screen push bx push cx push si push di mov cx,100d call dec_div mov cx,10d call dec_div mov cx,1d call dec_div pop di pop si pop cx pop bx retbinidec endp;-dec_div proc near;sub_subroutine to divide number in BX yb number in CX; print quotient on s
11、creen mov ax,bx mov dx,0 div cx mov bx,dx mov dl,al;print the contents of DL on screen add dl,30h mov ah,02h int 21h retdec_div endp;-crlf proc near;print carriage return and linefeed mov dl,0ah mov ah,02h int 21h; mov dl,0dh mov ah,02h int 21h; retcrlf endp;-prognam ends;* end start程序框图如下:实验截图如下:实验
12、总结:在复杂的程序设计中,采用模块化结构可以划分功能、分界程序,使得程序有复杂变简单,变清晰。主程序和子程序之间嵌套使用,使得写代码时思路更清楚明白,读代码时方便快捷清晰明了。这点跟高级编程语言类似。而此程序中变量p可以跟踪并控制输入的人数、输名字要预留缓存区、十进制码要和二进制码间相互转换,这些又体现了编程低级语言的特点。学习汇编语言,重要的事掌握如何通过汇编指令和程序来控制计算机各个组成部件工作,完成一系列任务。因此,学习汇编用语言与学习高级语言的不同之处是要学习如何深入到计算机的内部进行控制。通过这次实验,加深了我对汇编语言的理解。每一步的输入、存储、转换、输出,都需要一条条的汇编指令执
13、行。而且每一步都有自己的源和目标的地址,每个数据都有自己的存储空间和地址,我们可以很清晰的“跟踪”每一个数据的变化和地址的转移。实验体会:在复杂的程序设计中,采用模块化结构可以划分功能、分界程序,使得程序有复杂变简单,变清晰。主程序和子程序之间嵌套使用,使得写代码时思路更清楚明白,读代码时方便快捷清晰明了。这点跟高级编程语言类似。而此程序中变量p可以跟踪并控制输入的人数、输名字要预留缓存区、十进制码要和二进制码间相互转换,这些又体现了编程低级语言的特点。学习汇编语言,重要的事掌握如何通过汇编指令和程序来控制计算机各个组成部件工作,完成一系列任务。因此,学习汇编用语言与学习高级语言的不同之处是要
14、学习如何深入到计算机的内部进行控制。通过这次实验,加深了我对汇编语言的理解。每一步的输入、存储、转换、输出,都需要一条条的汇编指令执行。而且每一步都有自己的源和目标的地址,每个数据都有自己的存储空间和地址,我们可以很清晰的“跟踪”每一个数据的变化和地址的转移。2.7 计算工资scremp编写一个程序,接受用户输入的工作时间及工资率,显示计算得到的工资数。本程序有三个部分组成,输入工作时间和工资率,计算工资;显示工资值。在输入输出部分,与例2.6一样,必须考虑自负与数字的装换,以及十进制换二进制,二进制换十进制的问题。除此之外,还应注意到本例中的输入数可能是小数。在这里并不需要使用浮点数格式来进
15、行计算,只是在计算中必须处理小数。我们采用在接受输入数字是记录小数点后的位数,并把两个输入数的小数点后位数之和存放在nodec单元当中。在计算工资的乘法中,并不考虑小数点后的存在,而输出的工资数又只取出小数点后的两位数,因此我们用SHIFT单元记录移位因子,用ADJUST单元记录舍入值。对于不同的NODEC可以分以下情况进行处理。1.NODEC6我们知道,对于16位整数而言,及其允许的最大数是65535,对于NODEC6的数,移位因子将=10000,该数已经超过机器允许的范围,因此本例限制NODEC的值必须6,则作为溢出处理,此时将输出值变为0。2.NODEC=36此时移位因子 SHIFT=(
16、10)nodec2舍入值 ADJUST=1/2SHIFT例如:输入工作时间为8.52,工资率为10.25,则乘机为Product=852X1025=873300移位因子为 shift=(10)nodec2舍入值 ADJUST=1/2SHIFT=50作舍入及移位处理(Product+adjust)/shift=(873300+50)/100=8733又如:输入工作时间为65.245,工资率为8.52则, product=65245X852=55588740SHIFT=(10)5-2=1000Adjust=500作舍入及移位处理55588740+500/1000=55589240/1000=555
17、89金处理的值只是取得了答案的有效值,并未考录小数点的位置,这个问题将会在输出时得到解决。3.NODEC=02在这种情况下,乘积的结果不必做舍入及移位处理,只需记录NODEC的值,并在输出显示是解决小数点的问题即可在计算时还需啊哟说明一个问题:由于采用整数运算,要求输入数不超过6535,任意输入数超过改制就做溢出处理,在这里我们用输出0来表示。此外,两个输入数的成绩可能得到三十二位二进制数的结果,这用一般的运算乘法指令就可以得到。对于这样的双精度数作除法运算时,尽管我们已经限制shift的值不超过65535,但字运算的出发指令要求双精度被除数和单精度的除数相除,其结果应该是双精度的商,否则作为
18、溢出处理。为了避免这种溢出情况的发生,我们采用以下程序段来作为除法。设在以下程序段运行前,我们已取得双精度被除数在DX:AX中,除数在shift单元中,除法运算结果的商在DX,AX中。模块名:begin为中控制模块输入:接受从键盘输入的工作时间hour和工资rate输出:在屏幕上显示工资值wage功能:根据工作时间和工资率计算工资Wage=hour*rate调用:2:模块名:Q10SCR功能:清除屏幕3:模块名:Q20CURS功能:置于光标位置4模块名:B10inpt输入:接受从键盘输入的以小时为单位的工作时间及工资率输出:把工作时间缓存HASPAR缓存区,吧工资率存入ratepar缓冲区功能
19、:接受从键盘输入的工作时间及工资率,分别存入相应的缓存区中。5模块名:D10HOUR输入:从HRSPAR中取出工作时间输出:把转换为二进制的时间存入BINHRS单元中。功能:调用子过程M10ASBI,把工作时间从ASCLL吗转换为二进制数。6模块名:E10RATE输入:从RATEPAR中取出工资率。输出:把转换为二进制的工资率存入BINRATE单元中。功能:调用子过程M10ASBI,把工资率从ASCLL码转换为二进制数。7:模块名:M10ASBI输入:根据调用过程给出的指针以及字符个数取得一个ASCLL字符窜、输出:将ASCLL字符窜转换为二进制数,结果存放与BINAL单元中功能:把ASCLL
20、字符窜转换为二进制数。同时记录输入的小数点后的位数累计在NODEC单元中。8:模块名:F10MULT输入:从binHRAS中取得工作时间,从BINRATE中取得工资率。输出:根据工作时间及工资率的取值将其结果存放在DX,AX中功能:把工作时间和工资率的成绩经过舍入和移位处理后得到的二进制工资值存放在DX.:AX中。9模块名:G10WAGE 输入:DX,AX中的二进制工资数以及NODEC单元中的小数点后的位数输出:把二进制的工资数转换为ASCLL码存放在ASCWAGE为首地址的字符窜当中功能:10模块名输入:ASCWAGE中的字符窜输出:把字符窜在屏幕上显示出来功能:显示工资数;PROGRAM
21、TITLE GOES HERE -SCREMP;Enter hours&rate,display wage;*stacksg segment para stack stack dw 32 dup(?)stacksg ends;*datasg segment para data hrspar label byte ;Hours parameter list; maxhlen db 6 acthlen db ? hrsfld db 6 dup(?) ratepar label byte ;rate parameter list; maxrlen db 6 actrlen db ? ratefld
22、db 6 dup(?) messg1 db Hours worked?,$ messg2 db Rate of pay?,$ messg3 db Wage = ascwage db 14 dup(30h),13,10,$ messg4 db 13,10,Overflow!,13,10,$ adjust dw ? binval dw 0 binhrs dw 0 binrate dw 0 col db 0 decind db 0 mult10 dw 01 nodec dw 0 row db 3 shift dw ? tenwd dw 10 tempdx dw ? tempax dw ?datasg
23、 ends;*codesg segment para code;-begin proc far ;main part of program assume cs:codesg,ds:datasg,ss:stacksg,es:datasg;set up stack for return push ds sub ax,ax push ax;set DS register to current data segment mov ax,datasg mov ds,ax mov es,ax;main part of program goes here mov ax,0600h;CALL DISP call
24、 q10scr call q20cursa20loop: call b10inpt cmp acthlen,0 je a30 call d10hour call e10rate call f10mult call g10wage call k10disp jmp a20loopa30:;call timedate mov ax,0600h call q10scr retbegin endp;-; Input hours&rate;b10inpt proc near lea dx,messg1 mov ah,09h int 21h lea dx,hrspar mov ah,0ah int 21h
25、 cmp acthlen,0 jne b20 retb20: mov col,25 call q20curs lea dx,messg2 mov ah,09h int 21h lea dx,ratepar mov ah,0ah int 21h retb10inpt endp;-; Process hours:; -d10hour proc near mov nodec,0 mov cl,acthlen sub ch,ch lea si,hrsfld-1 add si,cx call m10asbi mov ax,binval mov binhrs,ax retd10hour endp;-; Process rate:; -e10rate proc near mov cl,actrlen sub ch,ch lea si,ratefld-1 add si,cx call m10asbi mov ax,binval mov binrate,ax rete10rate endp;-; Multiply,round,&shift; -f10mult proc near mov cx,07 lea di,ascwage mov ax,3030h cld rep stosw mov shift,10 mov adjust,0 mov cx,nodec cmp cl,06
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1