一个8086汇编语言程序,用于计算任何n个数字的平均值

时间:2013-01-16 07:17:48

标签: assembly masm

如何编写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

2 个答案:

答案 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。然后将此值移至dxint 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