在 TASM 8086 中比较 3 个数字(每个数字都是三位数)

问题描述 投票:0回答:1
mov ah, 09h
lea dx, msg1
int 21h

; Read 1st number
mov ah, 01h
int 21h
mov bh, al

mov ah, 01h
int 21h
mov bl, al

mov ax,bx
and ax,0F0Fh
aad         ;0X0X --> 00XX
mov bl,al       ;1ST NUMBER

mov ah, 09h
lea dx, msg2
int 21h
; Read 2nd number
mov ah, 01h
int 21h
mov ch, al

mov ah, 01h
int 21h
mov cl, al

mov ax,cx
and ax,0F0Fh
aad             ;0X0X --> 00XX
mov bh,al       ;2ND NUMBER

mov ah, 09h
lea dx, msg3
int 21h
; Read 3rd number
mov ah, 01h
int 21h
mov ch, al

mov ah, 01h
int 21h
mov cl, al

mov ax,cx
and ax,0F0Fh
aad             ;0X0X --> 00XX
mov ch,al       ;3ND NUMBER

mov ah, 09h
lea dx, msg5
int 21h

; Compare numbers
cmp bl, bh
jg first_compare
jl second_compare

first_compare:
    cmp bl,ch
    jg first_greatest
    jl third_greatest
    
second_compare:
    cmp bh,ch
    jg second_greatest
    jl third_greatest

first_greatest:
    call num_greates
    mov ax,0000h
        mov al, bl
    call greatestnum
    jmp done
    
second_greatest:
    call num_greates
    mov ax,0000h
    mov al, bh
    call greatestnum
    jmp done
    
third_greatest:
    call num_greates
    mov ax,0000h
    mov al, ch
    call greatestnum
    jmp done
    
greatestnum proc        ;Convert to ASCII then print
    aam
    add ax, 3030h
    mov bx, ax
    mov ah, 02h
    mov dl, bh
    int 21h
    mov dl, bl
    int 21h
    ret
greatestnum endp
    
num_greates proc
    mov ah, 09h
    lea dx, msg4
    int 21h
    ret
num_greates endp

我尝试创建两位数比较,然后打印两位数最大的数字。我不知道如何比较第三位数字然后打印它。我想我应该使用

shl
来移动 I :
"aad"
之后的值,然后
"mov bl,al"
来存储第三位数字,然后我应该将它们与另一个 16 位进行 16 位比较,但问题是没有足够的寄存器来储存它们

sorting assembly x86-16 tasm
1个回答
0
投票

解决方案取决于三位数的上限。

000 到 255 范围内的三位数

您可以继续使用

aad
指令,并且不会遇到任何寄存器短缺的情况,因为我们可以继续将连续的数字存储在BL、BH和CH中。

将第三位数字添加到第一个数字的代码:

mov  ah, 09h
lea  dx, msg1
int  21h
mov  ah, 01h     ; Get 1st digit of 1st number
int  21h         ; -> AL
mov  cl, al      ; ['0','2']
mov  ah, 01h     ; Get 2nd digit of 1st number
int  21h         ; -> AL
mov  ah, cl
and  ax, 0F0Fh
aad
mov  cl, al      ; [0,25]
mov  ah, 01h     ; Get 3rd digit of 1st number
int  21h         ; -> AL
and  al, 0Fh
mov  ah, cl
aad
mov  BL, al      ; [0,255]

对第二个号码 (BH) 和第三个号码 (CH) 使用类似的代码。

依次比较数字的部分有缺陷:

  • 当数字相等时,你没有决定要做什么。这不可避免地会导致错误的结果!想想
    jg
    jl
    并不是完全对立的。
    jge
    jl
    很好,
    jg
    jle
    也可以。
  • 您在这里使用了太多条件跳转。最好让执行尽可能“失败”:
compare12:
  cmp  bl, bh
  jge  compare13
compare23:
  cmp  bh, ch
  jge  second_greatest
  jl   third_greatest
compare13:
  cmp  bl, ch
  jl   third_greatest
first_greatest:
  ...

因为现在您想要显示的数字可能超过值 99,所以您必须通过代码片段将您的 greatestnum 过程中的代码从我的答案更改为 有关将二进制数转换为十进制数的问题,并且以 3 位数字显示答案

000 到 999 范围内的三位数

下面我提出了一种解决方案,该解决方案继续使用

aad
指令来组合最高有效数字,并依赖于乘以 10 来添加最低有效数字。同样,预计不会出现寄存器短缺的情况。我会将连续的数字存储在 BX、CX 和 DX 中。

将第三位数字添加到第一个数字的代码:

mov  ah, 09h
lea  dx, msg1
int  21h
mov  ah, 01h     ; Get 1st digit of 1st number
int  21h         ; -> AL
mov  BL, al      ; ['0','9']
mov  ah, 01h     ; Get 2nd digit of 1st number
int  21h         ; -> AL
mov  ah, BL
and  ax, 0F0Fh
aad
mov  BL, 10
mul  BL          ; -> AX = AL * BL = [0,99] * 10
mov  BX, AX      ; [0,990]
mov  ah, 01h     ; Get 3rd digit of 1st number
int  21h         ; -> AL
and  al, 0Fh
cbw
add  BX, ax      ; [0,999]

对第二个号码 (CX) 和第三个号码 (DX) 使用类似的代码。

因为 DX 包含数字之一,所以您需要在显示 msg5:

时保留其值
push dx
mov  ah, 09h
lea  dx, msg5
int  21h
pop  dx

使用改进的代码来比较数字,不要忘记将寄存器名称从{BL,BH,CH}更改为{BX,CX,DX}。

同样,因为现在您想要显示的数字可能超过值 99,所以您必须使用合适的代码更改 greatestnum 过程中的代码,以打印 AX 中保存的数字。通过阅读获得灵感。

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