如何编写8086汇编语言程序来计算任何n
个数字的平均值?我写了两个程序。一个使用mov ah,01 int 21h
输入函数,因此它只接受一个数字。出于这个原因,我不能输入像10这样的数字。
我从另一个缓冲区读取。它可以接受很多数字,但问题是它会不断循环。
这是第一个程序:
.MODEL SMALL
.DATA
VAL1 DB ?
NL1 DB 0AH,0DH,'ENTER HOW MANY NO U WANT:','$'
NL2 DB 0AH,0DH,'ENTER NO:','$'
NL3 DB 0AH,0DH,'AVEARGE:','$'
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
LEA DX,NL1
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
SUB AL,30H
MOV CL,AL
MOV BL,AL
MOV AL,00
MOV VAL1,AL
LBL1:
LEA DX,NL2
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
SUB AL,30H
ADD AL,VAL1
MOV VAL1,AL
LOOP LBL1
LBL2:
LEA DX,NL3
MOV AH,09H
INT 21H
MOV AX,00
MOV AL,VAL1
DIV BL
ADD AX,3030H
MOV DX,AX
MOV AH,02H
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
这是第二个:
TITLE "THIS PROGRAM CALCULATES ANY N NUMBER OF STUDENT AVERAGE SCORES"
.MODEL SMALL
.DATA
VAL1 DB ?
DISPLAY1 DB 0AH,0DH,'HOW MANY NUMBER OF STUDENT SCORES DO YOU WANT TO INPUT? :','$'
DISPLAY2 DB 0AH,0DH,'ENTER NO:','$'
DISPLAY3 DB 0AH,0DH,'AVEARGE:','$'
BUFFER DB 3,4 DUP(?)
.CODE
MAIN PROC
.STARTUP
LEA DX,DISPLAY1 ; loads the message in the variable display 1
MOV AH,09H ; interrupt function to display the message
INT 21H
MOV AH,0AH ; Read into buffer
INT 21H
SUB AL,30H
MOV CL,AL
MOV BL,AL ; moves the content of al to bl register
MOV AL,00 ; sets the value of al to zero, the value of al is now in bl register
MOV VAL1,AL ; stores al in val1 NB: al is still zero.
LBL1:
LEA DX,DISPLAY2 ; displays message in display 2
MOV AH,09H
INT 21H
MOV AH,0AH ;Read into buffer
LEA DX,BUFFER
INT 21H
SUB AL,30H
ADD AL,VAL1 ; add val1 to al i.e, it now adds the previous value to the new one.
MOV VAL1,AL ; saves the added value to val 1.
LOOP LBL1 ; continues too add.
LBL2:
LEA DX,DISPLAY3 ; displays character in display 3
MOV AH,09H
INT 21H
MOV AX,00 ; sets ax value back to 00
MOV AL,VAL1 ; moves the total value back to al
DIV BL ; divides the total value with the inputed number of values tht was stored in bl
ADD AX,3030H ; convert to ASCII
MOV DX,AX ; now moves the content of ax register to data register
MOV AH,09H ; this displays the result
INT 21H
.EXIT
MAIN ENDP
END MAIN
答案 0 :(得分:1)
您似乎对int 21h/0Ah
有“问题”。第一次执行此操作时,不要将dx
设置为任何合理的缓冲区。您的输入将在您的提示上涂鸦(可能没有太大的伤害)。在循环内部,您可以将dx
设置为正确的缓冲区。但是当int 21h/0Ah
返回时,您正在使用al
,就好像它是有用的(两次)。自从我做了很长一段时间以后,但我的回忆是al
将是最后输入的字符 - 几乎可以肯定是“输入”键 - 我认为是13或0D。
当int 21h/0Ah
返回时,缓冲区中的第二个字节(buffer + 1
)将是输入的字符数。我记得,这将包括“输入”键。您可能想要检查此值以查看需要“转换”为数字的字符数。输入的字符(1或2)将从buffer + 2
开始。这些是您想要转换为数字的字符 - 第一个字符 - '0'乘以10 +第二个字符-'0'。或者只是字符-'0',如果只有一个。
当您尝试打印结果时,您可以通过add ax, 3030h
。然后将此值移至dx
。 int 21h/9
期望在dx
中指向$ -terminated字符串。这不是你所拥有的!将这两个字符移动到一个缓冲区并用'$'终止它,或者一次打印一个......我曾经喜欢那个hokey int 29h
,但你可能最好使用某些东西这将打印出如此标准输出(int 29h
进入屏幕并且无法重定向)。也许像...
...
add ax, 3030h
mov dx, ax
mov ah, 2
xchg dl, dh ; print dh first, then dl
int 21h
xchg dl, dh
int 21h ; I think ah is still okay here...
...
...
add ax, 3030h
mov dx, ax
mov ah, 2
xchg dl, dh ; print dh first, then dl
int 21h
xchg dl, dh
int 21h ; I think ah is still okay here...
...
在进入循环之前,您将
LBL1:
设置为......某些内容(我认为这不对)。 cl
“可能”是xero,但我确定了!
这都是未经测试的,“从记忆中”......我可能记不起来了,但它应该让你更近一点(我希望)......
答案 1 :(得分:-3)
DATA SEGMENT
ONENO DW 04h
SECONDNO DW 08h
SUM DB 00h
AVG DB 00h
ENDS
CODE SEGMENT
ASSUME DS:DATA CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV AX,00
MOV AX,ONENO
ADD AX,SECONDNO
MOV SUM,AL
MOV BL,02
DIV BL
MOV AVG,AL
CODE ENDS
END START