总平均成绩计算器

问题描述 投票:0回答:1

我是这个汇编语言(emu8086)的新手,我只是想问一下这段代码是否有问题。我想显示平均成绩,但输出只有“平均”一词,并且不显示任何数字。
我应该做什么来解决或调试我的代码?

.MODEL SMALL
.DATA
        VAL1         DB      ?
        DISPLAY1     DB      0AH,0DH,'NUMBER OF SUBJECTS :','$'
        DISPLAY2         DB      0AH,0DH,'ENTER GRADE:','$'
        DISPLAY3         DB      0AH,0DH,'AVEARGE:','$'
    BUFFER       DB      3,4 DUP(?)
.CODE
MAIN    PROC

.STARTUP

        LEA DX,DISPLAY1 
        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,DISPLAY2 
        MOV AH,09H
        INT 21H

        MOV AH,0AH  
        LEA DX,BUFFER
        INT 21H
        SUB AL,30H

        ADD AL,VAL1 
        MOV VAL1,AL 
        LOOP LBL1   

LBL2:
        LEA DX,DISPLAY3 
        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

.EXIT

MAIN    ENDP
        END     MAIN
validation assembly input x86-16 emu8086
1个回答
0
投票
MOV AH,0AH  
LEA DX,BUFFER
INT 21H
SUB AL,30H

第一个错误是您正在使用 DOS.BufferedInput 函数 0Ah 输入成绩,但没有从缓冲区中检索数字。您似乎期望在 AL 寄存器中找到它,就像 DOS.GetCharacter 函数 01h 的情况一样。

LOOP LBL1

第二个错误是您使用的

loop
指令取决于整个 CX 寄存器,但您的代码仅设置 CX 的 CL 部分。当你的程序启动时,你不应该依赖任何寄存器内容,当然,除非这些设置有很好的记录。

ADD AX,3030H    
MOV DX,AX   
MOV AH,02H  
INT 21H

第三个错误是,您似乎期望显示由两位数字组成的“平均成绩”,并通过单次调用 DOS.PrintCharacter 函数 02h 来完成。

对于这个简单的练习,我们可以假设
科目数量

和他们的成绩都是个位数。当然,平均成绩也将是个位数。 使用 DOS.Getcharacter 函数 01h 就可以了,并且您正在使用从字符到数字表示的值的正确转换。但是,在处理用户输入时,您永远无法真正信任用户向您的程序提供有效的输入。由您来验证输入。对于一位数来说,这很简单:

GetDigit0_9: mov ah, 01h ; DOS.GetCharacter int 21h ; -> AL sub al, '0' cmp al, 9 ja GetDigit0_9

注意无意识的“无限循环”和“被零除”问题。
如果用户为

科目数
输入 0,则不能允许运行等级循环或执行

div bl
指令。使用 jcxz (JumpOnCXZero) 指令

    重做询问用户 [1,9] 中的值
  • LBL0: call GetDigit0_9 ; -> AX=[0,9] mov cx, ax jcxz LBL0 ; Guard against 0 number of subjects

  • 或直接跳至节目末尾
  • jcxz LBL3 ; Guard against 0 number of subjects LBL1: ... loop LBL1 LBL2: ... LBL3: mov ax, 4C00h ; DOS.Terminate int 21h

    
    
  • 修改后的代码:

... LEA DX, DISPLAY1 MOV AH, 09h ; DOS.PrintString INT 21h call GetDigit0_9 ; -> AX=[0,9] mov cx, ax mov bl, al ; (*) MOV VAL1, 0 jcxz LBL3 ; Guard against 0 number of subjects LBL1: LEA DX, DISPLAY2 MOV AH, 09h ; DOS.PrintString INT 21h call GetDigit0_9 ; -> AX=[0,9] add VAL1, al loop LBL1 LBL2: LEA DX, DISPLAY3 MOV AH, 09h ; DOS.PrintString INT 21h mov ah, 0 mov al, VAL1 div bl ; (*) add al, '0' mov dl, al mov ah, 02h ; DOS.PrintCharacter int 21h LBL3: mov ax, 4C00h ; DOS.Terminate int 21h ; IN () OUT (ax) GetDigit0_9: mov ah, 01h ; DOS.GetCharacter int 21h ; -> AL sub al, '0' cmp al, 9 ja GetDigit0_9 mov ah, 0 ret ...

	
© www.soinside.com 2019 - 2024. All rights reserved.