Let's say that 1A (26 in hex) is stored in the EAX register. How can I convert that to decimal and then display it as output? Is there any Irvine function for this, or is there another way to do it?
I have no idea if the Irvine library contains such a thing; I've never used that library.
(And I hope that I'm not about to solve a homework assignment for somebody, just sayin'...)
This is a pretty straightforward exercise in plain x86 assembly, using repeated division/modulus. In C, the basic algorithm looks something like this:
void ConvertToDecimal(unsigned int n, char *output)
{
char buffer[16];
char *dest = buffer + 15;
/* Perform repeated division, which outputs digits in reverse
order. But we put them in the buffer in reverse order, too,
so they end up coming out in the correct order overall. */
*--dest = '\0';
if (n == 0) {
*--dest = '0';
}
else {
while (n > 0) {
*--dest = n % 10 + '0';
n /= 10;
}
}
/* Copy the generated digits to the output. */
strcpy(output, dest);
}
The assembly version is really a matter of doing the same basic technique. (And starting from a high-level description of the problem in a language like C and then porting that solution to assembly is one way to solve problems like this.)
So starting with the number in eax
, and an output pointer to the target buffer in ebx
, you end up with something like this:
ConvertToDecimal:
push edi ; Preserve registers we're going to use.
sub esp, 16 ; Make room for a local buffer on the stack.
mov edi, esp ; edi will act like 'dest' does in the C version.
mov ecx, 10 ; We'll be repeatedly dividing by 10, and the
; div instruction doesn't let you just say 'div 10'.
dec edi
mov byte ptr [edi], 0 ; Write the trailing '\0'.
cmp eax, 0 ; If n == 0...
ja l1 ; If it's more than zero, run the loop.
dec edi
mov byte ptr [edi], '0' ; Write a '0' to the output.
jmp l2
; Main division loop.
l1: xor edx, edx ; Zero out edx in preparation for the division.
div ecx ; Divide and modulus edx|eax by 10.
; eax gets the quotient; edx gets the remainder.
add edx, '0' ; Change edx from 0-9 to '0'-'9'.
dec edi
mov byte ptr [edi], dl ; Write the next digit, which is now in dl.
cmp eax, 0
ja l1 ; Go back and do it again until we reach zero.
; Copy the result to the destination.
l2: mov al, byte ptr [edi] ; Read the next character from edi...
inc edi
mov byte ptr [ebx], al ; ...and write that character to ebx.
inc ebx
cmp al, 0 ; Copy until we reach the trailing 0 byte.
jnz l2
mov eax, ebx ; As a bonus for the caller, set the return register
dec eax ; to where we wrote the last byte.
add esp, 16 ; Clean up the buffer on the stack.
pop edi ; Restore the registers we used.
ret ; And we're done.
For the record, I haven't run the code above, but it should work.
As for displaying it as output, you'll need whichever library function or interrupt you can use to print a string. In the ol' DOS days, I'd have just repeatedly called int 10h
...