编制一个程序,其功能为:内存中以8位无符号数形式连续存放着10个数据,这数据来自于一个自动抄表系统记录的10个用户某月天然气的使用量(立方米),天然气费计算公式如下(其中,X表示天然气用量,Y表示应交天然气费):
- a)Y=X×80 X≤6
- b)Y=X×120 6<X≤10
- c)Y=X×160 X>10
计算每个用户需要交的天然气费,结果用字表示,并将结果存入指定单元。
例如:
用天然气量:05H,07H,12H……
天然气费: 0190H,0348H,0780H……
部分程序已经给出,其中原始数据由过程LOAD从文件INPUT.DAT中读入以SOURCE开始的内存单元中。运算结果要求从RESULT开始的内存单元存放, 由过程SAVE保存到文件OUTPUT.DAT中。
请填空BEGIN和END之间已给出的源程序使其完整,空白已经用横线标出,每行空白一般只需要一条指令,但采用功能相当的多条指令亦可,考生也可以删除BEGIN和END之间原有的代码并自行编程来完成要求的功能。
对程序必须进行汇编,并与IO.OBJ链接产生执行文件,最终运行程序产生结果。调试中若发现整个程序中存在错误之处,请加以修改。
[试题程序]
EXTRN LOAD:FAR,SAVE:FAR
NEQU 10
DSEG SEGMENT
SOURCE DB N DUP()
RESULT DW N DUP(0)
ADB 80
BDB 120
CDB 160
NAME0 DB ’INPUT.DAT’,0
NAME1 DB ’OUTPUT.DAT’,0
DSEG ENDS
SSEG SECMENT STACK
DB 256 DUP()
SSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG,SS:SSEG
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DSEG
MOV DS,AX
LEA DX,SOURCE
LEA SI,NAME0
MOV CX,N
CALL LOAD
; ******** BEGIN *********
LEA SI,SOURCE
LEA DI,RESULT
CLD
MOV CX,N
AGAIN: MOV AL,[SI]
CMP AL,6
JA (1)
(2)
JMP NEXT
LIMIT6:CMP AL,10
JA (3)
(4)
JMP NEXT
LIMIT10: (5)
NEXT: MOV [DI],AX
INC SI
ADD DI,2
LOOP AGAIN
; ******** END ********
LEA DX,RESULT
LEA SI,NAME1
MOV CX,N*2
CALL SAVE
RET
START ENDP
CSEG ENDS
END START
参考答案:(1)LIMIT6 (2)MUL A (3)LMIT10 (4)MUL B (5)MUL C
解析:
本题一个分段函数的问题,根据数据大小的不同,再采用不同的计算方法求出结果。其中所需要的一些常量在数据段中已经进行了定义,在程序中直接使用即可。但由于对每个数据进行处理的算法是相同的,因此用一个循环即可实现对所有数据的处理。另外,由于要分成不同的情况进行计算,所以循环中采用的是分支程序来实现。
进入循环以后,将数据取入AL中,并将其与6进行比较,如果大于6的话就需要进行跳转,否则将执行下面的操作。由于小于6时天然气费计算的方法是乘以80,因此第二个空白处应该填的内容是MUL A。第一个空白处应填跳转到哪条语句继续执行,有两个选择LMIT6或LIMIT10,但由于当数据大于6的时候,还有一个上限10需要比较,因此跳转的方向应该是和10进行比较的语句,从程序中可以知道应该是LIMIT6。第三个和第四个空白是数据和10进行比较后所需要的处理,大于10的时候跳转,小于10的时候继续执行。前面已经与6进行过比较,大于6的数才执行到这里,而数据又小于10,因此此时的天然气费计算方法是乘以120,即第四个空白处应填MUlB。由于大于10的时候天然气费的计算方法为乘以160,因此最后一个空白处的语句是MUL C。