This needs to be done in pure assembly (ie. no libraries or calls to C).
I understand the essence of the problem: one needs to divide the integer by 10, convert the one-digit remainder to ASCII, output that and then repeat the process with the quotient.
But for some reason, it's just not working. I'm using NASM on x86.
Here's what I have up to now (doesn't output anything, but doesn't throw any assembler errors either):
; integer to output is stored in eax
mov ecx, 10 ; for base 10
loop:
div ecx ;EAX contains the quotient, EDX the remainder
; Do something to EDX to convert it to ASCII, not sure if this is correct
add edx, '0'
push eax ;We'll be playing with EAX to output EDX, save EAX to the stack
mov eax, 4 ; sys_write
mov ebx, 1 ; to STDOUT
mov ecx, edx
mov edx, 1
int 0x80
pop eax ;restore EAX
cmp eax, 0 ;If EAX is 0, our job is done
jnz loop
There are a number of questions similar to this one (namely, this and this), but I'm lost in the implementation. This question (for DOS) was also helpful, but I'm still confused.
I must be missing something here. Thoughts?
There are at least two more problems. beyond the corruption of ecx
that @sarnold mentioned:
div ecx
divides the 64-bit value edx:eax
by ecx
, so you need to ensure that you set edx
to 0 before the division.
The second argument to the write
system call (in ecx
) should be a pointer to a buffer containing the character you want to print, not the character itself.
One way to solve the second problem is to push the register containing the character you want to print on the stack, and then assign the stack pointer esp
to ecx
(the stack pointer points at the most recently pushed item, and x86 stores values little-endian, so the first byte is the low 8 bits). e.g.
push edx ; save value on stack
mov eax, 4 ; sys_write
mov ebx, 1 ; to STDOUT
mov ecx, esp ; first byte on stack
mov edx, 1 ; length = one byte
int 0x80
pop edx ; remove what we pushed (or "add esp, 4" would do just as well here;
; we don't need the actual value again)
That should be enough to get some output...
(But at that point, you might notice a "feature" of your algorithm, and want to re-think how you store the digits that are produced by the division!)
You properly set ecx
to 10
at the top of your routine, but overwrite ecx
later:
mov eax, 4 ; sys_write
mov ebx, 1 ; to STDOUT
mov ecx, edx ;;; oops -- lost the 10
mov edx, 1
int 0x80
Try moving the loop
up one line, so ecx
is re-initialized to 10
each time through the loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With