Добавление чисел, когда сумма больше 9 - PullRequest
0 голосов
/ 26 июня 2018
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

Как видите, результат: Сумма::, которая является символом выше '9' в диаграмме ASCII.

Как я могу заставить его распечатать 10?

1 Ответ

0 голосов
/ 26 июня 2018

Результат (EAX) находится в ЦП в формате, который INTEL называет «целым числом». Сначала вы должны извлечь единичные десятичные цифры, а затем сохранить их в строку ASCII, которую вы можете отобразить. Обычный метод заключается в многократном делении целого числа на 10 и сохранении остатка. Google для "ассемблировать конвертировать целочисленную строку", и вы получите много исчерпывающих объяснений.

Это ваша программа делает это:

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
...