Converting a number into tetradecimal/ASCII

4313 views assembly
5

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

answered question

Look at the ASCII table. The letters A, B, C... do not follow directly after 9.

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? for a simple base-10 function (where you can drop in a table lookup instead of add edx, '0').

1 Answer

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]

posted this

Have an answer?

JD

Please login first before posting an answer.