flat assembler
Message board for the users of flat assembler.

Index > OS Construction > printBinary function

Author
Thread Post new topic Reply to topic
Daedalus



Joined: 25 Mar 2007
Posts: 52
Daedalus
Hey guys,

I tried to code a printBinary function, that, well, prints ax in binary, but for some reason it doesn't work. I've checked the code over and over and well, you know how it goes. By the way, I've tested other functions in this program, so the set up is okay.

First of, code calling printbinary:
Code:
use16
org 0x100

start:
  mov ax, 20            ;so it should print 0...1010
  call printbinary
.return:
ret    


Code:
;printbinary (ax number)
printbinary:
  push ax
  mov cx, 16           ;16 bits in ax
.while:
  cmp cx, 0            ;while cx
  jle .return          ;not je cuz "you never know"
  bsf bx, ax           ;find the first set bit, store index of that bit in bx
  cmp bx, 0            ;
  push cx              ;in case putc changes it
  je .pOne             ;if index == 0, print a 1
  mov al, '0'          ;else a 0 ofc
  call putc
  jmp .next
.pOne:
  mov al, '1'
  call putc
.next:
  pop cx               ;restore saved copy
  dec cx               ;next bit
  rcl ax, 1            ;rotate it one bit left
  jmp .while           ;loop
.return:
  pop ax               ;Pop the copy
  ret                  ;and we're done      


This doesn't work, so I tried another (better) function (due to discovery of bt-mnemonic, hehe)

Code:
;printbinary (ax number)
printbinary:
  push ax
  mov cx, 16           ;16 bits in ax
.while:
  cmp cx, 0            ;while cx
  je .return
  bt ax, 0             ;copies 0th bit into CF, not matter if I change value to 1
  push cx              ;in case putc changes it
  jc .pOne             ;if set, print a 1
  mov al, '0'          ;else a 0 ofc
  call putc
  jmp .next
.pOne:
  mov al, '1'
  call putc
.next:
  pop cx               ;restore saved copy
  dec cx               ;next bit
  shl ax, 1            ;shift left, synonym? Sure this does what I mean tho.
  jmp .while           ;loop
.return:
  pop ax               ;Pop the copy
  ret                  ;and we're done    


Which also doesn't work!

The output is in both cases the same:

C:\w00tos>miscFunc.COM
0000000000000000

If someone can clear things up, or knows a far better way of doing this (i.e. "have you heard about <mnemonic> ?"), thanks in advance,

Nick
Post 27 Feb 2008, 23:37
View user's profile Send private message MSN Messenger Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4240
Location: 2018
edfed
what is this code?
there is a simpler way to print binary.
Code:
bin2ascii:
mov bx,ax
mov cl,16
.next:
mov al,'0'
shr bx
jnc @f
inc al
@@:
call putc
dec cl
jne .next
ret 
    


this works, it can be extended to binary strings up to 65535 bits.
this one is the version for OO?? lib.
it can print very long bit strings from memory.
Code:
num:
;esi = current item
;edi = parent item
.call=0
.x=4
.y=8
.xl=12
.yl=16
.txt=20
.c0=24
.c1=28
.cinv=32
.smooth=36
.num=40
.type=44
.size=32
.bin:
        push eax ebx ecx edx ;save the previous context
        mov eax,[esi+.num]  ;the memory location of bitstring
        push eax
        mov eax,[eax]      ;the addressing is a second stage one.
        mov ecx,[esi+.type] ;bit string leng
        mov edx,[esi+.txt]  ;the text buffer, to write convert in ascii
        lea edx,[edx+ecx]  ;point to the last byte of ascii buffer 
        mov byte[edx],0    ;this is a null terminated string
        dec edx                ;point to first bit image
        mov bh,.size        ;this is the size of one single stream, a dword
.onebit:
        mov bl,'0'
        shr eax,1   ; the lsb is the carry
        adc bl,0   ; add the carry, can be done by a jnc @f, inc bl
        mov [edx],bl ;fill in ascii buffer
        dec edx  ; point to next bit image
        dec bh
        jne @f     ; is the end of bit stream?
        mov bh,32  ; reinit the bitstream
        pop eax      ;load the next dword of the bit string
        add eax,4   ;.
        push eax    ;.
        mov eax,[eax] ;there
@@:
        dec ecx    ; is it the last bit?
        jne .onebit  ;no, continue
        pop eax
        inc edx    
        mov [esi+.txt],edx  ; set the text pointer, to know where the string begins  
        pop edx ecx ebx eax  ; restore the previous context
        call ctxt   ; print the string pointed by [esi+.txt]
        ret

    
Post 27 Feb 2008, 23:57
View user's profile Send private message Visit poster's website Reply with quote
Daedalus



Joined: 25 Mar 2007
Posts: 52
Daedalus
That code was well commented? I think you can understand it if you take a look at it. But your code prints it in reverse no? And I didn't know that shl and shr already set the CF flag (so there's no need for bt) and that dec set the ZF flag. If you leave those out, it's practicly the same code I wrote, only with a push to save CX (in case putc changes it) and the BT and CMP.
Post 28 Feb 2008, 09:28
View user's profile Send private message MSN Messenger Reply with quote
Daedalus



Joined: 25 Mar 2007
Posts: 52
Daedalus
By the way, your "simpler" code produces wrong output as well.

Code:
start:
  mov ax, 20            ;so it should print 0...1010
  call bin2ascii
.return:
ret

;putchar (al char)
putc:
  mov ah, 0x0E
  mov bh, 0x00
  mov bl, 0x07
  int 0x10
ret

bin2ascii:
mov bx,ax
mov cl,16
.next:
mov al,'0'
shr bx, 1
jnc @f
inc al
@@:
call putc
dec cl
jne .next
rer    


output:

C:\w00tos>miscFunc.COM
0111111111111111
Post 28 Feb 2008, 09:39
View user's profile Send private message MSN Messenger Reply with quote
DJ Mauretto



Joined: 14 Mar 2007
Posts: 464
Location: Rome,Italy
DJ Mauretto
20 = 0x14 = 0000 0000 0001 0100

Code:
org 0x100
start: 
   mov     ax,0003h
    int     10h

     mov     ax, 20             
         call    bin2ascii 

.return: 
ret 


bin2ascii: 

      mov     bx,ax 
      mov     cx,16 

.next: 
   xor     ax,ax
       shl     bx,1
        adc     ax,0x30
     call    putc 
       sub     cx,1
        jnz     .next

   ret

;putchar (al char) 
putc: 
        push    bx
  mov     ah, 0x0E 
   mov     bh, 0x00 
   mov     bl, 0x07 
   int     0x10
        pop     bx 
 ret 
    
Post 28 Feb 2008, 10:05
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4240
Location: 2018
edfed
yes, dj moretto is right...
but, if you're a real coder, then, you have to make errors, then correct them, dig into the code to find the solution.
it's not frequent to have the think OK at the first try.

DJ mauretto, i prefer to make it:
Code:
xor al,al
shl bx,1
adc al,'0'
    

isn't it better? explicit, shorter etc...
Post 28 Feb 2008, 10:13
View user's profile Send private message Visit poster's website Reply with quote
Daedalus



Joined: 25 Mar 2007
Posts: 52
Daedalus
hahahahah. My code doesn't work because, tadada, I change AX! That was quite stupid. Nice use of adc Mauretto! Handy mnemonic. Thanks all.
Post 28 Feb 2008, 10:50
View user's profile Send private message MSN Messenger Reply with quote
DJ Mauretto



Joined: 14 Mar 2007
Posts: 464
Location: Rome,Italy
DJ Mauretto
Quote:
isn't it better? explicit, shorter etc...


Wink remember always that the most important thing is the algorithm,then you can optimise it as you prefer
Post 28 Feb 2008, 10:59
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17475
Location: In your JS exploiting you and your system
revolution
I wonder how many ways there are of doing the bit to ascii conversion?

Code:
xor al,al
add bx,bx
adc al,'0'

add bx,bx
setc al
or al,'0'

add bx,bx
salc
neg al
or al,'0'

mov al,'0'/2
add bx,bx
rcl al,1

mov al,'0'/2
add bx,bx
adc al,al

mov al,'0' shr 1
shld ax,bx,1
add bx,bx
    

... plus many more
Post 28 Feb 2008, 11:02
View user's profile Send private message Visit poster's website Reply with quote
Daedalus



Joined: 25 Mar 2007
Posts: 52
Daedalus
Did you just came up with all those?
Post 28 Feb 2008, 11:06
View user's profile Send private message MSN Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17475
Location: In your JS exploiting you and your system
revolution
Sure, all are just off the top of my head, but I'm sure you can think of more. There are lots of ways.
Post 28 Feb 2008, 11:09
View user's profile Send private message Visit poster's website Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4240
Location: 2018
edfed
Very Happy i didn't think about an other method, as the shl, adc is the more explicit.
the more explicit one is the best to use, for size, speed and understanding.
but when accoutumed with asm coding, they are all explicit.
add bx,bx is exactlly the same as shl bx,1
but is shorter. so, i'll adopt it only in case of shl 1

Code:
xor al,al
add bx,bx
adc al,'0'
    


a good name for this function is num.bin
as num is the class for numeric convertion in ascii
and .bin is a sub function of this class.

the reverse class can be ascii
with the same sub functions names.
ascii.bin

i'll expend it to hex, dec, udec (unsigned decimal), oct,
then :
Code:
num:
.bin:
.hex:
.dec:
.udec:
.oct:
.what you want.
    
Post 28 Feb 2008, 12:13
View user's profile Send private message Visit poster's website Reply with quote
Daedalus



Joined: 25 Mar 2007
Posts: 52
Daedalus
I'm afraid I can't think of all those methods, simply because I don't know how ASM works yet, hehe. But I've learned a lot in this thread already, espcially to take note of which flags are changed by mnemonics. Saves a lot of CMP's Wink
Post 28 Feb 2008, 14:43
View user's profile Send private message MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.