flat assembler
Message board for the users of flat assembler.

Index > Windows > Simulation of wsprintf

Author
Thread Post new topic Reply to topic
Tommy



Joined: 17 Jun 2003
Posts: 489
Location: Norway
Tommy
Just a simulation (partly finished and not optimized) of wsprintf (something for the Fresh string library??):
Code:
include "%fasminc%/win32ax.inc"

.data

        sError          db "Error: invalid pattern.",0
        sTemp           db "everybody",0
        sFormat         db "Hi %s! 4 shl 2 = %d...",0
        sOutput         rb 100h
        lBuffer         rd 2

.code

        start:
                mov     dword [lBuffer],sTemp
                mov     eax,4
                shl     eax,2
                mov     dword [lBuffer+4],eax
                stdcall FormatString,sFormat,sOutput,lBuffer
                test    eax,eax
                jnz     error
                invoke  MessageBox,0,sOutput,sFormat,0
                jmp     done
        error:
                invoke  MessageBox,0,sError,0,0
        done:
                invoke  ExitProcess,0

proc FormatString, lFormat, lOutput, lParam
    .buffer     dd ?
        enter
        mov     eax,[lParam]
        mov     [.buffer],eax
        mov     esi,[lFormat]
        mov     edi,[lOutput]
    .loop:
        lodsb
        cmp     al,"%"
        je      .param
        stosb
        test    al,al
        jnz     .loop
        jmp     .done
    .param:
        lodsb
        cmp     al,"%"
        jne     .string
        stosb
        jmp     .loop
      .string:
        cmp     al,"s"
        jne     .decimal
        push    esi
        mov     eax,[.buffer]
        mov     esi,[eax]
        add     [.buffer],4
      .string_loop:
        lodsb
        test    al,al
        jz      .string_loop.end
        stosb
        jmp     .string_loop
      .string_loop.end:
        pop     esi
        jmp     .loop
      .decimal:
        push    esi
        cmp     al,"d"
        jne     .error
        mov     esi,[.buffer]
        mov     eax,[esi]
        add     [.buffer],4
        xor     ecx,ecx
        mov     ebx,10
      .decimal_loop:
        xor     edx,edx
        div     ebx
        push    edx
        inc     ecx
        test    eax,eax
        jnz     .decimal_loop
      .decimal_loop_output:
        pop     eax
        add     al,30h
        stosb
        loop    .decimal_loop_output
        pop     esi
        jmp     .loop
    .error:
        or      eax,-1
        return
    .done:
        xor     eax,eax
        return

.end start    
Post 17 Feb 2004, 13:22
View user's profile Send private message Visit poster's website Reply with quote
roticv



Joined: 19 Jun 2003
Posts: 374
Location: Singapore
roticv
Post 17 Feb 2004, 13:26
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
Tommy



Joined: 17 Jun 2003
Posts: 489
Location: Norway
Tommy
Hmm...No, not until now... Very Happy
Post 17 Feb 2004, 15:27
View user's profile Send private message Visit poster's website Reply with quote
Tommy



Joined: 17 Jun 2003
Posts: 489
Location: Norway
Tommy
Here's an improved version of the procedure... Very Happy
Code:
; string.format (sFormat, sOutput, [args])
;   sFormat:    string containing the pattern of the output string
;                 %s: string
;                 %d: decimal number
;                 %h: hexadecimal number in lower case
;                 %H: hexadecimal number in upper case
;
;                 %d, %h and %H also accepts ":[number of fixed digits]"
;                 The number in the square brackets should then be in
;                 [0..9] and equal one less the number of fixed digits...
;   sOutput:    pointer to buffer which will receive the output string
;   [args]:     ...
;
; Put these two variables in the data section:
;   alpha_addition  db 0
;   digit_count     db 0
string.format:
        enter   0,0
        mov     edx,16
        mov     esi,[ebp+8]
        mov     edi,[ebp+12]
  .loop:
        lodsb
        cmp     al,"%"
        je      .format
        stosb
        test    al,al
        jnz     .loop
  .done:
        xor     eax,eax
        jmp     .finish
  .error:
        or      eax,-1
  .finish:
        leave
        pop     eax
        sub     edx,8
        add     esp,edx
        jmp     eax
  .format:
        lodsb
        cmp     al,"%"
        jne     .not_percent
        stosb
        jmp     .loop
    .not_percent:
        mov     [digit_count],0
        push    eax
        cmp     byte [esi],":"
        jne     .not_extra
        lodsb
        cmp     byte [esi],":"
        je      .not_extra
        lodsb
        cmp     al,"0"
        jl      .error
        cmp     al,"9"
        jg      .error
        sub     al,2Fh
        mov     [digit_count],al
      .not_extra:
        pop     eax
        cmp     al,"s"
        je      .string
        cmp     al,"h"
        je      .number.lhex
        cmp     al,"H"
        je      .number.uhex
        cmp     al,"d"
        jne     .error
    .number.dec:
        mov     ebx,10
        call    .number
        jmp     .loop
    .number.lhex:
        mov     byte [alpha_addition],27h
        mov     ebx,16
        call    .number
        jmp     .loop
    .number.uhex:
        mov     byte [alpha_addition],7
        mov     ebx,16
        call    .number
        jmp     .loop
    .number:
        mov     eax,[ebp+edx]
        add     edx,4
        push    edx
        xor     ecx,ecx
      .number.loop:
        xor     edx,edx
        div     ebx
        push    edx
        inc     ecx
        test    eax,eax
        jnz     .number.loop
        cmp     [digit_count],0
        je      .number.putchar
        push    ecx
        mov     eax,ecx
        movzx   ecx,byte [digit_count]
        sub     ecx,eax
        jz      .number.prefix.end
        js      .number.prefix.end
        mov     al,"0"
      .number.prefix:
        stosb
        loop    .number.prefix
      .number.prefix.end:
        pop     ecx
      .number.putchar:
        pop     eax
        add     al,30h
        cmp     al,39h
        jle     .number.putchar.nonalpha
        add     al,[alpha_addition]
      .number.putchar.nonalpha:
        stosb
        loop    .number.putchar
        pop     edx
        ret
    .string:
        push    esi
        mov     esi,[ebp+edx]
        add     edx,4
      .string.loop:
        lodsb
        test    al,al
        jz      .string.end
        stosb
        jmp     .string.loop
      .string.end:
        pop     esi
        jmp     .loop    
Example of usage:
Code:
sFormat         db "Hi %s! %d-lol",13,10
                db "%s = offset: 0x%H:7",0
sOutput         rb 100h
sTemp           db "everybody",0
sLabel          db "start",0

stdcall         string.format,sFormat,sOutput,sTemp,16,sLabel,start
    
Post 17 Feb 2004, 17:45
View user's profile Send private message Visit poster's website Reply with quote
Vortex



Joined: 17 Jun 2003
Posts: 318
Vortex
Tommy,

Nice work. Thanks.

_________________
Code it... That's all...
Post 18 Feb 2004, 18:25
View user's profile Send private message Visit poster's website 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.