Printing large numbers in ASM

Programming, for all ages and all languages.
Post Reply
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Printing large numbers in ASM

Post by mark3094 »

I want to be able to use interrupt 0x15 to get a memory map before entering protected mode.
I also want to be able to print the base addresses and limits to the screen to confirm the values that I get.

I have written a procedure in ASM to print the number it finds in EAX, which works up until the number is larger than 1073741824. Numbers lower seem fine (not that i've tested them all of course), but anything larger prints the wrong values.

My procedure gets the number and reverses the digits first, then prints each number by dividing it by 10. The code is below.

My thought at this stage is that I must be doing something wrong with the division that's messing up a register.

Any thoughts?

Code: Select all

	MOV		EDX, EAX						;  The number is passed in EAX, and 'saved' temporarily in EDX
	XOR		EBX, EBX						;  EBX is the 'storage' register
	XOR		ECX, ECX
	
	Reverse:
	MOV		EAX, EBX						;  Shift one decimal place left
	PUSH	ECX
	MOV		ECX, 10
	PUSH	EDX
	MUL		ECX
	POP		EDX
	MOV		EBX, EAX

	MOV		EAX, EDX						;  Get the last digit of the number by dividing and taking the remainder
	XOR		EDX, EDX
	DIV		ECX
	POP		ECX
	
	ADD		EBX, EDX
	MOV		EDX, EAX
	INC		ECX								;  Counts the digits to print
	CMP		EAX, 0
	JNZ		Reverse
	
	MOV		EAX, EBX
	

    Print:
	XOR		EDX, EDX						;  Divide by 10 to get last digit
	PUSH	ECX
	MOV		ECX, 10
	DIV		ECX
	POP		ECX
	MOV		EBX, EAX						;  Quotient: EAX -> EBX
	MOV		EAX, EDX						;  Remainder: EDX -> EAX
	
	ADD		AL, 48							;  Print ASCII
	MOV		AH, 0Eh
	INT		10h
	MOV		EAX, EBX

	DEC		ECX
	CMP		ECX, 0							;  Loop until all digits are printed
	JNZ		Print
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Printing large numbers in ASM

Post by mark3094 »

I just figured it out.
The reversed number is too big to fit in a 32-bit register
Some large numbers will work, but some won't.

I'm not sure how to fix this yet, but at least I now know where to start looking :)
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: Printing large numbers in ASM

Post by Minoto »

A simple solution would be to store the ASCII value of each converted digit on the stack -- push a 0 or some other invalid value as a flag first, then push each digit as it's converted. The conversion is done when the quotient is 0, at which point you start popping values off the stack and printing them until you encounter the flag you pushed initially, which you just discard.
Those who understand Unix are doomed to copy it, poorly.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Printing large numbers in ASM

Post by mark3094 »

Minoto wrote:A simple solution would be to store the ASCII value of each converted digit on the stack -- push a 0 or some other invalid value as a flag first, then push each digit as it's converted. The conversion is done when the quotient is 0, at which point you start popping values off the stack and printing them until you encounter the flag you pushed initially, which you just discard.
Thanks. That is a good idea.
However, I have not long finished another solution where I use the stack to store the temporary value that DX was previously doing.
When MUL was being used on the 10th loop, the number was getting so large that the MUL instruction was using DX, which was then getting trashed. Therefore I rearranged things to not use DX as temporary storage, and it now works fine.

I do like your suggestion though. Wish I had have thought of that myself :)
User avatar
Minoto
Member
Member
Posts: 89
Joined: Thu May 12, 2011 7:24 pm

Re: Printing large numbers in ASM

Post by Minoto »

mark3094 wrote:However, I have not long finished another solution where I use the stack to store the temporary value that DX was previously doing.
When MUL was being used on the 10th loop, the number was getting so large that the MUL instruction was using DX, which was then getting trashed. Therefore I rearranged things to not use DX as temporary storage, and it now works fine.)
There's more than one way to do just about everything -- glad to hear you found your own way. :D
Those who understand Unix are doomed to copy it, poorly.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Printing large numbers in ASM

Post by mark3094 »

Minoto wrote: glad to hear you found your own way
Yes, quite stoked to have figured it out myself rather than have the answer handed to me, or even reverse-engineer someone else's :D


http://www.urbandictionary.com/define.php?term=stoked
Post Reply