What I need is a small (fast) piece of code that converts hexadecimal values (32 bit) to binary.

Posted on 2003-04-02 17:50:14 by Psionicist
I am assuming you want to convert a hexadecimal number to a binary string. Here is a simple HLA solution.

``````

program hex;

#include ("stdlib.hhf")

static
number : int32;
buf    : byte[32];

MessageBox: procedure
(
hWnd			:dword;
lpText                  :string;
lpCaption               :string;
uType			:dword
);
@stdcall;
@use eax;
@returns( "eax" );
@external( "__imp__MessageBoxA@16" );

begin hex;

stdout.put ("Enter a number",nl );

stdin.getd ();

// to number variable

mov ( eax, number );

push ( edi );

// Copy address of buffer to edi

mov ( &buf, edi );

// Repeat 32 times since there are 32 bits in
// the number. We shift each bit in the number to
// the left. If it is a one we copy 1 to a buffer
// if it is zero we copy zero to the buffer

for ( mov( 0, ecx ); ecx < 32; inc ( ecx )) do

shl ( 1, number );

// if carry flag is set
// copy a 1 char to buffer
// otherwise copy a 0 char

if ( @c ) then

mov ( '1', (type byte [ edi + ecx ] ));

else
mov ( '0', (type byte [ edi + ecx ] ));

endif;
endfor;

// Terminate string with zero

mov ( 0, (type byte [ edi + ecx ] ));

MessageBox ( 0, edi, edi, 0 );

pop ( edi );

end hex;

``````
Posted on 2003-04-02 19:59:00 by Odyssey
``````lea edx, HexAsciiString ; "32FA1B30"

;check validity + build
xor ecx, ecx
xor eax, eax
xor ebx, ebx
@@:
mov al, [edx + ecx]
inc ecx
.if ecx > 8
jmp @F
.endif
shl ebx, 4
.if( eax > 2Fh )&&( eax < 3Ah)
and eax, 0Fh
or ebx, eax
jmp @B
.endif
and eax, FFFFFFDFh
.if( eax > 40h )&&(eax < 47h)
and eax, 0Fh
or ebx, eax
jmp @B
.endif
jmp @Error

@@:

; Ebx=32 bit binary of the string in edx``````

PS: I didnt test this.. kinda rambled it off the top of my head.. but it should work...

Hope it helps..
:alright:
NaN
Posted on 2003-04-02 22:16:22 by NaN
Assuming the same thing as Odyssey, here's a procedure in real assembler. It takes the 32-bit number and the address of a buffer (at least 33 bytes to include the terminating 0) as parameters.

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

Raymond
Posted on 2003-04-02 22:51:03 by Raymond
Hey
<disclaimer>
i wrote this a a while ago and isnt the greatest as far as speed or size
but it works.
</disclaimer>

anyways id love any suggestions to make it better.

;HexStringToBin
; IN:szHexString pointer to a zero terminated hex string eg 10ABCDEF
; string can be anylength
; IN:OUT pvBuffResult
; binary result of string. buffer should be size ( strlen / 2 )
; RETURNS:
; eax == 1 if all went well
; eax == 0 if invalid char int string eg letters greater then F
;
Option DOTNAME
HexStringToBin proc uses esi edi szHexString:DWORD, pvBuffResult:DWORD

INVOKE CharUpper,

mov esi, ;get string
mov edi, ;get buff

.loopit:
mov ah, byte ptr ;bet first char

sub ah, '0' ;convert it to bin

inc esi ;get next byte
mov al, byte ptr ;

sub al, '0' ;convert it bin

cmp ah, 011h ;is it a letter
jl @F ;if not then skip it

cmp ah, 016h ;is it valid?
jg .NotHexChar ;if not get out

sub ah, 07 ;else fix it
@@:

cmp al, 011h ;is it a letter
jl @F ;if not skip

cmp al, 016h ;is it valid?
jg .NotHexChar ;if not get out

sub al, 07 ;else fix A-F

@@:
ror ah, 4 ;fix our nibble
or al, ah ;now make our result

mov byte ptr , al ;store result destination buff

inc edi ;inc dest buff
inc esi ;inc src buff

cmp byte ptr , 0 ;are we at end of string?
jnz .loopit ;if not keep going

xor eax, eax
inc eax ;set success
ret

.NotHexChar:
xor eax, eax ;set invalid char
ret

HexStringToBin endp

OPTION NODOTNAME
Posted on 2003-04-05 20:59:13 by prs
prs:
I can't see how you can maintain that your code works with all the coding errors.

1)
; IN:OUT pvBuffResult
; binary result of string. buffer should be size ( strlen / 2 )
Your goal is to obtain a DWORD as an answer. Whatever the input is, the size of the buffer for the answer must ALWAYS be a dword size, regardless of "strlen".

2) The whole procedure gets wasted if your input string has an odd number of characters. The ending zero would be treated as one of the regular input characters (in AL) and get converted to a -30h. Being a negative signed byte, it is considered less that 11h and thus a valid number by your jl @F ;if not skip code which follows the comparison.

(The presence of any character in the input string having a hex value less than 30h, such as a hyphen, would also be treated as a valid character by your code.)

3) You store the "byte" results in the dword buffer in a "big-endian" manner. Only a handfull of computers in the whole world still use that convention.

Raymond
Posted on 2003-04-05 21:43:40 by Raymond
Hey Thanks for the feedback,

1: Actually the Goal was to just to return a binary representation of the string entered
in wysiwyg format. it converts the whole buffer
to binary exaclyt how you enter it,

2: I know the input string has to be an even lenght, it works on the ascii chars as "bytes"
eg 01 03 AB AC. something like 01 03 4 is two bytes and a nibble which my function
doesnt claim to handle,

3: didnt see the hyphen problem, thanks for pointing that out. I think when i originally
wrote this, it basicaly had most of the input already validated before being called.

Anyways it is here as another solution to the problem posed. didn't claim to be the fastests
or smallest. but it does work as i expected. I probably should have pointed the above
issues out. Thats the great thing about other peoples perspectives, it makes
you think things out better.

Thanks again
Take Care
prs
Posted on 2003-04-05 22:56:30 by prs
Posted on 2003-04-06 17:49:01 by lingo12