News:

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

dwtoa

Started by Jimg, January 23, 2005, 04:31:39 PM

Previous topic - Next topic

Jimg

Hutch-

What is the latest version of dwtoa that you are going to include in the next release of m32lib?

Jimg

I'm asking because there has been much discussion about the bug in the past, and the last post by you in the old forum says this is the final version-
http://www.old.masmforum.com/download.php?id=1305
but that file does not exists and I would like to make sure I'm using the corrected version.

hutch--

Jim,

This version pasted in had a minor bug in it fixed by JIBZ and exhaustively tested OK.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

  ; ---------------------------------------------------------------
  ; This procedure was written by Tim Roberts
  ; Minor fix by Jibz, December 2004
  ; ---------------------------------------------------------------

    .486
    .model flat, stdcall  ; 32 bit memory model
    option casemap :none  ; case sensitive

    .code

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

align 4

dwtoa proc dwValue:DWORD, lpBuffer:DWORD

    ; -------------------------------------------------------------
    ; convert DWORD to ascii string
    ; dwValue is value to be converted
    ; lpBuffer is the address of the receiving buffer
    ; EXAMPLE:
    ; invoke dwtoa,edx,ADDR buffer
    ;
    ; Uses: eax, ecx, edx.
    ; -------------------------------------------------------------

    push ebx
    push esi
    push edi

    mov eax, dwValue
    mov edi, [lpBuffer]

    or eax,eax
    jnz sign

  zero:
    mov word ptr [edi],30h
    ret

  sign:
    jns pos
    mov byte ptr [edi],'-'
    neg eax
    inc edi

  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
      inc edi
    .endw

    mov byte ptr [edi], 0       ; terminate the string

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

    .while (esi < edi)
      dec edi
      mov al, [esi]
      mov ah, [edi]
      mov [edi], al
      mov [esi], ah
      inc esi
    .endw

    pop edi
    pop esi
    pop ebx

    ret

dwtoa endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Jimg

Ok, maybe I'm just being dumb here, but doesn't the following:
   push ebx
    push esi
    push edi

    mov eax, dwValue
    mov edi, [lpBuffer]

    or eax,eax
    jnz sign

  zero:
    mov word ptr [edi],30h
    ret


try to return if there is a zero value with three extra things still on the stack?

Relvinian

It does.  ;-)

There are three options to fix the code correctly:

1) Add the three pops necessary before the first retun statement.
2) move the pushing of ebx, esi, edi to just after the label sign.
3) use the USES directive in the function declaration and add ebx, esi , edi then remove the pops from just before the last return.

Relvinian

MichaelW

The (generated) LEAVE instruction that precedes the RET will allow it to return safely, but it will fail to preserve EDI.

eschew obfuscation

Jibz

Amazing!

I made the fix for the imprecision more than a year ago for a previous MASM32 release, which had the ret at that strange place. Guess I should have cross checked if anything else had been updated in the meantime :green.

hutch--

Here is a quick fix with some instruction updates as well.


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

  ; ---------------------------------------------------------------
  ; This procedure was written by Tim Roberts
  ; Minor fix by Jibz, December 2004
  ; ---------------------------------------------------------------

    .486
    .model flat, stdcall  ; 32 bit memory model
    option casemap :none  ; case sensitive

    .code

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

align 4

dwtoa proc dwValue:DWORD, lpBuffer:DWORD

    ; -------------------------------------------------------------
    ; convert DWORD to ascii string
    ; dwValue is value to be converted
    ; lpBuffer is the address of the receiving buffer
    ; EXAMPLE:
    ; invoke dwtoa,edx,ADDR buffer
    ;
    ; Uses: eax, ecx, edx.
    ; -------------------------------------------------------------

    push ebx
    push esi
    push edi

    mov eax, dwValue
    mov edi, [lpBuffer]

    test eax,eax
    jnz sign

  zero:
    mov word ptr [edi],30h
    jmp dtaexit

  sign:
    jns pos
    mov byte ptr [edi],'-'
    neg eax
    add edi, 1

  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

dwtoa endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Jimg

#8
Ok, another dumb newbie question-

Why didn't you put a uses on the proc statement and get rid of the manual push/pop instructions rather than add another jump?  It all works the same, I was just wondering if there was a specific reason.  (This is a campus type question but we are already started here, and my next question will be a laboratory type question :wink)

Edit:

Ok, I see, it adds three additional instructions.  Never mind.