News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

ASCIIZ conversion procedures based on 'dwtoa'

Started by GregL, May 01, 2007, 10:43:45 PM

Previous topic - Next topic

GregL

The 'dwtoa' procedure in masm32.lib works great as long as you understand that
it always treats the value being converted as signed. If you want to convert an
unsigned value greater than 07FFFFFFFh your out of luck. I modified the 'dwtoa'
procedure to always treat the value being converted as unsigned and named it
'udwtoa'. I then set an alias of 'sdwtoa' to 'dwtoa' and then derived some
procedures for converting bytes and words, signed and unsigned to ASCIIZ. If
anyone finds them useful that's great.


.386
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONE

INCLUDE windows.inc

INCLUDE kernel32.inc
INCLUDE masm32.inc

INCLUDE c:\masm32\macros\macros.asm

INCLUDELIB kernel32.lib
INCLUDELIB masm32.lib

udwtoa PROTO   udwValue:DWORD,  pszBuffer:PTR BYTE
sdwtoa TEXTEQU <dwtoa>
uwtoa  PROTO   uwValue:WORD,    pszBuffer:PTR BYTE
swtoa  PROTO   swValue:SWORD,   pszBuffer:PTR BYTE
ubtoa  PROTO   ubValue:BYTE,    pszBuffer:PTR BYTE
sbtoa  PROTO   sbValue:SBYTE,   pszBuffer:PTR BYTE

SBYTE_MIN  EQU -128
SBYTE_MAX  EQU 127

UBYTE_MIN  EQU 0
UBYTE_MAX  EQU 255

SWORD_MIN  EQU -32768
SWORD_MAX  EQU 32767

UWORD_MIN  EQU 0
UWORD_MAX  EQU 65535

SDWORD_MIN EQU -2147483648
SDWORD_MAX EQU 2147483647

UDWORD_MIN EQU 0
UDWORD_MAX EQU 4294967295


.DATA?

    szBuffer BYTE 256 DUP(?)

.CODE

start:

    INVOKE StdOut, SADD("SBYTE",13,10);
    FOR num, <SBYTE_MIN, SBYTE_MAX>
        mov al, num
        INVOKE sbtoa, al, ADDR szBuffer
        INVOKE StdOut, ADDR szBuffer
        INVOKE StdOut, SADD(13,10)
    ENDM
    INVOKE StdOut, SADD(13,10)
   
    INVOKE StdOut, SADD("BYTE",13,10)
    FOR num, <UBYTE_MIN, UBYTE_MAX>
        mov al, num
        INVOKE ubtoa, al, ADDR szBuffer
        INVOKE StdOut, ADDR szBuffer
        INVOKE StdOut, SADD(13,10)
    ENDM   
    INVOKE StdOut, SADD(13,10)
   
    INVOKE StdOut, SADD("SWORD",13,10)
    FOR num, <SWORD_MIN, SWORD_MAX>
        mov ax, num
        INVOKE swtoa, ax, ADDR szBuffer
        INVOKE StdOut, ADDR szBuffer
        INVOKE StdOut, SADD(13,10)
    ENDM
    INVOKE StdOut, SADD(13,10)
   
    INVOKE StdOut, SADD("WORD",13,10)
    FOR num, <UWORD_MIN, UWORD_MAX>
        mov ax, num
        INVOKE uwtoa, ax, ADDR szBuffer
        INVOKE StdOut, ADDR szBuffer
        INVOKE StdOut, SADD(13,10)
    ENDM       
    INVOKE StdOut, SADD(13,10)
   
    INVOKE StdOut, SADD("SDWORD",13,10)
    FOR num, <SDWORD_MIN, SDWORD_MAX>
        mov eax, num
        INVOKE sdwtoa, eax, ADDR szBuffer
        INVOKE StdOut, ADDR szBuffer
        INVOKE StdOut, SADD(13,10)
    ENDM
    INVOKE StdOut, SADD(13,10)
   
    INVOKE StdOut, SADD("DWORD",13,10)
    FOR num, <UDWORD_MIN, UDWORD_MAX>
        mov eax, num
        INVOKE udwtoa, eax, ADDR szBuffer
        INVOKE StdOut, ADDR szBuffer
        INVOKE StdOut, SADD(13,10)
    ENDM       
    INVOKE StdOut, SADD(13,10)   
       
    INVOKE ExitProcess, 0

; *********************************************
; ASCIIZ conversion procedures based on 'dwtoa'
; *********************************************

ALIGN 4

udwtoa PROC udwValue:DWORD, pszBuffer:PTR BYTE

    ; ---------------------------------------------------------------
    ; Original procedure 'dwtoa' written by Tim Roberts
    ; Minor fix by Jibz, December 2004
    ; Modified to convert value as unsigned by Greg Lyon, May 2007
    ; -------------------------------------------------------------
    ; Convert unsigned DWORD to ASCIIZ string
    ; udwValue is value to be converted
    ; pszBuffer is the address of the receiving buffer
    ; EXAMPLE:
    ; invoke udwtoa, edx, ADDR buffer
    ;
    ; Uses: eax, ecx, edx.
    ; -------------------------------------------------------------

    push ebx
    push esi
    push edi

    mov eax, udwValue
    mov edi, pszBuffer

    test eax,eax
    jnz pos

  zero:
    mov WORD PTR [edi], 30h
    jmp dtaexit

  pos:
    mov ecx, 3435973837
    mov esi, edi

    .WHILE (eax > 0)
      mov ebx, eax
      mul ecx
      shr edx, 3
      mov eax, edx
      lea edx, [edx*4+edx]
      add edx, edx
      sub ebx, edx
      add bl, '0'
      mov [edi], bl
      add edi, 1
    .ENDW

    mov BYTE PTR [edi], 0       ; terminate the string

    ; We now have all the digits, but in reverse order.

    .WHILE (esi < edi)
      sub edi, 1
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      add esi, 1
    .ENDW

  dtaexit:

    pop edi
    pop esi
    pop ebx

    ret

udwtoa ENDP
; --------------------------------------------------
; sdwtoa TEXTEQU <dwtoa>
; --------------------------------------------------
uwtoa PROC uwValue:WORD, pszBuffer:PTR BYTE
    movzx eax, uwValue     
    INVOKE udwtoa, eax, pszBuffer
    ret
uwtoa ENDP 
; --------------------------------------------------
swtoa PROC swValue:SWORD, pszBuffer:PTR BYTE
    movsx eax, swValue     
    INVOKE sdwtoa, eax, pszBuffer
    ret
swtoa ENDP 
; --------------------------------------------------
ubtoa PROC ubValue:BYTE, pszBuffer:PTR BYTE
    movzx eax, ubValue     
    INVOKE udwtoa, eax, pszBuffer
    ret
ubtoa ENDP
; --------------------------------------------------
sbtoa PROC sbValue:SBYTE, pszBuffer:PTR BYTE
    movsx eax, sbValue     
    INVOKE sdwtoa, eax, pszBuffer
    ret
sbtoa ENDP 
; --------------------------------------------------

END start


PBrennick

Greg,
Recently, I used this when adding syntax highlighting to my project:


udw2a proc source:DWORD, lpBuffer:DWORD
;---------------------------------------
    push    eax
    push    esi
    mov     edx, lpBuffer
    mov     esi, source
    xor     eax, eax
    xor     ecx, ecx
    mov     [edx+8], al
    mov     cl, 7
@@:
    mov     eax, esi
    and     al, 00001111b
    cmp     al,10
    sbb     al,69h
    das
    mov     [edx + ecx], al
    shr     esi, 4
    dec     ecx
    jns     @B
    pop     esi
    pop     eax
    ret
;---------------------------------------
udw2a endp


Paul
The GeneSys Project is available from:
The Repository or My crappy website

GregL

Paul,

If you need an 8 character hex string, that works great. That's tricky using DAS.  :8)


PBrennick

Greg,
yep! RGB values, of course, used for syntax highlighting. BTW, if I do not want eight characters, I use the same procedure and just filter out the leading zeroes in the calling proc. An easy way would be to use the right$ macro, I guess.  :8)

Paul
The GeneSys Project is available from:
The Repository or My crappy website