user12271878
user12271878

Reputation:

How to add the digits of number in assembly x86

I'm working on a program in assembly language that will compute the sum of the digits of an integer that will be inputted by the client. The number will always be 10 digits long. I am very new to assembly, and I have no idea how to proceed. Here is what I have written so far:

        SECTION .data

msg1:   db "Enter a number 10 digits long: "
len1:   equ $-msg1

msg2:   db "The sum of the digits is "
len2:   db $-msg2


        SECTION .bss

num:    resb 10
sum:    resb 3


        SECTION .text
        global _start

_start: nop

start:

        ;prompt for number
        mov     eax, 4
        mov     ebx, 1
        mov     ecx, msg1
        mov     edx, len1
        int     080h

        ;input number
        mov     eax, 3
        mov     ebx, 0
        mov     ecx, num
        mov     edx, 10
        int     080h

init:
        mov     esi, num
        mov     edi, sum

add_digits:

        ;loop 10 times
        ;retrieve next digit
        ;add '0' to convert to number
        ;add to sum

        ;subtract 0 to sum


        ;print results
        mov     eax, 4
        mov     ebx, 1
        mov     ecx, msg2
        mov     edx, len2
        int     080h

        mov     eax, 4
        mov     ebx, 1
        mov     ecx, sum
        mov     edx, 3
        int     080h

        ;exit
exit:
        mov     eax, 1
        mov     ebx, 0
        int     080h        

I just need to know how to implement the pseudocode in "add_digits". Also, let me know if I have written any of code above poorly/wrong. Greatly appreciated.

Upvotes: 0

Views: 4848

Answers (3)

Frank Kotler
Frank Kotler

Reputation: 3119

  1. since sys_read always returns the linefeed - won't return without it - I would allocate 11 bytes for the buffer and put 11 in edx for sys_read. You might want to flush the buffer too...
  2. you want to subtract '0' to convert from character to number, and add '0' to convert from number to character. Your comments have it backwards.
  3. since we know, per the "specification", that the sum will not exceed 90, which will fit in a byte and can be represented in two characters, yeah there's a way to avoid div...

    ; sum in al...
    aam ; split the byte in al into two digits in al and ah
    add ax, 3030h ; add '0' to both digits
    xchg al, ah  ; swap 'em into right order
    mov [edi], ax ; store both characters in "[sum]"
    mov byte [edi + 2], 10 ; linefeed after printing it?
    

(WARNING untested code!) That's nice and short, but limited in the range of numbers it'll convert - handy for "time" numbers. I'd learn to do it with div and/or learn to use the C library functions, but if my shakey memory serves, that should do it.

Upvotes: 0

phuclv
phuclv

Reputation: 41764

If you read the number into memory as binary, you'll need to extract the digits from the number again, i.e you need to convert from binary to decimal. To convert between number systems you need to divide (in this case divide by 10) or use some special algorithms. There's double dabble to convert from binary to decimal without division, but maybe it's slower than division on architectures support divide operation.

The easiest way is reading the digits one-by-one and add it to the sum right away, or read the whole number as string and then add the characters

Upvotes: 0

Seva Alekseyev
Seva Alekseyev

Reputation: 61351

Read up on the divide AKA div instruction, how it gives you both the quotient and the remainder. Then think about the relationship between retrieving digits of a number and division by 10.

Upvotes: 3

Related Questions