# Converting a number into tetradecimal/ASCII

4313 views
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.

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'`).

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