You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NASM v2.15.05汇编中输入并相加多位数?

多位数加法输入问题解决方案

问题描述

已花费4小时尝试实现多位数输入功能,目前仅能成功处理0-9的个位数。尝试将字节数改为2,但程序未受影响,仍无法解决问题,求助可行方案。

原代码:

;adding two numbers(user input)

section .data
msg1 db "Enter the first number : ",0xa
len1 equ $ - msg1
msg2 db "Enter the 2nd number : ",0xa
len2 equ $ - msg2

msg3 db "The sum is: "
len3 equ $- msg3

section .bss
num1 resb 2
num2 resb 2 
res resb 2

section .text
global _start
_start :
  
  ;typing the first msg
  mov edx,len1
  mov ecx,msg1
  mov ebx,1 
  mov eax,4
  int 0x80
  
  ;getting the user input for the first number 
  mov edx,2 
  mov ecx,num1
  mov ebx,0 
  mov eax,3
  int 0x80
  
  ;typing the second msg 
  mov edx,len2
  mov ecx,msg2
  mov ebx,1 
  mov eax,4
  int 0x80
  
  ;getting the 2nd user input
  mov edx,2 
  mov ecx,num2
  mov ebx,0 
  mov eax,3
  int 0x80
  
  ; moving the first number to eax register and second number to ebx
  mov eax,[num1]
  sub eax,'0' ; subtract to convert ascii into decimal
  mov ebx,[num2]
  sub ebx,'0'
  
  add eax,ebx
  add eax,'0' ; to convert decimal into ascii again
  
  mov [res],eax ; storing the sum in res memory location
  
  ;typing the third msg 
  mov edx,len3
  mov ecx,msg3
  mov ebx,1 
  mov eax,4
  int 0x80
  
  ;printing the sum
  mov edx,2
  mov ecx,res
  mov ebx,1 
  mov eax,4
  int 0x80
  
  
  
  ;exiting
  mov ebx,0
  mov eax,1 
  int 0x80

问题根源

  • 原代码仅读取输入的第一个字符(mov eax,[num1]取的是num1指向的第一个字节),完全未处理多位数的后续位
  • 多位数转十进制需要逐位计算:比如输入"12",要执行1*10 + 2的逻辑,原代码没有这个转换步骤
  • 结果输出时,若和为多位数(比如12+34=46),直接加'0'只能得到单个字符,无法输出完整数字

解决方案步骤

  1. 扩展输入缓冲区:给num1、num2分配足够空间(比如10字节),支持更长的多位数输入
  2. 实现多位数转十进制函数:遍历输入的每个字符,直到遇到换行符,通过结果*10 + 当前位数字的逻辑计算出十进制数值
  3. 实现十进制转ASCII输出函数:把计算出的和(十进制)逐位转成ASCII字符,反向存储后再正向输出,确保多位数能正确显示

修改后的完整代码

; 多位数加法程序
section .data
msg1 db "Enter the first number: ", 0xa
len1 equ $ - msg1
msg2 db "Enter the second number: ", 0xa
len2 equ $ - msg2
msg3 db "The sum is: "
len3 equ $ - msg3
newline db 0xa

section .bss
num1 resb 10    ; 支持最多9位数字+换行符
num2 resb 10
sum_buffer resb 10 ; 存储转换后的和的ASCII

section .text
global _start

_start:
    ; 提示输入第一个数
    mov edx, len1
    mov ecx, msg1
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; 读取第一个数
    mov edx, 10
    mov ecx, num1
    mov ebx, 0
    mov eax, 3
    int 0x80

    ; 提示输入第二个数
    mov edx, len2
    mov ecx, msg2
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; 读取第二个数
    mov edx, 10
    mov ecx, num2
    mov ebx, 0
    mov eax, 3
    int 0x80

    ; 转换num1为十进制
    mov ecx, num1
    call str_to_int
    mov esi, eax ; 保存第一个数到esi

    ; 转换num2为十进制
    mov ecx, num2
    call str_to_int
    add esi, eax ; 计算两数之和,保存到esi

    ; 输出结果提示
    mov edx, len3
    mov ecx, msg3
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; 将和转换为ASCII字符串
    mov eax, esi
    mov ecx, sum_buffer
    call int_to_str

    ; 输出转换后的和
    mov edx, eax ; int_to_str返回字符串长度
    mov ecx, sum_buffer
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; 输出换行
    mov edx, 1
    mov ecx, newline
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; 退出程序
    mov ebx, 0
    mov eax, 1
    int 0x80

; 字符串转十进制函数
; 输入:ecx = 字符串地址
; 输出:eax = 转换后的十进制数
str_to_int:
    xor eax, eax ; 初始化结果为0
.next_char:
    movzx edx, byte [ecx] ; 读取当前字符
    cmp dl, 0xa ; 判断是否是换行符
    je .done
    sub dl, '0' ; ASCII转数字
    imul eax, 10 ; 结果*10
    add eax, edx ; 加上当前数字
    inc ecx ; 指针后移
    jmp .next_char
.done:
    ret

; 十进制转ASCII字符串函数
; 输入:eax = 十进制数,ecx = 输出缓冲区地址
; 输出:eax = 字符串长度
int_to_str:
    mov ebx, 10 ; 除数10
    xor esi, esi ; 计数器,记录数字位数
.next_digit:
    xor edx, edx
    div ebx ; eax=商,edx=余数
    add dl, '0' ; 余数转ASCII
    mov [ecx + esi], dl ; 存储到缓冲区(反向)
    inc esi
    test eax, eax ; 判断商是否为0
    jnz .next_digit

    ; 反转字符串(因为是反向存储的)
    mov eax, esi ; 保存长度
    xor esi, esi
    dec eax
.reverse_loop:
    cmp esi, eax
    jge .reverse_done
    mov dl, [ecx + esi]
    mov dh, [ecx + eax]
    mov [ecx + esi], dh
    mov [ecx + eax], dl
    inc esi
    dec eax
    jmp .reverse_loop
.reverse_done:
    mov eax, esi ; 返回字符串长度
    ret

代码说明

  • str_to_int函数:遍历输入字符串,把每个ASCII字符转成数字,通过结果*10 + 当前数字的方式计算出十进制数值
  • int_to_str函数:把十进制数不断除以10取余数,转成ASCII后反向存储,再反转得到正确顺序的字符串
  • 缓冲区扩展到10字节,支持输入9位以内的整数(需要更长位数可继续扩大缓冲区)

内容的提问来源于stack exchange,提问作者drkcutie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:54:52