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

x86 32位NASM中实现三位数加999并输出结果的问题

Fixing Carry Handling in Your 3-digit + 999 Assembly Program

Hey there! Let's work through that carry issue you're facing. The core problem is that your current code only handles the three digits of the input and addition, but doesn't account for the final carry that would create the fourth digit (the thousands place) when needed. Plus, we need to adjust how we store the results to make sure the output is in the correct order. Let's break down the fixes step by step:

What's Wrong with the Original Code

  • Your loop processes the three digits correctly with adc and aaa, but you're storing each result in the same index as the input digits. This leaves no space for the thousands-place carry.
  • When aaa sets the carry flag (CF) after the final (hundreds-place) addition, there's no code to capture that carry and turn it into the leading digit of your four-digit result.

Modified Code with Explanations

Here's the fixed version of your code, with comments explaining the key changes:

section .data
numToAdd db "999",0x00
userPrompt db "Please enter a 3 digit number (000-999):", 0x0a, 0x00
len_userPrompt equ $-userPrompt
section .bss
userNum resb 4 ; user input: (3 digit num + \n)
resultNum resb 4 ; Stores 4-digit result as ASCII string
section .text
global main
main:
    ; Print prompt
    mov eax, 0x04
    mov ebx, 0x01
    mov ecx, userPrompt
    mov edx, len_userPrompt
    int 0x80

    ; Read user input
    mov eax, 0x03
    mov ebx, 0x00
    mov ecx, userNum
    mov edx, 4
    int 0x80

    ; Initialize registers for addition loop
    mov edx, 2          ; Start with the ones place (index 2 of input strings)
    mov ecx, 3          ; Loop 3 times (ones, tens, hundreds)
    clc                 ; Clear carry flag before starting additions

loop_here:
    mov al, [numToAdd + edx]   ; Get the corresponding digit from 999
    adc al, [userNum + edx]    ; Add user's digit + carry from previous step
    aaa                        ; Adjust to BCD, sets CF if there's a carry
    pushf                      ; Save carry flag (add will modify flags)
    add al, 0x30               ; Convert BCD result back to ASCII
    popf                       ; Restore carry flag for next iteration
    mov [resultNum + edx + 1], al  ; Store result in the correct position (ones→index3, tens→2, hundreds→1)
    dec edx
    loop loop_here

    ; Handle the final carry for the thousands place
    mov al, '0'
    adc al, 0x00          ; If CF is set, al becomes '0'+1='1'; stays '0' otherwise
    mov [resultNum], al   ; Store thousands digit as first character in result

    ; Print the 4-digit result
    mov eax, 0x04
    mov ebx, 0x01
    mov ecx, resultNum
    mov edx, 0x04
    int 0x80

    ; Exit program
    mov eax, 0x01
    int 0x80

Key Fixes Explained

  1. Result Storage Adjustment: We now store each digit result in resultNum + edx + 1 instead of resultNum + edx. This shifts the ones/tens/hundreds results to the right by one position, leaving the first index (0) free for the thousands digit.
  2. Carry Capture for Thousands Place: After the loop finishes, we check the carry flag with adc al, 0x00. If there's a carry from the hundreds-place addition, this turns our initial '0' into '1', which we store as the leading digit of the result.
  3. Correct ASCII Conversion: The pushf/popf pair preserves the carry flag through the ASCII conversion step, ensuring the next iteration's adc uses the correct carry value.

Testing this code with inputs like 100 will output 1099, and 999 will output 1998—exactly what you need!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:47:28