[Assembly] Binary to decimal conversion for 64bit> numbers

This is a discussion on [Assembly] Binary to decimal conversion for 64bit> numbers within the Tech Board forums, part of the Community Boards category; Say you have a value (%rsp):8(%rsp) how would you go about printing this number to stdout in decimal form? One ...

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    101

    [Assembly] Binary to decimal conversion for 64bit> numbers

    Say you have a value (%rsp):8(%rsp) how would you go about printing this number to stdout in decimal form?

    One method would be dividing it by 10 of course recursively but I cant figure out how to apply a divide operation across a 128bit number (using 64bit registers). To test this I have a little program that's doubling the value 2^64 - 2 (18446744073709551614) hens the value when doubled is 2 ^ 65 - 4 (36893488147419103228) and would be stored
    (%rsp)
    00000000000000000000000000000000000000000000000000 00000000000001
    8(%rsp)
    11111111111111111111111111111111111111111111111111 11111111111100
    Code:
    .section	.data
    .text
    	.global main
    
    	.type	main, @function
    main:
    	pushq	%rbp
    	movq	%rsp, %rbp
    	subq	$8, %rsp
    
    	movq	$18446744073709551614, %r13	#our number
    #	movq	%r13, (%rsp)
    	
    	addq	%r13, %r13
    	jnc	nocarry
    	movq	$1, %rbx
    	movq	%rbx, (%rsp)
    	addq	$8, %rsp
    
    nocarry:
    	movq	%r13, (%rsp)
    	
    ###Wanting to print number in decimal, I can output the binary by a recursive div2 operation.  Here the value is at -8(%rsp):(%rsp).
    
    	movl	$0, %eax
    	leave
    	ret
    Converting from decimal to ascii is no problem, and in fact I think the best way to do this is to use printf. Essentially the number has to be converted so 8(%rsp) represents the first 64 decimal bits of the number and (%rsp) would have the binary representation for the most significant decimal part. Eg the number is 36893488147419103228 so after the conversion 8(%rsp) would contain 6893488147419103228 (in binary) and (%rsp) would contain 3.

    So this....
    (%rsp)
    00000000000000000000000000000000000000000000000000 00000000000001
    8(%rsp)
    11111111111111111111111111111111111111111111111111 11111111111100

    Gets converted to this.... (%rsp doesn't necessarily have to refer to the same location)
    (%rsp)
    00000000000000000000000000000000000000000000000000 00000000000011
    8(%rsp)
    01011111101010101001011011110010011000100100011111 11111111111100

    This would allow two printf statements to be executed. There are alternative methods, of course.


    edit -- Btw this program is linked with g++ so `as ./file.s -o file.o && g++ file.o -o file` is how you assembly / link it.
    Last edited by 1veedo; 06-29-2008 at 12:33 PM.
    --

  2. #2
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Passing from a representation in base 2 to a representation in base 10 isn't all that trivial with computers (as you can see). Normally, if you don't care much about efficiency, you would divide successively by 10 (or some power of 10) the number until it equals 0. Which, if you have number spanning more than 1 "word" (in our case, with the x86-64 ISA, a word is 64-bit wide), can mean you'll have to implement an algorithm for dividing such numbers. In fact, it will get dirty quite fast; you should be able to find the representation in base 10 of some 2-words long numbers (like the one in your example) using only the DIV instruction and some well chosen power of 10 divider, else you'll have to go for the big guns.

    So, I would advise you to use a "math" library, like gmp. It's quite easy to use, yet powerful (and quite efficient). The input and output functions on integers are especially what you are looking for. In fact, you would also want to take a look at the mpz_set_str() function.

    On a side note, your assembly code seems a bit broken. Be careful on how you handle the stack.
    Last edited by foxman; 06-29-2008 at 08:58 PM.
    I hate real numbers.

  3. #3
    Registered User
    Join Date
    Dec 2003
    Posts
    101
    What's wrong with the code? Just curious. You do know leave is the same as
    Code:
    movq    %rbp, %rsp
    popq    %rbp
    And yes I do know there are math libraries for this. If this were C I'd probably be using it. I wrote a very inefficient one (floating point) a few months ago and recently in learning 64bit assembly decided to look at this just for the technical aspect. You're probably right though; it's probably best done by division.

  4. #4
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Code:
    main:
    	pushq	%rbp
    	movq	%rsp, %rbp
    	subq	$8, %rsp
    
    	movq	$18446744073709551614, %r13	#our number
    	
    	addq	%r13, %r13
    	jnc	nocarry    // This branch will never be taken
    	movq	$1, %rbx
    	movq	%rbx, (%rsp)
    	addq	$8, %rsp   // After this instruction, %rsp == %rbp
    
    nocarry:
    	movq	%r13, (%rsp)  // Equivalent to "movq %r13, (%rbp)" -- you just trashed (%rbp), but since we are in the "main" function, I'm not sure of the consequences
    	
    	movl	$0, %eax
    	leave
    Don't forget that the PUSH instruction on the x86-64 ISA is "Decrements the stack pointer and then stores the source operand on the top of the stack". So when you write "subq $8, %rsp", you are creating 8 bytes of stack space, which is not enough to hold your 16 bytes value. Personnaly, I would do it this way

    Code:
    main:
    	pushq	%rbp
    	movq	%rsp, %rbp
    	subq	$16, %rsp
    
    	movq	$18446744073709551614, %r13	#our number
    	
    	addq	%r13, %r13
    	jnc	nocarry
    	movq	$1, %rbx
    	movq	%rbx, -16(%rbp)
    
    nocarry:
    	movq	%r13, -8(%rbp)
    
    # Here you want to print -16(%rbp):-8(%rbp)
    	movl	$0, %eax
    	leave
    So you don't have to care about the value of %rsp.
    I hate real numbers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Decimal to binary conversion
    By blckspder in forum C Programming
    Replies: 5
    Last Post: 04-07-2005, 01:38 PM
  2. binary to decimal
    By miryellis in forum C Programming
    Replies: 7
    Last Post: 03-14-2004, 08:35 PM
  3. binary to decimal
    By jk81 in forum C Programming
    Replies: 1
    Last Post: 09-13-2002, 06:20 AM
  4. Replies: 10
    Last Post: 06-12-2002, 04:15 PM
  5. Binary to decimal conversion help!
    By matrism in forum C Programming
    Replies: 4
    Last Post: 03-25-2002, 12:22 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21