山东大学汇编语言上机实验实验五.docx

上传人:b****7 文档编号:10005359 上传时间:2023-02-07 格式:DOCX 页数:41 大小:527.16KB
下载 相关 举报
山东大学汇编语言上机实验实验五.docx_第1页
第1页 / 共41页
山东大学汇编语言上机实验实验五.docx_第2页
第2页 / 共41页
山东大学汇编语言上机实验实验五.docx_第3页
第3页 / 共41页
山东大学汇编语言上机实验实验五.docx_第4页
第4页 / 共41页
山东大学汇编语言上机实验实验五.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

山东大学汇编语言上机实验实验五.docx

《山东大学汇编语言上机实验实验五.docx》由会员分享,可在线阅读,更多相关《山东大学汇编语言上机实验实验五.docx(41页珍藏版)》请在冰豆网上搜索。

山东大学汇编语言上机实验实验五.docx

山东大学汇编语言上机实验实验五

子程序设计

2.6显示学生名次表rank

编制一个程序,要求接受键盘输入的一个班的学生成绩,并存放于一个50字的grade数组中,其中grade+i保存学号为I+1的学生成绩。

然后根据grade中的学生成绩,把学生成绩依次填入50字的rank数组中,其中rank+i的内容是学号为i+1的学生的名次。

再按学号顺序把名次从终端上显示出来。

本题要做的主要工作和例2.2的内容是完全一样的,只是增加了由用户键入学生成绩及输出学生名次两个部分的内容,因此这三个部分可以用子程序结构来完成。

子程序结构划分的层次图如图2.17所示,可以看出,main为主要模块,其下一层的三个模块为程序的三大部分。

现将各模块说明如下:

1.模块名:

main为总模块

输入:

从键盘输入一个班的学生成绩

输出:

显示一个班的学生成绩

功能:

根据输入的学生成绩,计算并显示学生名次。

算法如下:

一个学生名次等于成绩高于该学生的人数+1.

2.模块名:

input

输入:

以学号为序型键盘输入一个班的学生成绩。

各个成绩之间用逗号隔开,最后以回车符号结束。

输出:

把一个班的学生成绩存入grade数组。

功能:

接受一个班的学生成绩。

调用子模块decibin把键盘输入的一个十进制数转换为二进制数。

调用子模块crlf完成回车,换行功能。

3.模块名:

rankp

输入:

从grade数组取得一个班的学生成绩。

输出:

以学号为序计算出该班每个学生的名次存入rank数组。

功能:

计算一个班的学生成绩。

算法为:

一个学生的名次等于成绩高于该生的学生人数加1.

4,。

模块名;output

输入:

把rank数组取得一个班的学生名次。

输出:

把一个班的学生名次以学号为序在总端上显示出来。

功能:

先是一个班的学生名次。

调用子模块decibin把键盘输入的一个十进制数转换为二进制数。

调用子模块crlf完成回车,换行功能。

5:

模块名:

decilin

输入:

从键盘输入一个十进制数。

输出:

把该数转换成二进制数并存入BX寄存器中。

功能:

从键盘输入一个十进制数转换成二进制数并存入BX寄存器中。

6.模块名:

crlf

输出:

向终端发出回车换行符。

功能:

完成一次回车换行操作。

7.模块名:

binidec

输入:

从BX寄存器取得一个二进制数。

输出:

在终端屏幕显示一个十进制数。

功能:

把BX寄存器中的二进制数转换为十进制数,并在终端显示出来。

调用子模块DCE_DIV用来作除法运算并显示字符。

8.模块名:

dec_div

输入:

从BX寄存器中的二进制数除以相应的十的幂,并在屏幕显示一位商。

余数保存在BX寄存器中。

有了以上的层次图及模块说明,对程序的全貌有了基本了解。

在图2.18中,我们给出了除rankp以外的其余各个子程序的程序框图。

Rankp的框图与图2.4相同。

图2.19是程序清单,图2.20是本例的运行情况。

;PROGRAMTITLEGOESHERE——Rank

;**************************************************************************

datareasegment

gradedw50dup(?

rankdw50dup(?

countdw?

mess1db'Grade?

$'

mess2db13,10,'InputError!

',13,10,'$'

mess3db'Rank:

$'

datareaends

;**************************************************************************

prognamsegment

;--------------------------------------------------------------------------

mainprocfar

assumecs:

prognam,ds:

datarea

start:

;setupstackforreturn

pushds

subax,ax

pushax

;setDSregistertocurrentdatasegment

movax,datarea

movds,ax

;MAINPARTOFPROGRAMGOESHERE

callinput

callrankp

calloutput

ret

mainendp

;--------------------------------------------------------------------------

inputprocnear

leadx,mess1

movah,09

int21h

;

movsi,0

movcount,0

enter:

calldecibin

inccount

cmpdl,','

jestore

cmpdl,13

jeexit2

jneerror

store:

movgrade[si],bx

addsi,2

jmpenter

error:

leadx,mess2

movah,09

int21h

exit2:

movgrade[si],bx

callcrlf

ret

inputendp

;--------------------------------------------------------------------------

rankpprocnear

movdi,count

movbx,0

loop1:

movax,grade[bx]

movwordptrrank[bx],0

movcx,count

leasi,grade

next:

cmpax,[si]

jgno_count

incwordptrrank[bx]

no_count:

addsi,2

loopnext

addbx,2

decdi

jneloop1

ret

rankpendp

;--------------------------------------------------------------------------

outputprocnear

leadx,mess3

movah,09

int21h

;

movsi,0

movdi,count

next1:

movbx,rank[si]

callbinidec

movdl,','

movah,02

int21h

addsi,2

decdi

jnznext1

callcrlf

ret

outputendp

;--------------------------------------------------------------------------

decibinprocnear

;proceduretoconverdecimalonkeybdtobinary.

;resultisleftinBXregister.

movbx,0

;getdigitfromkeyboard,converttobinary

newchar:

movah,1

int21h

movdl,al

subal,30h

jlexit1

cmpal,9d

jgexit1

cbw

;(digitisnowinAX)

;multiplynumberinBXby10decimal.

xchgax,bx

movcx,10d

mulcx

xchgax,bx

;adddigitinAXtonumberinBX

addbx,ax

jmpnewchar

exit1:

ret

decibinendp

;--------------------------------------------------------------------------

binidecprocnear

;proceduretoconvertbinarynumberinBXtodecimal

;onconsolescreen

pushbx

pushcx

pushsi

pushdi

movcx,100d

calldec_div

movcx,10d

calldec_div

movcx,1d

calldec_div

popdi

popsi

popcx

popbx

ret

binidecendp

;--------------------------------------------------------------------------

dec_divprocnear

;sub_subroutinetodividenumberinBXybnumberinCX

;printquotientonscreen

movax,bx

movdx,0

divcx

movbx,dx

movdl,al

;printthecontentsofDLonscreen

adddl,30h

movah,02h

int21h

ret

dec_divendp

;--------------------------------------------------------------------------

crlfprocnear

;printcarriagereturnandlinefeed

movdl,0ah

movah,02h

int21h

;

movdl,0dh

movah,02h

int21h

;

ret

crlfendp

;--------------------------------------------------------------------------

prognamends

;**************************************************************************

endstart

程序框图如下:

实验截图如下:

实验总结:

 

           

          

在复杂的程序设计中,采用模块化结构可以划分功能、分界程序,使得程序有复杂变简单,变清晰。

主程序和子程序之间嵌套使用,使得写代码时思路更清楚明白,读代码时方便快捷清晰明了。

这点跟高级编程语言类似。

而此程序中变量p可以跟踪并控制输入的人数、输名字要预留缓存区、十进制码要和二进制码间相互转换,这些又体现了编程低级语言的特点。

学习汇编语言,重要的事掌握如何通过汇编指令和程序来控制计算机各个组成部件工作,完成一系列任务。

因此,学习汇编用语言与学习高级语言的不同之处是要学习如何深入到计算机的内部进行控制。

 

通过这次实验,加深了我对汇编语言的理解。

每一步的输入、存储、转换、输出,都需要一条条的汇编指令执行。

而且每一步都有自己的源和目标的地址,每个数据都有自己的存储空间和地址,我们可以很清晰的“跟踪”每一个数据的变化和地址的转移。

实验体会:

 

在复杂的程序设计中,采用模块化结构可以划分功能、分界程序,使得程序有复杂变简单,变清晰。

主程序和子程序之间嵌套使用,使得写代码时思路更清楚明白,读代码时方便快捷清晰明了。

这点跟高级编程语言类似。

而此程序中变量p可以跟踪并控制输入的人数、输名字要预留缓存区、十进制码要和二进制码间相互转换,这些又体现了编程低级语言的特点。

学习汇编语言,重要的事掌握如何通过汇编指令和程序来控制计算机各个组成部件工作,完成一系列任务。

因此,学习汇编用语言与学习高级语言的不同之处是要学习如何深入到计算机的内部进行控制。

 

通过这次实验,加深了我对汇编语言的理解。

每一步的输入、存储、转换、输出,都需要一条条的汇编指令执行。

而且每一步都有自己的源和目标的地址,每个数据都有自己的存储空间和地址,我们可以很清晰的“跟踪”每一个数据的变化和地址的转移。

2.7计算工资scremp

编写一个程序,接受用户输入的工作时间及工资率,显示计算得到的工资数。

本程序有三个部分组成,输入工作时间和工资率,计算工资;显示工资值。

在输入输出部分,与例2.6一样,必须考虑自负与数字的装换,以及十进制换二进制,二进制换十进制的问题。

除此之外,还应注意到本例中的输入数可能是小数。

在这里并不需要使用浮点数格式来进行计算,只是在计算中必须处理小数。

我们采用在接受输入数字是记录小数点后的位数,并把两个输入数的小数点后位数之和存放在nodec单元当中。

在计算工资的乘法中,并不考虑小数点后的存在,而输出的工资数又只取出小数点后的两位数,因此我们用SHIFT单元记录移位因子,用ADJUST单元记录舍入值。

对于不同的NODEC可以分以下情况进行处理。

1.NODEC>6

我们知道,对于16位整数而言,及其允许的最大数是65535,对于NODEC>6的数,移位因子将>=10000,该数已经超过机器允许的范围,因此本例限制NODEC的值必须<=6.如果NODEC>6,则作为溢出处理,此时将输出值变为0。

2.NODEC=3~6

此时移位因子SHIFT=(10)^nodec—2

舍入值ADJUST=1/2SHIFT

例如:

输入工作时间为8.52,工资率为10.25,则乘机为

Product=852X1025=873300

移位因子为shift=(10)^nodec—2

舍入值ADJUST=1/2SHIFT=50

作舍入及移位处理

(Product+adjust)/shift=(873300+50)/100

=8733

又如:

输入工作时间为65.245,工资率为8.52

则,product=65245X852=55588740

SHIFT=(10)^5-2=1000

Adjust=500

作舍入及移位处理

55588740+500/1000=55589240/1000

=55589

金处理的值只是取得了答案的有效值,并未考录小数点的位置,这个问题将会在输出时得到解决。

3.NODEC=0~2

在这种情况下,乘积的结果不必做舍入及移位处理,只需记录NODEC的值,并在输出显示是解决小数点的问题即可

在计算时还需啊哟说明一个问题:

由于采用整数运算,要求输入数不超过6535,任意输入数超过改制就做溢出处理,在这里我们用输出0来表示。

此外,两个输入数的成绩可能得到三十二位二进制数的结果,这用一般的运算乘法指令就可以得到。

对于这样的双精度数作除法运算时,尽管我们已经限制shift的值不超过65535,但字运算的出发指令要求双精度被除数和单精度的除数相除,其结果应该是双精度的商,否则作为溢出处理。

为了避免这种溢出情况的发生,我们采用以下程序段来作为除法。

设在以下程序段运行前,我们已取得双精度被除数在DX:

AX中,除数在shift单元中,除法运算结果的商在DX,AX中。

 

模块名:

begin为中控制模块

输入:

接受从键盘输入的工作时间hour和工资rate

输出:

在屏幕上显示工资值wage

功能:

根据工作时间和工资率计算工资

 

Wage=hour*rate

调用:

 

2:

模块名:

Q10SCR

功能:

清除屏幕

3:

模块名:

Q20CURS

功能:

置于光标位置

4模块名:

B10inpt

输入:

接受从键盘输入的以小时为单位的工作时间及工资率

输出:

把工作时间缓存HASPAR缓存区,吧工资率存入ratepar缓冲区

功能:

接受从键盘输入的工作时间及工资率,分别存入相应的缓存区中。

5模块名:

D10HOUR

输入:

从HRSPAR中取出工作时间

输出:

把转换为二进制的时间存入BINHRS单元中。

功能:

调用子过程M10ASBI,把工作时间从ASCLL吗转换为二进制数。

6模块名:

E10RATE

输入:

从RATEPAR中取出工资率。

输出:

把转换为二进制的工资率存入BINRATE单元中。

功能:

调用子过程M10ASBI,把工资率从ASCLL码转换为二进制数。

7:

模块名:

M10ASBI

输入:

根据调用过程给出的指针以及字符个数取得一个ASCLL字符窜、

输出:

将ASCLL字符窜转换为二进制数,结果存放与BINAL单元中

功能:

把ASCLL字符窜转换为二进制数。

同时记录输入的小数点后的位数累计在NODEC单元中。

8:

模块名:

F10MULT

输入:

从binHRAS中取得工作时间,从BINRATE中取得工资率。

输出:

根据工作时间及工资率的取值将其结果存放在DX,AX中

功能:

把工作时间和工资率的成绩经过舍入和移位处理后得到的二进制工资值存放在DX.:

AX中。

9模块名:

G10WAGE

输入:

DX,AX中的二进制工资数以及NODEC单元中的小数点后的位数

输出:

把二进制的工资数转换为ASCLL码存放在ASCWAGE为首地址的字符窜当中

功能:

10模块名

输入:

ASCWAGE中的字符窜

输出:

把字符窜在屏幕上显示出来

功能:

显示工资数

;PROGRAMTITLEGOESHERE--SCREMP

;Enterhours&rate,displaywage

;*************************************

stacksgsegmentparastack'stack'

dw32dup(?

stacksgends

;*************************************

datasgsegmentpara'data'

hrsparlabelbyte;Hoursparameterlist;

maxhlendb6

acthlendb?

hrsflddb6dup(?

rateparlabelbyte;rateparameterlist;

maxrlendb6

actrlendb?

rateflddb6dup(?

 

messg1db'Hoursworked?

','$'

messg2db'Rateofpay?

','$'

messg3db'Wage='

ascwagedb14dup(30h),13,10,'$'

messg4db13,10,'Overflow!

',13,10,'$'

adjustdw?

binvaldw0

binhrsdw0

binratedw0

coldb0

decinddb0

mult10dw01

nodecdw0

rowdb3

shiftdw?

tenwddw10

tempdxdw?

tempaxdw?

datasgends

;*************************************

codesgsegmentpara'code'

;-------------------------------------

beginprocfar;mainpartofprogram

assumecs:

codesg,ds:

datasg,ss:

stacksg,es:

datasg

;setupstackforreturn

pushds

subax,ax

pushax

;setDSregistertocurrentdatasegment

movax,datasg

movds,ax

moves,ax

;mainpartofprogramgoeshere

movax,0600h

;CALLDISP

callq10scr

callq20curs

a20loop:

callb10inpt

cmpacthlen,0

jea30

calld10hour

calle10rate

callf10mult

callg10wage

callk10disp

jmpa20loop

a30:

;calltimedate

movax,0600h

callq10scr

ret

beginendp

;-------------------------------------------

;Inputhours&rate

;

b10inptprocnear

leadx,messg1

movah,09h

int21h

leadx,hrspar

movah,0ah

int21h

cmpacthlen,0

jneb20

ret

b20:

movcol,25

callq20curs

leadx,messg2

movah,09h

int21h

leadx,ratepar

movah,0ah

int21h

ret

b10inptendp

;--------------------------------------------

;Processhours:

;--------------

d10hourprocnear

movnodec,0

movcl,acthlen

subch,ch

leasi,hrsfld-1

addsi,cx

callm10asbi

movax,binval

movbinhrs,ax

ret

d10hourendp

;---------------------------------------------

;Processrate:

;-------------

e10rateprocnear

movcl,actrlen

subch,ch

leasi,ratefld-1

addsi,cx

callm10asbi

movax,binval

movbinrate,ax

ret

e10rateendp

;----------------------------------------------

;Multiply,round,&shift

;---------------------

f10multprocnear

movcx,07

leadi,ascwage

movax,3030h

cld

repstosw

movshift,10

movadjust,0

movcx,nodec

cmpcl,06

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1