汇编语言代码给出了不准确的结果。 (8086仿真器)

Assembly language code is giving inaccurate results. (8086 emulator)

我需要在 8086 模拟器中编写代码,用户输入 0 到 9。如果该值低于 3,则打印 'Good morning!'。如果值大于或等于 4 且小于 6(基本上只是 4 和 5),则打印 'Good afternoon!'。如果该值大于或等于 8,则打印 'Good night!'。对于值 3、6 和 7,系统不执行任何操作。但是,就我而言,我也得到了这三个值的输出。我的代码有什么问题?

.MODEL SMALL
.STACK 100H
.DATA  
    STRING1 DB "Enter number:$"
    STRING2 DB "Good morning!$"
    STRING3 DB "Good afternoon!$"  
    STRING4 DB "Good night!$"
.CODE
 MAIN PROC
    
    MOV AX , @DATA
    MOV DS , AX
    LEA DX , STRING1
    MOV AH , 9
    INT 21h
    
    MOV AH , 1
    INT 21h
    SUB AL , 30h
    
    CMP AL , 3
    JL good_morning
    
    CMP AL , 6
    JL next_check
    
    CMP AL , 8
    JGE good_night
    
    good_morning:
    LEA DX , STRING2
    MOV AH , 9
    INT 21h
    JMP exit_label
    
    next_check:
    CMP AL , 4
    JGE good_afternoon
    
    good_afternoon:
    LEA DX , STRING3
    MOV AH , 9
    INT 21h
    JMP exit_label
    
    good_night:
    LEA DX , STRING4
    MOV AH , 9
    INT 21h
    JMP exit_label    
    
    exit_label:
    MOV AX , 4C00H
    INT 21h
    
    
 MAIN ENDP
 
END MAIN

您的代码的第一个问题是没有评论!汇编很难阅读 评论;不要让自己变得更难(或者以后必须返回并维护此代码的人)。训练自己在编写代码 时写注释。没有人愿意稍后再回去 只是 写评论。作为奖励,编写注释将(希望)迫使您在编写代码时思考逻辑。

[I]n my case, I am getting an output for these three values [3, 6 and 7] as well.

首先跟踪代码的逻辑,逐步执行它并在脑海中“执行”它。由于 input-processing 中的 most 工作正常,我们可以假设读取输入的代码是正确的,所以我们将在那之后开始:

CMP AL , 3
JL good_morning    ; if AL < 3, jump to "good_morning"; otherwise, fall through

CMP AL , 6
JL next_check      ; if AL < 6, jump to "next_check"; otherwise, fall through

CMP AL , 8
JGE good_night     ; if AL > 8, jump to "good_night"; otherwise, fall through

问问自己:如果输入值为 3(因为这是您看到错误输出的第一个值)会怎样?好吧,它转到 next_check。所以,去看看那个代码:

next_check:
CMP AL , 4
JGE good_afternoon   ; if AL >= 4, jump to "good_afternoon"; otherwise, fall through

good_afternoon:
LEA DX , STRING3
MOV AH , 9
INT 21h
JMP exit_label

糟糕!无论 输入值是什么,你都会掉到 good_afternoon !如果AL大于等于4,则跳转到;否则,你就会失败。但是你掉进的地方和你跳到的地方完全一样,所以你会看到输入值为 3 的“下午好”的输出。这是错误的。

您可以通过在有条件跳转之后添加一个无条件跳转来修复它:

next_check:
CMP AL , 4
JGE good_afternoon   ; if AL >= 4, jump to "good_afternoon"; otherwise, fall through
JMP exit_label

good_afternoon:
LEA DX , STRING3
MOV AH , 9
INT 21h
JMP exit_label

但这比反转比较逻辑和分支方向的效率低(在我看来可读性差):

next_check:
CMP AL , 4
JL  exit_label     ; if AL < 4, jump to "exit_label"; otherwise, fall through

good_afternoon:
LEA DX , STRING3
MOV AH , 9
INT 21h
JMP exit_label

基于此技术,您应该能够通过代码跟踪产生无效输出的其他输入并以类似方式更正问题。