This is my best effort to code an x86 32 bits to get an unsigned int (4 bytes) and convert it into a string. My strategy was successively divide the number by ten and fulfill the remainder of the div according its position in the heap pre-allocated string. I am assuming the bigger value has 10 digits at most.
File i2a.s:
# convert integer to ASCII
.section .data
num:
.long 123456789
str:
# 0123456789A
.string " \n"
len:
.long .-str
.section .text
.globl _start
_start:
# last index of str
lea str+0xa, %edi
# initialize eax
mov num, %eax
loop:
# divide
xor %edx, %edx
mov $0xa, %ecx
div %ecx # quocient: EAX / remainder: EDX
# convert remainder to ASCII
add $0x30, %edx
# store it in str[i--]
mov %dl, -1(%edi)
dec %edi
# if quocient is zero, we're done.
cmp $0, %eax
je print
# if i == 0, we're done.
cmp str, %edi
je print
# repeat.
jmp loop
print:
# print content of str
mov $4, %eax
mov $1, %ebx
lea str, %ecx
# where the generated string starts?
# str[%edi]
sub $str, %edi
add %edi, %ecx
# what is the final length of str?
# len -= %edi
mov len, %edx
sub %edi, %edx
int $0x80
exit:
mov $1, %eax
mov %edx, %ebx
int $0x80
I know there are some criticism about div and its slow execution. Please, fell free to criticize it as well as to point out caveats, tips, and tricks.
Simple script I'm using to build it: (it will create bin directory in cwd)
#! /bin/bash
# binaries output directory (objects and executables are placed there)
OUTDIR=bin
[ -d $OUTDIR ] || mkdir $OUTDIR
as --32 $1.s -o $OUTDIR/$1.o \
&& ld -m elf_i386 $OUTDIR/$1.o -o $OUTDIR/$1 \
&& $OUTDIR/$1
Usase:
./build i2a
mov 5, %eaxinstead ofmov EAX, 5. :) \$\endgroup\$