0
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

My code is there: https://ideone.com/uPw6UW

As you can see, the result is: The sum is: : , which is the character above '9' in ASCII chart.

How can I make it print out 10 ?

rkhb
  • 14,159
  • 7
  • 32
  • 60
z3l
  • 23
  • 2
  • 3
    Well, do you see character "10" in ASCII table? I don't. You can't print single character "10", you will have to resolve it in other way. (maybe also check https://stackoverflow.com/tags/x86/info ) (BTW your question title is quite wrong.. so if you remove addition, and do just `number1 dd 10`, will it work? Your problem is not in addition at all, it's just about printing/formatting [correct] result value) – Ped7g Jun 26 '18 at 11:37
  • 2
    Furthermore `mov [sum], eax` stores 32 bit value into memory (32 bit = 4 bytes), but you reserve only single byte in `sum resb 1`, so you are overwriting 3 more bytes than you reserved. Unplanned memory overwrite is one of the toughest common bugs to find (as the behaviour tends to be very random and rarely connected to the part which did overwrite the values originally, the bug often demonstrates much later in completely unrelated situation), while programming in assembly (and even C and C++). – Ped7g Jun 26 '18 at 11:42
  • You need to write a routine that converts an integer to a string. – m0skit0 Jun 26 '18 at 16:34
  • Almost a duplicate of [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/q/13166064), which has a more efficient int->string function (just decrement a pointer from the end of a buffer instead of push/pop to reverse). – Peter Cordes Jun 26 '18 at 21:46

1 Answers1

2

The result (EAX) resides in the CPU in a format that INTEL calls "integer". You have first to extract the single decimal digits and then store them to an ASCII string which you can display. The usual method is to repeatedly divide the integer by 10 and store the remainder. Google for "assembly convert integer string" and you'll get a lot of exhaustive explanations.

This is your program doing it:

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
rkhb
  • 14,159
  • 7
  • 32
  • 60