The MASM Forum

Miscellaneous => The Orphanage => Topic started by: shankle on May 01, 2016, 08:38:09 PM

Title: hexidecimal input
Post by: shankle on May 01, 2016, 08:38:09 PM
User inputs a hexidecimal value.
It goes into a field like:
    hexinput db '        ',0
I then need to get that value into a field like:
   hexvalue  dd 0

This shouldn't be to hard but it is eluding me. :redface:
Thanks for any help.
Title: Re: hexidecimal input
Post by: anunitu on May 01, 2016, 09:33:56 PM
Is it just a matter of how the hexadecimal is formatted? like across a single or multiple bytes or just a value transferred to another register or table?
Title: Re: hexidecimal input
Post by: fearless on May 01, 2016, 10:17:05 PM
The masm32 library function htodw (convert hex string to DWORD) maybe is what your looking for?

Title: Re: hexidecimal input
Post by: shankle on May 02, 2016, 12:44:31 AM
Thanks guys for replying.
Didn't know the function "htpdw" even existed.
Will give it a shot...
Since I am coding in GoAsm I will have to modify this module.
I guess that's ok????????
Title: Re: hexidecimal input
Post by: jj2007 on May 02, 2016, 02:41:33 AM
Quote from: anunitu on May 01, 2016, 09:33:56 PM
Is it just a matter of how the hexadecimal is formatted?

There are three common formats:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  mov esi, Val("12345678h")
  mov edi, Val("$12345678")
  mov ebx, Val("0x12345678")
  deb 1, "Results", esi, x:esi, edi, x:edi, ebx, x:ebx
EndOfCode


Output:
Results
esi             305419896
x:esi           12345678
edi             305419896
x:edi           12345678
ebx             305419896
x:ebx           12345678
Title: Re: hexidecimal input
Post by: nidud on May 02, 2016, 03:53:58 AM
deleted
Title: Re: hexidecimal input
Post by: shankle on May 02, 2016, 06:09:23 AM

Thank you NIdud,
This code is intended for a GoAsm program
So I have modified it slightly.
Data entered is f42400H but could be any hex number
I get a result of "ni rorre"?
dwtoa is a masm32 and GoAsm convert Dword to ascii string module

BufAdd        dd  0
saveeax       dd  0  ; temp save
HexInputData  db  '      ',0     ; set for 6 positions

;      HexInputData to Decimal DD
    lea esi,HexInputData
    xor eax,eax    ; result
xor ecx,ecx
xor edx,edx
xor edi,edi
mov edi,5
.lupe
mov cl,[esi]  ; esi: string
add esi,1
and ecx,not 030h
bt ecx,6
sbb edx,edx
and edx,55
sub ecx,edx
shl eax,4
add eax,ecx
dec edi   ; length of string
jnz <.lupe
mov [saveeax],eax

; test code begin
;tmsg     db   'testing result of HexInputData',0
;tmsg2    db  '        ',0
      mov ecx,[saveeax]
      lea ebx,tmsg2
      mov [BufAdd], ebx
      invoke dwtoa, ecx,[BufAdd]      ; Hex DD to string
                                      ; output is in tmsg2
     invoke MessageBox, [hWnd], addr tmsg, addr tmsg2, MB_OK ;true
; test code end
Title: Re: hexidecimal input
Post by: nidud on May 02, 2016, 06:20:05 AM
deleted
Title: Re: hexidecimal input
Post by: jj2007 on May 02, 2016, 07:05:59 AM
Quote from: nidud on May 02, 2016, 03:53:58 AMUp to 16 byte

Pretty good :t

Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)

10268   cycles for 100 * xtol
8641    cycles for 100 * xtol2
28680   cycles for 100 * MovVal
30435   cycles for 100 * a2uq
7903    cycles for 100 * Masm32 hval

10242   cycles for 100 * xtol
8586    cycles for 100 * xtol2
28742   cycles for 100 * MovVal
30452   cycles for 100 * a2uq
7902    cycles for 100 * Masm32 hval

10284   cycles for 100 * xtol
8640    cycles for 100 * xtol2
28934   cycles for 100 * MovVal
30436   cycles for 100 * a2uq
7903    cycles for 100 * Masm32 hval

10272   cycles for 100 * xtol
8624    cycles for 100 * xtol2
28764   cycles for 100 * MovVal
30439   cycles for 100 * a2uq
7897    cycles for 100 * Masm32 hval

10275   cycles for 100 * xtol
8991    cycles for 100 * xtol2
28663   cycles for 100 * MovVal
30536   cycles for 100 * a2uq
7902    cycles for 100 * Masm32 hval

74      bytes for xtol
62      bytes for xtol2
23      bytes for MovVal
34      bytes for a2uq
12      bytes for Masm32 hval

00000000 00000000 12AB34CD 56EF7801     = eax xtol
00000000 00000000 12AB34CD 56EF7801     = eax xtol2
00000000 00000000 12AB34CD 56EF7801     = eax MovVal
00000000 00000000 0000000C 00000000     = eax a2uq
00000000 00000000 00000000 12AB34CD     = eax Masm32 hval


Couldn't convince a2uq to produce meaningful results, and hval is limited to a DWORD 8)
Title: Re: hexidecimal input
Post by: habran on May 02, 2016, 02:36:45 PM
Here is another way to do that:

hex2num PROC uses ebx esi src:DWORD
   mov esi,src
   xor ebx, ebx
   .for (::)
      movsx eax, BYTE PTR [esi]
      .break .if (!eax)
      shl  ebx, 4
      lea  esi,[esi+1]
      lea  edx,[eax-48]
      .if (edx <= 9)
   mov eax, edx
      .else
         or   eax,20h
lea edx, DWORD PTR [eax-97]
.if (edx <= 5)
     add  eax, -87
         .endif
      .endif
      add  ebx, eax
   .endfor
   add  eax, ebx
   ret
hex2num ENDP


and here is 64 bit version:

hex2num PROC FRAME src:QWORD
   xor   r8d, r8d
   .for (::)
       movsx eax, BYTE PTR [rcx]
       .break .if (!eax)
       shl  r8d, 4
       lea  rcx,[rcx+1]
       lea  edx,[rax-48]
       .if (edx <= 9)
          mov  eax, edx
       .else
        or   eax,20h
        lea  edx, DWORD PTR [rax-97]
        .if (edx <= 5)
           add  eax, -87
        .endif
      .endif
      add  r8d, eax
   .endfor
    add  eax, r8d
    ret
hex2num ENDP
Title: Re: hexidecimal input
Post by: jj2007 on May 02, 2016, 04:39:06 PM
Added to testbed:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz (SSE4)
Assembled with HJWasm
10179   cycles for 100 * xtol
8317    cycles for 100 * xtol2
23974   cycles for 100 * MovVal
88369   cycles for 100 * a2uqJ
7893    cycles for 100 * Masm32 hval (dword)
4608    cycles for 100 * hex2num (Habran, dword)

10183   cycles for 100 * xtol
8591    cycles for 100 * xtol2
23861   cycles for 100 * MovVal
88544   cycles for 100 * a2uqJ
7856    cycles for 100 * Masm32 hval (dword)
4604    cycles for 100 * hex2num (Habran, dword)

10179   cycles for 100 * xtol
8663    cycles for 100 * xtol2
23860   cycles for 100 * MovVal
88536   cycles for 100 * a2uqJ
7890    cycles for 100 * Masm32 hval (dword)
4613    cycles for 100 * hex2num (Habran, dword)

74      bytes for xtol
62      bytes for xtol2
23      bytes for MovVal
34      bytes for a2uqJ
12      bytes for Masm32 hval (dword)
70      bytes for hex2num (Habran, dword)

00000000 00000000 12AB34CD 56EF7801     = eax xtol
00000000 00000000 12AB34CD 56EF7801     = eax xtol2
00000000 00000000 12AB34CD 56EF7801     = eax MovVal
00000000 00000000 12AB34CD 56EF7801     = eax a2uqJ
00000000 00000000 00000000 12AB34CD     = eax Masm32 hval (dword)
00000000 00000000 00000003 12AB34CD     = eax hex2num (Habran, dword)
Title: Re: hexidecimal input
Post by: habran on May 02, 2016, 07:52:21 PM
Impresive :icon_exclaim:
I've done it for the beauty and to demonstrate HJWasm capabilities, I did not expect such advantage in the speed :shock:
I wonder how much faster is 64 bit version because there is no overhead.
Here is the result from my machine:
Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz (SSE4)
Assembled with HJWasm
6585    cycles for 100 * xtol
5837    cycles for 100 * xtol2
16475   cycles for 100 * MovVal
63942   cycles for 100 * a2uqJ
5376    cycles for 100 * Masm32 hval (dword)
3120    cycles for 100 * hex2num (Habran, dword)

6508    cycles for 100 * xtol
5856    cycles for 100 * xtol2
16326   cycles for 100 * MovVal
63416   cycles for 100 * a2uqJ
5320    cycles for 100 * Masm32 hval (dword)
3111    cycles for 100 * hex2num (Habran, dword)

6518    cycles for 100 * xtol
5913    cycles for 100 * xtol2
16261   cycles for 100 * MovVal
63464   cycles for 100 * a2uqJ
5330    cycles for 100 * Masm32 hval (dword)
3140    cycles for 100 * hex2num (Habran, dword)

74      bytes for xtol
62      bytes for xtol2
23      bytes for MovVal
34      bytes for a2uqJ
12      bytes for Masm32 hval (dword)
70      bytes for hex2num (Habran, dword)

00000000 00000000 12AB34CD 56EF7801     = eax xtol
00000000 00000000 12AB34CD 56EF7801     = eax xtol2
00000000 00000000 12AB34CD 56EF7801     = eax MovVal
00000000 00000000 12AB34CD 56EF7801     = eax a2uqJ
00000000 00000000 00000000 12AB34CD     = eax Masm32 hval (dword)
00000000 00000000 00000003 12AB34CD     = eax hex2num (Habran, dword)

--- ok ---
Title: Re: hexidecimal input
Post by: nidud on May 02, 2016, 09:26:53 PM
deleted
Title: Re: hexidecimal input
Post by: shankle on May 02, 2016, 09:32:42 PM
Thanks everyone for responding.
To Nidud,
I am not able to get any of your versions to come up with
the correct result.
To Habran,
I have to convert your code to GoAsm 64-bit and that is
a problem for me.
Title: Re: hexidecimal input
Post by: habran on May 02, 2016, 10:33:10 PM
Hi shankle,
Why do you think that you must use GoAsm ;)
I make my choices by using common sense 8)
Title: Re: hexidecimal input
Post by: nidud on May 02, 2016, 10:40:21 PM
deleted
Title: Re: hexidecimal input
Post by: jj2007 on May 02, 2016, 10:43:54 PM
Quote from: habran on May 02, 2016, 07:52:21 PMI did not expect such advantage in the speed :shock:

The crt_sscanf is surprisingly slow ::)

Intel(R) Core(TM) i7-4700MQ CPU @ 2.40GHz (SSE4)
Assembled with HJWasm
5837    cycles for 100 * xtol2   QWORD size, accepts 123aBcD with or without trailing h
16475   cycles for 100 * MovVal  QWORD size, accepts almost everything*) (decimal, 1010b, 0xAb12, $abc, 0abch)
63942   cycles for 100 * a2uqJ   QWORD size, CRT, accepts only hex with the given format string
5376    cycles for 100 * Masm32 hval (dword)
3120    cycles for 100 * hex2num (Habran, dword)


*)
include \masm32\MasmBasic\MasmBasic.inc
  Init
  Print Str$("\n%i", Val("2748"))
  Print Str$("\n%i", Val("101010111100b"))
  Print Str$("\n%i", Val("101010111100y"))
  Print Str$("\n%i", Val("0xaBc"))
  Print Str$("\n%i", Val("$aBc"))
  Print Str$("\n%i (bad format)", Val("aBc"))
  Print Str$("\n%i", Val("aBch"))
  Print Str$("\n%i", Val("aBcH"))
EndOfCode
Title: Re: hexidecimal input
Post by: habran on May 03, 2016, 06:18:16 AM
Hi shankle,
Here is 64 bit in a plain asm:
Quotehex2dec   PROC  src:QWORD
   movsx   eax, BYTE PTR [rcx]
   xor   edx, edx
   mov   r9, rcx
   test   eax, eax
   je   LN16
LL2:
   shl   edx, 4
   lea   r8d, DWORD PTR [rax-48]
   cmp   r8d, 9
   ja   LN6
   mov   eax, r8d
   jmp   LN8
LN6:
   or   eax, 32
   lea   ecx, DWORD PTR [rax-97]
   cmp   ecx, 5
   ja   LN8
   add   eax, -87
LN8:
   inc   r9
   add   edx, eax
   movsx   eax, BYTE PTR [r9]
   test   eax, eax
   jne   LL2
LN16:
   mov   eax, edx
   ret   
hex2dec   ENDP
it is created from this C source:
Quoteuint_32  hex2dec(const char *src)
{
  uint_32 a;
  uint_32 b = 0;
  for ( ;; )
  {
    a = *src;
    if (!a) break;
    b = (b << 4);
    if (a >= '0' && a <= '9') a -= '0';
    else {
      a |= 0x20;
      if (a >= 'a' && a <= 'f') a -= 'a' - 10;
    }
    b = b + a;
    src++;
  }
  return (b);
}
Title: Re: hexidecimal input
Post by: shankle on May 03, 2016, 04:40:46 PM
Thanks everyone for your help.  I think I have solved my problem.
It might not be the best but its works.