0

[Assembly x86-64]

Specifically, I am trying to convert 137,799 to a tetradecimal and then into an ASCII value, that should be "3830B" but I am getting "3830;", so my last digit is wrong for some reason. Here's my code:

; Part 1 - Successive division

mov eax, dword [iNum1] ; get the integer 137,799
mov rcx, 0 ; digitCount = 0
mov ebp, 14 ; set for dividing by 14

divideLoop:
            mov edx, 0
            div ebp ; divide by 14

            push rdx ; push remainder
            inc rcx

            cmp eax, 0 
            jne divideLoop
; -----
; Part 2 - Convert remainders and store

mov rbx, num1String ; get addr of string
mov rsi, 0 ; index = 0 

popLoop:
        pop r8
        add r8b, "0" ; converting to ASCII

        mov byte [rbx+rsi], r8b
        inc rsi
        loop popLoop    

mov byte [rbx+rsi], NULL

I don't see what I am doing wrong. Any help would be appreciated.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Vroryn
  • 125
  • 6
  • 2
    Look at the ASCII table. The letters A, B, C... do **not** follow directly after 9. – rkhb Sep 16 '18 at 07:39
  • Note that `loop` is inefficient (but maybe won't slow down any more than `div`), and you don't need to push/pop. Just start from the end of a buffer. See [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/a/46301894) for a simple base-10 function (where you can drop in a table lookup instead of `add edx, '0'`). – Peter Cordes Sep 16 '18 at 07:47

1 Answers1

2

Your mistake is adding the number you got to the letter '0':

    add r8b, "0" ; converting to ASCII

This works for digits, as 0 to 9 are contiguous in ASCII, but after the digits there are some symbols before the alphabet starts. Take a look at this table:

https://www.torsten-horn.de/techdocs/ascii.htm

The easiest way is to add a lookup-table in your program ("0123456789AB") and then use the number you got to index the correct character.

table: .string "0123456789AB"
// ...
mov r8b, [table+r8b]
tkausl
  • 13,686
  • 2
  • 33
  • 50
  • 1
    Note that `symbol + register` only works in position-dependent code on systems where symbols are in the low 32 bits of address space (e.g. Linux but not OS X). But yes, a digit table lookup is a good way to do conversions to bases higher than 10. In PIE / PIC code, you'd want the table base address in a register from a RIP-relative LEA, but using the table base right in the addressing mode is good when it's usable. – Peter Cordes Sep 16 '18 at 07:45