【问题标题】:Adding 4-digit numbers and displaying sum - Assembly Language添加 4 位数字并显示总和 - 汇编语言
【发布时间】:2016-11-29 11:20:48
【问题描述】:

我正在制作一个程序,我想从用户那里获取两个 4 位数字并显示它们的总和。

我知道如何从用户那里获取 4 位输入,但我无法将 4 位数字相加并显示结果。

需要帮助才能知道如何添加和显示两个 4 位数字的总和。

我正在使用emu8086汇编器

这是我到目前为止所做的。总和计算不正确。不是显示总和,而是在控制台上显示一些符号,例如“$”等。

.model small
.data  
st9 db 13,10,"Enter First Number : ",'$'
st10 db 13,10,"Enter Second Number : ",'$'
st11 db 13,10,"Result = ",'$'
num dw ?
num2 dw ? 
a dw 1000
b db 100
c db 10
.code
main proc
    mov AX,@data
    mov DS,AX

    addition:     
    mov AH,9H
    mov DX,offset st9
    INT 21H

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL a                       ;1st digit
    mov num,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL b                       ;2nd digit
    add num,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL c                      ;3rd digit
    ADD num,AX

    mov AH,1
    INT 21H                      ;4th digit
    SUB AL,30H
    ADD num,AX

    mov AH,9H
    mov DX,offset st10
    INT 21H

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL a                     ;1st digit
    mov num2,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL b                   ;2nd digit
    ADD num2,AX

    mov AH,1
    INT 21H  
    SUB AL,30H
    MUL c                     ;3rd digit
    ADD num2,AX

    mov AH,1
    INT 21H                ;4th digit
    SUB AL,30H 
    ADD num2,AX

    call addfunc 

    exit:
    mov AH,4CH
    INT 21H 

    addfunc proc near 

        mov BX,num2
        ADD BX,num
        SUB BX,48D

        mov AH,9H
        mov DX,offset st11
        INT 21H

        mov AH,2
        mov DL,bH
        INT 21H 

        mov AH,2
        mov DL,bl
        INT 21H  

        ret 

end main

【问题讨论】:

  • 那么你得到了什么?请参阅minimal reproducible example 了解如何编写更完整的问题。另外,当您在 emu8086 内置的调试器中单步执行时,您会看到什么?
  • 您的代码没有任何 cmets,所以 IDK 为什么要从总和中减去 48D,但我看不到任何可以将整数转换回十进制数字的东西。跨度>
  • @PeterCordes 没有显示总和,而是在屏幕上显示了一些符号,例如 $ 等。我还编辑了我的问题。
  • 我没用过emu8086,只用过NASM和gas。 D 表示十进制常量,对吗? 48 是0 的 ASCII 码。所以这应该适用于一位数的结果。 (并打破其他一切)。我敢肯定,您不能通过一次减法将 BX 中 0-99 的整数转换为 BL 和 BH 中的两个 ASCII 数字。您需要除以 10。当然,当您需要超过 2 个数字时,您需要重复执行此操作。
  • 或者您可以一次添加一个十进制数字的字符串,然后自己处理基数为 10 位的进位。

标签: assembly emu8086


【解决方案1】:

在担心总和之前,您需要确保输入正确。可惜他们错了!

在计算第一个数字时,您使用mul a。由于 a 变量被定义为一个单词(值为 1000),所以这个乘法是一个单词大小的操作,因此它实际上将 AX 寄存器与您的变量相乘。你的程序只在 AL 寄存器中获得一个值,它只是 AX 寄存器的低半部分。 您需要事先将AH 的上半部分归零。

mov AH,1
INT 21H  
SUB AL,30H
mov ah,0          <<<<<<<<<< Add this
MUL a             ;1st digit
mov num,AX

第 2 位和第 3 位的代码是正确的,但第 4 位又是错误的。 add num,ax 指令依赖于上半部分 AH 的内容,不是你设置的。

mov AH,1
INT 21H           ;4th digit
SUB AL,30H
mov ah,0          <<<<<<<<<< Add this
ADD num,AX

您需要对 numnum2 进行这些更正。


addfunc proc near 
    mov BX,num2
    ADD BX,num
    SUB BX,48D

从您在 addfunc 过程中计算的总和中减去 48D 是没有意义的。
此外,对 BL 和 BH 中的字节使用 DOS 中的 DisplayCharacter 函数不会显示结果数字。
下面是如何在屏幕上显示 AX 中的 16 位数字的一个版本:

addfunc proc near
 mov  ax,num2
 add  ax,num

 xor  cx,cx   ;Counts the digits
 mov  bx,10   ;Fixed divider
more:
 xor  dx,dx   ;Word division needs to zero DX!
 div  bx
 push dx      ;Remainder [0,9]
 inc  cx      ;One digit more
 test ax,ax
 jnz  more    ;Continu until AX is empty
next:
 pop  dx
 add  dl,48   ;Turn into a character, from [0,9] to ["0","9"]
 mov  ah,02h  ;DOS DisplayCharacter function
 int  21h
 loop next    ;Continu for all digits (*)

(*) 由于两个 4 位数字之和从 0 到 19998 不等,因此显示的位数从 1 到 5 不等。

【讨论】:

  • 感谢您提供详细且解释清楚的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 2010-12-24
相关资源
最近更新 更多