flat assembler
Message board for the users of flat assembler.

Index > DOS > how to do binary to decimal?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 22 Jul 2008, 21:09
How would I go about doing binary to decimal to display on screen? I'm very confused about this. All things I see to do bin to dec would just do bin to hex in computers....ugh...like http://en.wikipedia.org/wiki/Binary_numeral_system#Decimal that. I need to convert to string somehow. But how would I figure out how to do that?

_________________
----> * <---- My star, won HERE
Post 22 Jul 2008, 21:09
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 22 Jul 2008, 22:49
divide by ten.

modulo will contain the less significant digit.

Code:

num dd 32133
string rb 100
.end db 0
...
mov edi,string.end
mov eax,num
mov byte[edi],0
inc edi
mov ebx,10
next:
xor edx,edx
idiv eax,ebx
and dl,0fh
je @f
mov [edi],dl
dec edi
jmp .next
@@:
or eax,eax
jne .next
ret
    


something like that. Very Happy
Post 22 Jul 2008, 22:49
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 22 Jul 2008, 23:25
Would something like THIS be faster? How would I implement it? With BCD, it would be much easier to display.

_________________
----> * <---- My star, won HERE
Post 22 Jul 2008, 23:25
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 22 Jul 2008, 23:32
mmmh, note that CPUs are not as flexible as FPGAs are Smile
Post 22 Jul 2008, 23:32
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 22 Jul 2008, 23:51
I found this neat c++ code that does what I want, very small to implement. Works up to 99, To do over that, you would need to modify it.

unsigned char chartobcd(unsigned char n)
{
return ((n / 10) << 4) | (n % 10);
}

In asm, its simple. (the 'hexword' routine was written by rugxulo and displays a hex number to screen)
Code:
org 100h

start:
mov ax,1100011b  ;99 in decimal
mov bl,10        ;10 for division
div bl           ;divide. the quotient is in al, the remainder is in ah
mov dl,ah        ;save remainder
shl ax,4         ;shift quotient to ah
or al,dl         ;put remainder in al
call hexword     ;call routine to display it     

key:
in al,60h
dec al
jnz key
ret

hexword:
          mov cx,2
.begin: 
          push cx 
          mov cl,4 
          rol al,cl
          pop cx 
          push ax 
          and al,0Fh 
          cmp al,10 
          sbb al,69h 
          das 
          int 29h 
          pop ax 
          loop .begin 
.ret: 
          ret
    

Why wont a rol ax,4 work to replace the saving and putting back of the remainder??

_________________
----> * <---- My star, won HERE
Post 22 Jul 2008, 23:51
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 23 Jul 2008, 02:39
> How would I go about doing binary to decimal to display on screen?

Download an example Idea http://board.flatassembler.net/topic.php?t=8670

> Why wont a rol ax,4 work to replace the saving and putting back of the remainder??

ROL AX, 1 - 8086 compatible
ROL AX, CL - 8086 compatible
ROL AX, 4 - not 8086 compatible

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 23 Jul 2008, 02:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20589
Location: In your JS exploiting you and your system
revolution 23 Jul 2008, 04:24
DOS386 wrote:
ROL AX, 1 - 8086 compatible
ROL AX, CL - 8086 compatible
ROL AX, 4 - not 8086 compatible
Sure, but why is that relevant? Who uses an 8086 nowadays?
Post 23 Jul 2008, 04:24
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 23 Jul 2008, 04:53
> but why is that relevant?

1st the guy asked
2nd one can see such code and get irritated about it
3rd one can code 8086-compatible, just for the heck Laughing
Post 23 Jul 2008, 04:53
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 23 Jul 2008, 21:28
Ok, I found one written by thimis thats only 24 bytes and works with up to FFFFh
It's in This Thread.
Code:
dispnum:
        mov cx,10             ; print ax number in decimal 
dn: 
        xor dx,dx 
        div cx 
        push dx 
        or ax,ax 
        jz @f 
        call dn 
@@: 
        pop dx 
        add dl,30h 
        mov ah,2 
        int 21h 
        ret
    

It recursively calls itself until all numbers are done.
(It's somewhat confusing to me, but I think I understand it.)

_________________
----> * <---- My star, won HERE
Post 23 Jul 2008, 21:28
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 24 Jul 2008, 20:17
I'm having trouble modifying thimis' code to print ','s
The modified code only prints '65,' and then halts.

My code is in between ;;new blocks
fch is comma minus 30h
Code:
org 100h

mov ax,03h
int 10h

mov ax,65535
call dispnum

key:
in al,60h
dec al
jnz key
ret 

dispnum:
        mov cx,10             ; print ax number in decimal
        ;;new
        mov bx,3
        ;;new
dn:
        xor dx,dx
        div cx
        push dx
        ;;new
        dec bx
        jnz @f
        mov bx,3
        push 0fch   
@@:
        ;;new
        or ax,ax
        jz @f 
        call dn 
@@: 
        pop dx
        add dl,30h 
        mov ah,2 
        int 21h
        ret
    


I'm experimenting with using colors to make certain words stand out more. Mainly, names in red

_________________
----> * <---- My star, won HERE
Post 24 Jul 2008, 20:17
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 794
Location: Adelaide
sinsi 25 Jul 2008, 00:12
Because that code is recursive, the extra "push 0fch" is mucking up the return address - in the case of 65535 it actually returns to address 0005, which crashes. Here's some old code I used to use (before I found something 100x faster)
Code:
number_to_dec:  pusha
                mov si,10
                sub bx,bx
  .next:        sub dx,dx
                div si
                push dx
                inc bh
                test ax,ax
                jz .reverse
                inc bl
                cmp bl,3
                jnz .next
                push ','-'0'
                inc bh
                sub bl,bl
                jmp .next
  .reverse:     pop ax
                add al,'0'
                call printchar
                dec bh
                jnz .reverse
                popa
                ret
    

It uses BH to keep track of pushes and BL to count when a comma is needed. Start using EAX,EDX etc and it does 32-bit numbers too.
Post 25 Jul 2008, 00:12
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 25 Jul 2008, 02:05
Ok, I sat down for 10min and rewrote thimis' code.
IT WORKS.
I don't entirely understand why bx has to be set to 4, but it works and thats all that matters
Code:
org 100h

mov ax,03h 
int 10h 

mov ax,0FFFFh
call dispnum 

key: 
in al,60h 
dec al 
jnz key 
ret  

dispnum:
        mov cx,10    ;for dividing
        mov bx,4     ;for comma count
dn:
        xor dx,dx    ;zero out dx
        dec bx       ;decrease bx
        jnz @f       ;if bx is zero that means comma has been found
        mov bx,4     ;put bx back to 4
        push 0fch    ;push comma-30h
        jmp @123     ;jmp to call(we dont call here for many reasons)
@@:
        div cx       ;if not, divide by 10
        push dx      ;push remainder
        or ax,ax     ;test for zero
        jz @f        ;if it is go to displayer
@123:
        call dn      ;call whole routine again
@@:
        pop dx       ;pop first number off stack
        add dl,30h   ;make it ascii
        mov ah,2     ;function 2 is display character
        int 21h      ;display it
        ret          ;basically a loop and then return to caller
    


EDIT: When changed to use eax with numbers up to billions, It still works right. yay Smile
(the div cx needs to be changed to ecx too)

EDIT 2:tried commenting the dispnum routine



EDFED: I kinda ignored your post, sorry. But I saw 32 bits and weird divs and went "WOAH" and just kinda skipped over it. I dont like using 32bit for some reason. Plus, your code just looked a little complex.

_________________
----> * <---- My star, won HERE
Post 25 Jul 2008, 02:05
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 25 Jul 2008, 04:00
I wrote a routine for FAMOS which displays a 32-bit number in any base you choose (usually hex or decimal, but could be binary ou up to base 36 using letters A-Z), with all leading zeros suppressed so you can also control the maximum no of digits displayed. Would easily convert to DOS if you're intereted.
Post 25 Jul 2008, 04:00
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
windwakr 25 Jul 2008, 04:30
Nah, the routine I have is good enough
Post 25 Jul 2008, 04:30
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 25 Jul 2008, 04:40
thanks anyway, for the opportunity to give it to you.
Post 25 Jul 2008, 04:40
View user's profile Send private message Visit poster's website Reply with quote
Shahada



Joined: 25 Jul 2008
Posts: 77
Shahada 25 Jul 2008, 10:07
@neville
I'm interested to see the routine. Where can I find the source code for FAMOS? Or it is not open source? What lincense it has?
Post 25 Jul 2008, 10:07
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 26 Jul 2008, 06:28
Shahada wrote:
interested to see the routine. ... Or it is not open source?


See above, my example is open source. Idea

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 26 Jul 2008, 06:28
View user's profile Send private message Reply with quote
Shahada



Joined: 25 Jul 2008
Posts: 77
Shahada 26 Jul 2008, 07:10
DOS386 wrote:
See above, my example is open source. Idea


I saw yor example, but it is better to have more examples, so I want to see neville's way of doing it. Do you know more detailes about FAMOS?
Post 26 Jul 2008, 07:10
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 27 Jul 2008, 02:28
You can do it all without any slow DIVs at all. (In fact, you can supposedly do the whole conversion faster than a single DIV opcode.) See Terje's method (386+). However, it has leading zeros and no commas.

If you want 8086 code with commas that still works with a 32-bit number, try my bin2dec routine (although it puts the entire ASCIIZ result in a buffer backwards, so you have to either reverse it before output or output in reverse). Unlike the first method, it's not optimized for speed.

EDIT: "div cx" (or any word register / memory value) always uses DX:AX (which is a 32-bit number). "div cl" is faster, and that's all you really need if you only want a 16-bit number (e.g. value in AX).

So no, you don't need 386+ to do 32-bit arithmetic. Heck, you can even do 64-bit numbers too (on an 8086!). See here ("bignum").


Last edited by rugxulo on 27 Jul 2008, 02:51; edited 2 times in total
Post 27 Jul 2008, 02:28
View user's profile Send private message Visit poster's website Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 27 Jul 2008, 02:41
windwakr wrote:
I found this neat c++ code that does what I want, very small to implement. Works up to 99, To do over that, you would need to modify it.

unsigned char chartobcd(unsigned char n)
{
return ((n / 10) << 4) | (n % 10);
}


BTW, if you're curious, here's what GCC 4.3.0 outputs for that (no MULs or DIVs!):

Code:
_chartobcd:
   mov     cl, BYTE PTR [esp+4]
        xor     eax, eax
    mov     al, cl
      lea     edx, [eax+eax*4]
    lea     edx, [eax+edx*8]
    lea     edx, [edx+edx*4]
    shr     dx, 8
       shr     dl, 3
       mov     al, dl
      sal     eax, 4
      lea     edx, [edx+edx*4]
    add     edx, edx
    sub     cl, dl
      or      eax, ecx
    ret
    
Post 27 Jul 2008, 02:41
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.