首页 > 解决方案 > 加法,当总和大于 9 时

问题描述

segment .data
    msg db "The sum is: " 
    len equ $-msg
    number1 dd 7
    number2 dd 3

segment .bss
    sum resb 1

section .text
    global _start

_start:
    ; Addition
    mov eax, [number1]
    mov ebx, [number2]
    add eax, ebx
    add eax, '0'
    mov [sum], eax

    ; Output
    mov ecx, msg    
    mov edx, len
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; Output
    mov ecx, sum
    mov edx, 1
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; Exit code
    mov eax, 1
    mov ebx, 0
    int 0x80

我的代码在那里:https ://ideone.com/uPw6UW

如您所见,结果为: 和为: : ,即 ASCII 图表中 '9' 上方的字符。

我怎样才能让它打印出 10 ?

标签: assemblynasm

解决方案


结果 (EAX) 以 INTEL 称为“整数”的格式驻留在 CPU 中。您必须首先提取单个十进制数字,然后将它们存储到您可以显示的 ASCII 字符串中。通常的方法是将整数反复除以 10 并存储余数。谷歌“汇编转换整数字符串”,你会得到很多详尽的解释。

这是你的程序这样做:

segment .data
    msg db "The sum is: "
    len equ $-msg
    lf db 0x0A
    number1 dd 7
    number2 dd 3

segment .bss
    sum resb 40                 ; 40 Bytes for an ASCII string
    sum_len resd 1

section .text
    global _start

_start:
    ; Addition
    mov eax, [number1]
    mov ebx, [number2]
    add eax, ebx

    ; Convert the number to a string
    mov edi, sum                ; Argument: Address of the target string
    call int2str                ; Get the digits of EAX and store it as ASCII
    sub edi, sum                ; EDI (pointer to the terminating NULL) - pointer to sum = length of the string
    mov [sum_len], edi

    ; Output "The sum is: "
    mov ecx, msg
    mov edx, len
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; Output sum
    mov eax, 4
    mov ebx, 1
    mov ecx, sum
    mov edx, [sum_len]
    int 0x80

    ; Output Linefeed
    mov eax, 4
    mov ebx, 1
    mov ecx, lf
    mov edx, 1
    int 0x80

    ; Exit code
    mov eax, 1
    mov ebx, 0
    int 0x80

int2str:    ; Converts an positive integer in EAX to a string pointed to by EDI
    xor ecx, ecx
    mov ebx, 10
    .LL1:                   ; First loop: Save the remainders
    xor edx, edx            ; Clear EDX for div
    div ebx                 ; EDX:EAX/EBX -> EAX Remainder EDX
    push dx                 ; Save remainder
    inc ecx                 ; Increment push counter
    test eax, eax           ; Anything left to divide?
    jnz .LL1                ; Yes: loop once more

    .LL2:                   ; Second loop: Retrieve the remainders
    pop dx                  ; In DL is the value
    or dl, '0'              ; To ASCII
    mov [edi], dl           ; Save it to the string
    inc edi                 ; Increment the pointer to the string
    loop .LL2               ; Loop ECX times

    mov byte [edi], 0       ; Termination character
    ret                     ; RET: EDI points to the terminating NULL

推荐阅读