News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

binary to ascii

Started by hfheatherfox07, December 21, 2012, 03:44:57 PM

Previous topic - Next topic

dedndave

really, if they have "10 0101", we can just zero-extend those and call it the same as "00000010 00000101"
the tricky one is how to handle "10101010010101010101010" - string sections longer than 8 bits

here is another one that might throw a wrench in the works...
"01010 11010000 11010200"   :biggrin:

hfheatherfox07

 :eusa_snooty:I am beginning to suspect that it should not have any space
I google "binary to ASCII text converters online
And it seems that they do not have spaces

http://m.branah.com/ascii-converter

Even if you enter 2 words with a space inbetween them
The binary ASCII is a long string
So .... I'm going to have to relook that routine that I have

Anyway it is 5 AM here
Going to hit the hey , I will think clearly after a nap
Thank you all for all the help :)
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

jj2007

Quote from: dedndave on December 21, 2012, 09:00:05 PM
here is another one that might throw a wrench in the works...
"01010 11010000 11010200"   :biggrin:

I'm afraid even my routine in Reply #12 doesn't throw an error... :redface:

hfheatherfox07

Here is the tool that I got to convert ASCII to Binary

Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

FORTRANS

Hi,

   I made a fixed point binary, hex, and decimal converter
back when.  It's in the Archive2 subforum as  5486_FIX2DEC.zip.
A DOS program, but it may give you some ideas.  It is an
older version so if anyone wants an updated version I can
dig it out and post it.

Regards,

Steve N.

hfheatherfox07

what I am trying to accomplish is something like this http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/Binary_To_Text.asp

I need to take out the space in the ascii2bin routine in ASCII2BIN.zip and I can't get it to work

I did find another ascii2bin but It gives me wrong bin?

.486p
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

hex2abin proto :DWORD,:DWORD

.data
szHexString  db "48 65 6C 6C 6F" ; Hello
hstr     db 60 dup(0)
mybuffer db 4096 dup(?) ; total converted string
szCapt   db "Hex To Binary", 0
.code

start:

invoke hex2abin,addr szHexString,addr hstr
invoke lstrcat, addr mybuffer,addr hstr
invoke MessageBox,NULL,addr mybuffer,addr szCapt,MB_OK
Invoke ExitProcess,0
hex2abin proc uses edi hexnumber:DWORD, lpbuf:DWORD

mov edx,hexnumber
mov ecx,32
mov edi,lpbuf
@@:
shl edx,1 ;transfers the bits to the C flag one by one
mov al,18h ;30h (ASCII 0)/2
rcl al,1 ;gets the ASCII 0 back + the C flag as 0 or 1
stosb
dec ecx
jnz @B
mov al,0
stosb
ret

hex2abin endp
end start
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

hfheatherfox07

Here is a Bin2Ascii.ASM that I found , but I can not get it to work

; Here is a version of Bin2Ascii that allows the quotient to overflow, but
; takes care that the resulting answer will be correct.  It is certainly
; shorter than the version in the sample solution.

; Note, however, that if Virgo followed the Encoding Reference Manual strictly,
; this version would not work.

; For DIV, the Encoding Reference Manual states:

; "If the quotient is too large to fit in the low half of the dividend, then the
; quotient and remainder are undefined and a Type 0 software interrupt is performed."

; Here, we take advantage of the fact that with Virgo, the results of a 32 bit DIV
; of this form are that the remainder is correct and the quotient is the low
; word of the quotient.

; Note that this subroutine will not assemble on its own.  (Replace the Bin2Ascii
; in the sample solution with this file and then assemble and execute.)

;*****************************************************************************
;*
;* NAME:    Bin2Ascii
;*
;* void Bin2Ascii( unsigned long int & BinVal, char & AsciiText[] )
;*
;* Purpose: converts 32-bit binary value BinVal to $-terminated AsciiText string
;* (AsciiText[] must be large enough to hold the Ascii representation of
;* the largest unsigned long integer value + the terminator)
;* Note: supresses leading zeros (and blanks) during conversion
;*
;* Accepts: address of double word (little endian), and address of character string
;* Returns: nothing
;*****************************************************************************

Bin2Ascii:
push bp
mov bp,sp
push ax
push bx
push cx
push dx
push si
push di

mov bx,word ptr[bp+4] ; address of long int
mov ax, [bx] ; low word of long int
add bx,2
mov dx, [bx] ; high word of long int
mov bx,word ptr[bp+6] ; address of string

; set string to 10 blanks plus a $ sign (cannot assume that it is set up right)
mov si,0
BlankLoop:
mov byte ptr[bx+si],' '
inc si
cmp si,10
jne BlankLoop
mov byte ptr[bx+si],'$'

mov si,9 ; start with 10th digit (offset)
DigitLoop:
mov cx,dx ; store a copy of dx in cx

div word ptr[constant10] ; divide dx:ax by 10 (quotient in ax, remainder in dx)
add dx,30h ; add 30h to remainder to convert to ascii

mov byte ptr[bx+si],dl ; store ascii character at offset si
dec si ; decrement offset

mov di,ax ; store a copy of quotient in di
mov ax,cx ; move old dx into ax
mov dx,0 ; set dx to 0
div word ptr[constant10] ; divide old dx by 10 (quotient in ax, remainder in dx)

mov dx,ax ; move quotient into dx
mov ax,di ; move old quotient into ax (thus dx:ax contains quotient of dx:ax / 10)

cmp ax,0 ; if both ax and dx are 0 we are done, otherwise loop again
jne DigitLoop

cmp dx,0
jne DigitLoop

; now we need to fix up the string as it is currently right justified and should be left justified
cmp si,-1
je  DoneBin2Ascii ; if si is -1 the string is full and thus left justified so we are done
add si,1
mov di,0
JustifyLoop:
mov cl,byte ptr[bx+si]
mov byte ptr[bx+di],cl
inc si
inc di
cmp si,10
jbe JustifyLoop

DoneBin2Ascii:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop bp
ret


Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

hfheatherfox07

I found another Bin2Hex proc here http://www.purebasic.fr/english/viewtopic.php?p=153495

Why is it crashing?

.486p
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

Bin2ASCII proto :DWORD,:DWORD

.data
HEX_PRE           db "%X", 32, 0 ; prefix hex, 32 for space, 0 to end
szBinaryString  db "0100100001100101011011000110110001101111" ; Hello
hBinarystr     db 60 dup(0)
mybuffer db 4096 dup(?) ; total converted string
buffer          db 32 dup(?) ; buffer
szCapt   db "Binary To Hex", 0
.code

start:

invoke Bin2ASCII,addr szBinaryString,addr buffer
invoke wsprintf, ADDR buffer, ADDR HEX_PRE, eax ; buffer = 5dup(0)
invoke lstrcat, ADDR mybuffer, ADDR buffer ; mybuffer db 512 dup(0)
invoke MessageBox,NULL,addr mybuffer,addr szCapt,MB_OK
Invoke ExitProcess,0
Bin2ASCII proc  src:DWORD, dst :DWORD


;the setup
pushad                 ;save all cpu registers

mov esi,src            ;point to source
mov edi,dst            ;point to destination

;mov ecx,size        ;counter into source file  PureBasic
invoke lstrlen, addr szBinaryString
mov ecx, eax ; move src length to ecx

lea ebx,hex_table      ;get the address of the lookup table

or ecx,ecx             ;test it's not 0
jz short done

;now do the work
ALIGN 16      ;make sure the next instruction starts on a 16 byte boundary.
lp:

movzx eax,byte ptr [esi]   ;get next byte
mov edx,[4*eax+ebx]        ;look up HEX

mov [edi],dx               ;write the output
add edi,3                  ;update destination pointer
     
inc esi                    ;update pointer
dec ecx                    ;update count

jns short lp               ;go back for next character on this line

done:

popad                      ;restore all cpu registers

ALIGN 16  ;make sure the lookup table is aligned in memory
hex_table:
dd "  00","  10","  20","  30","  40","  50","  60","  70"
dd "  80","  90","  A0","  B0","  C0","  D0","  E0","  F0"
dd "  01","  11","  21","  31","  41","  51","  61","  71"
dd "  81","  91","  A1","  B1","  C1","  D1","  E1","  F1"
dd "  02","  12","  22","  32","  42","  52","  62","  72"
dd "  82","  92","  A2","  B2","  C2","  D2","  E2","  F2"
dd "  03","  13","  23","  33","  43","  53","  63","  73"
dd "  83","  93","  A3","  B3","  C3","  D3","  E3","  F3"
dd "  04","  14","  24","  34","  44","  54","  64","  74"
dd "  84","  94","  A4","  B4","  C4","  D4","  E4","  F4"
dd "  05","  15","  25","  35","  45","  55","  65","  75"
dd "  85","  95","  A5","  B5","  C5","  D5","  E5","  F5"
dd "  06","  16","  26","  36","  46","  56","  66","  76"
dd "  86","  96","  A6","  B6","  C6","  D6","  E6","  F6"
dd "  07","  17","  27","  37","  47","  57","  67","  77"
dd "  87","  97","  A7","  B7","  C7","  D7","  E7","  F7"
dd "  08","  18","  28","  38","  48","  58","  68","  78"
dd "  88","  98","  A8","  B8","  C8","  D8","  E8","  F8"
dd "  09","  19","  29","  39","  49","  59","  69","  79"
dd "  89","  99","  A9","  B9","  C9","  D9","  E9","  F9"
dd "  0A","  1A","  2A","  3A","  4A","  5A","  6A","  7A"
dd "  8A","  9A","  AA","  BA","  CA","  DA","  EA","  FA"
dd "  0B","  1B","  2B","  3B","  4B","  5B","  6B","  7B"
dd "  8B","  9B","  AB","  BB","  CB","  DB","  EB","  FB"
dd "  0C","  1C","  2C","  3C","  4C","  5C","  6C","  7C"
dd "  8C","  9C","  AC","  BC","  CC","  DC","  EC","  FC"
dd "  0D","  1D","  2D","  3D","  4D","  5D","  6D","  7D"
dd "  8D","  9D","  AD","  BD","  CD","  DD","  ED","  FD"
dd "  0E","  1E","  2E","  3E","  4E","  5E","  6E","  7E"
dd "  8E","  9E","  AE","  BE","  CE","  DE","  EE","  FE"
dd "  0F","  1F","  2F","  3F","  4F","  5F","  6F","  7F"
dd "  8F","  9F","  AF","  BF","  CF","  DF","  EF","  FF"

Bin2ASCII endp
end start
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

jj2007

Quote from: hfheatherfox07 on December 22, 2012, 06:32:26 AM
I found another Bin2Hex proc here http://www.purebasic.fr/english/viewtopic.php?p=153495

Why is it crashing?

Because a ret is missing in line 67. Still, I haven't understood: Are you testing all these crappy snippets out of interest for others' coding attempts, or do you need a solution? The one in reply #12 works perfectly :biggrin:

dedndave

none of them do what you seem to want to do
one is for ascii hex to binary
one is for binary to ascii hex
one is for binary to ascii decimal, which is 16-bit code

the function you want to perform is a very simple one
however, you have to start by defining some rules

what if i give you a string of 1's and 0's, the length of which is not evenly divisible by 8 ?
how do you want your routine to handle that case ?

if it is less than 8 - we can zero-extend it
but, what if there are (21) 1's and 0's ?

dedndave

the basic idea of the conversion is something like this....

ASCII "0" is 30h, or 48 decimal, in binary
ASCII "1" is 31h, or 49 decimal, in binary

of course, you may want to check for a null terminator byte, first
if you xor an input byte with 30h....
if it is ASCII "0", the result will be binary 0
if it is ASCII "1", the result will be binary 1
if it is any other value, the result will be > binary 1

you can successively shift those bits into a byte (left-most text digits are higher order bits)
when you have 8 of them, you have your ASCII character

there are a number of tricks you can play to make it fast
but, i wouldn't worry about that - just get a routine that works up and running

hfheatherfox07

ALL I wanted to do is this http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/Binary_To_Text.asp

I will look into this some more......
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

i saw that
ok
but, he has a nice pile of 1's and 0's whose length is evenly divisible by 8   :P

here's how he handles it - lol
QuoteError: Malformed binary. Your binary code is must be divisible by 8.
not very clear - he means the length must be divisible by 8

here's how he handles non-printable characters
29º¹2:7294·5
<·º¹'»0¶:4·2—

hfheatherfox07

Well I am working with the assumption that I do for now lo

How to translate this little Part

mov esi,src            ;point to source
mov edi,dst            ;point to destination

;mov ecx,size        ;counter into source file  PureBasic


the  mov ecx,size

I found another one with same deal ....
.data
szHexLookup db "0123456789ABCDEF"

.code

bin2hex:
mov esi, [sourcedata]
mov edi, [targetstring]
mov ecx, [sourcelength]

.process:
lodsb
mov ah, al
and al, 0xF
movzx edx, al
mov al, [szHexLookup + edx]
stosb

shr ah, 4
movzx edx, ah
mov al, [szHexLookup + edx]
stosb

dec ecx
jnz .process


how do you write  mov      ecx, [sourcelength] ?

I get the same wrong results whether I use
mov ecx,sizeof sourcedata   
or     
invoke lstrlen, addr sourcedata
mov ecx, eax ; move src length to ecx


.486p
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

Bin2ASCII proto :DWORD,:DWORD

.data
szHexLookup db "0123456789ABCDEF"
HEX_PRE           db "%X", 32, 0 ; prefix hex, 32 for space, 0 to end
szBinaryString  db "0100100001100101011011000110110001101111" ; Hello = 48 65 6C 6C 6F
hBinarystr     db 60 dup(0)
szCapt   db "Binary To Hex", 0
.data
mybuffer db 4096 dup(?) ; total converted string
buffer   db 4096 dup(?) ; buffer

.code

start:

invoke Bin2ASCII,addr szBinaryString,addr buffer
invoke wsprintf, ADDR buffer, ADDR HEX_PRE, eax ; buffer = 5dup(0)
invoke lstrcat, ADDR mybuffer, ADDR buffer ; mybuffer db 512 dup(0)
invoke MessageBox,NULL,addr mybuffer,addr szCapt,MB_OK
Invoke ExitProcess,0
Bin2ASCII proc  sourcedata:DWORD, targetstring :DWORD


;the setup
pushad                 ;save all cpu registers

mov esi,sourcedata            ;point to source
mov edi,targetstring            ;point to destination

;mov ecx,sizeof sourcedata         ;counter into source file  PureBasic
invoke lstrlen, addr sourcedata
mov ecx, eax ; move src length to ecx

process:
lodsb
mov ah, al
and al, 0Fh
movzx edx, al
mov al, [szHexLookup + edx]
stosb

shr ah, 4
movzx edx, ah
mov al, [szHexLookup + edx]
stosb

dec ecx
jnz process
ret
popad                      ;restore all cpu registers


Bin2ASCII endp
end start



.486p
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

Bin2ASCII proto :DWORD,:DWORD

.data
HEX_PRE           db "%X", 32, 0 ; prefix hex, 32 for space, 0 to end
szBinaryString  db "0100100001100101011011000110110001101111" ; Hello = 48 65 6C 6C 6F
szCapt   db "Binary To Hex", 0
.data
mybuffer db 4096 dup(?) ; total converted string
buffer   db 4096 dup(?) ; buffer

.code

start:

invoke Bin2ASCII,addr szBinaryString,addr buffer
invoke wsprintf, ADDR buffer, ADDR HEX_PRE, eax ; buffer = 5dup(0)
invoke lstrcat, ADDR mybuffer, ADDR buffer ; mybuffer db 512 dup(0)
invoke MessageBox,NULL,addr mybuffer,addr szCapt,MB_OK
Invoke ExitProcess,0
Bin2ASCII proc  src:DWORD, dst :DWORD


;the setup
pushad                 ;save all cpu registers

mov esi,src            ;point to source
mov edi,dst            ;point to destination

;mov ecx,size        ;counter into source file  PureBasic
;mov ecx,sizeof src
invoke lstrlen, addr src
mov ecx, eax ; move src length to ecx

lea ebx,hex_table      ;get the address of the lookup table

or ecx,ecx             ;test it's not 0
jz short done

;now do the work
ALIGN 16      ;make sure the next instruction starts on a 16 byte boundary.
lp:

movzx eax,byte ptr [esi]   ;get next byte
mov edx,[4*eax+ebx]        ;look up HEX

mov [edi],dx               ;write the output
add edi,3                  ;update destination pointer
     
inc esi                    ;update pointer
dec ecx                    ;update count

jns short lp               ;go back for next character on this line

done:
ret
popad                      ;restore all cpu registers

ALIGN 16  ;make sure the lookup table is aligned in memory
hex_table:
dd "  00","  10","  20","  30","  40","  50","  60","  70"
dd "  80","  90","  A0","  B0","  C0","  D0","  E0","  F0"
dd "  01","  11","  21","  31","  41","  51","  61","  71"
dd "  81","  91","  A1","  B1","  C1","  D1","  E1","  F1"
dd "  02","  12","  22","  32","  42","  52","  62","  72"
dd "  82","  92","  A2","  B2","  C2","  D2","  E2","  F2"
dd "  03","  13","  23","  33","  43","  53","  63","  73"
dd "  83","  93","  A3","  B3","  C3","  D3","  E3","  F3"
dd "  04","  14","  24","  34","  44","  54","  64","  74"
dd "  84","  94","  A4","  B4","  C4","  D4","  E4","  F4"
dd "  05","  15","  25","  35","  45","  55","  65","  75"
dd "  85","  95","  A5","  B5","  C5","  D5","  E5","  F5"
dd "  06","  16","  26","  36","  46","  56","  66","  76"
dd "  86","  96","  A6","  B6","  C6","  D6","  E6","  F6"
dd "  07","  17","  27","  37","  47","  57","  67","  77"
dd "  87","  97","  A7","  B7","  C7","  D7","  E7","  F7"
dd "  08","  18","  28","  38","  48","  58","  68","  78"
dd "  88","  98","  A8","  B8","  C8","  D8","  E8","  F8"
dd "  09","  19","  29","  39","  49","  59","  69","  79"
dd "  89","  99","  A9","  B9","  C9","  D9","  E9","  F9"
dd "  0A","  1A","  2A","  3A","  4A","  5A","  6A","  7A"
dd "  8A","  9A","  AA","  BA","  CA","  DA","  EA","  FA"
dd "  0B","  1B","  2B","  3B","  4B","  5B","  6B","  7B"
dd "  8B","  9B","  AB","  BB","  CB","  DB","  EB","  FB"
dd "  0C","  1C","  2C","  3C","  4C","  5C","  6C","  7C"
dd "  8C","  9C","  AC","  BC","  CC","  DC","  EC","  FC"
dd "  0D","  1D","  2D","  3D","  4D","  5D","  6D","  7D"
dd "  8D","  9D","  AD","  BD","  CD","  DD","  ED","  FD"
dd "  0E","  1E","  2E","  3E","  4E","  5E","  6E","  7E"
dd "  8E","  9E","  AE","  BE","  CE","  DE","  EE","  FE"
dd "  0F","  1F","  2F","  3F","  4F","  5F","  6F","  7F"
dd "  8F","  9F","  AF","  BF","  CF","  DF","  EF","  FF"

Bin2ASCII endp
end start
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

dedndave

if you get the string from an edit box or something, it will have a null terminator
so - no real need to keep the length
however, if you intend to test the length before converting it....
use StrLen, a masm32 library function

to do a simple test on your code, you can use the SIZEOF operator

szTest db '10101010',0

mov ecx,sizeof szTest-1    ;we use (-1) to subtract out the length of the null byte

ECX will be 8