Assembly code that returns the sum of the even digits of a number

41 Views Asked by At
global main
section .data
msgeven db "The sum of the even digits in the number is:",0
sum db 0
uc db 0
c db 0
num db 234



section .text


main:

mov ax,[num]
_calculatesum:
cmp ax,'0'

je calculate_sum_done
mov r8b,10
div r8b
mov [uc],ah
mov[c],al

xor ebx,ebx
mov bl,[uc]
test bl,1
jnz _skip_odd_digit
mov cl,[sum]
add cl,bl

_skip_odd_digit:
jmp _calculatesum


calculate_sum_done:
add cl,'0'
mov [sum],cl
mov rax,1
mov rdi,1
mov rsi,msgeven
mov rdx,50
syscall

mov rax,1
mov rdi,1
mov rsi,sum
mov rdx,1
syscall

mov rax,60
mov rdi,0
syscall

I have this assembly code that should return the sum of the even digits in num, in this case 6, but although I can run the program I get this The sum of the even digits in the number is:00�0 and i don't really know how to solve this error

1

There are 1 best solutions below

0
Sep Roland On
The sum of the even digits in the number is:00�0

You are printing too many characters to the screen. The msgeven text has 44 characters, so you should not be using mov rdx,50 in your syscall. Solve this with:

msgeven db  "The sum of the even digits in the number is:"
length  equ $ - msgeven

...

mov  edx, length
syscall

What you currently output as the result, does not reflect the calculation that is going on:

  • You forget to update the sum variable and thus only the very last digit will make it (somewhat) to the result. The best solution does not need to use the sum variable at all. See below.
  • It is most probable for the loop to run for too long since your loop-ending-condition is cmp ax,'0' which is the same as cmp ax, 48 and not at all the test for zero that is needed.
  • The size error on mov ax,[num] for the byte-sized variable is probably harmless as it would have loaded a zero in AH.

A solution

num     db  234
msgeven db  "The sum of the even digits in the number is: "
result  db  "??"
length  equ $ - msgeven

  ...

  movzx eax, byte [num]
  mov   ebx, 10          ; CONST divider
  xor   ecx, ecx         ; Result
.CalculateSum:
  xor   edx, edx
  div   ebx              ; EDX:EAX / EBX  --> EAX is quotient
  test  dl, 1            ;                --> EDX is remainder
  jnz   .SkipOddDigit
  add   ecx, edx
.SkipOddDigit:
  test  eax, eax
  jnz   .CalculateSum

For your test case number 234 the result is 6 and that is just a single character, so adding '0' would be sufficient. However, the biggest result that you can expect is the 2-character number 16 coming from test case number 88.

  mov   eax, ' '
  cmp   cl, 10
  jb    .OneChar
  add   eax, 17        ; -> AL='1'
  sub   ecx, 10
.OneChar:
  mov   [result], al
  add   cl, '0'
  mov   [result + 1], cl

  mov   edx, length
  mov   rsi, msgeven
  mov   edi, 1
  mov   eax, 1
  syscall