; ---------------------------------------------------------------------------
; FILE: EAX2ASCII.Asm
; DATE: May 1, 2013
; ---------------------------------------------------------------------------
align 16
EAX2ASCII_Int32_LPad:
; ---------------------------------------------------------------------------
; INPUT:
;   EAX = signed value to convert
;   EDI = ASCII buffer for converted value
;    DL = width of the field (value is padded by spaces on the left side)
; EXAMPLE:
;   EAX = -8367
;    DL = 8
;   EDI = "   -8367"
; ---------------------------------------------------------------------------
    pusha
    movzx     edx, dl
    ;
    ; Format the value into stack buffer of 16 characters
    ;
    mov       esi, edi
    sub       esp, 16
    mov       edi, esp
    call      EAX2ASCII_Int32
    ;
    ; # of spaces for padding = EDX - ECX
    ;
    sub       edx, ecx
    jbe       .copy_result
    ;
    ; Pad with spaces
    ;
.pad:
    mov       byte [esi], 20h
    add       esi, 1
    sub       edx, 1
    jnz       .pad

.copy_result:
    xchg      esi, edi
    rep       movsb
    mov       [edi], cl

    add       esp, 16
    popa
    ret

; ---------------------------------------------------------------------------
virtual at 0
loc1:
    .Buffer   rb 16
    .PadChar  db ?
    .Slush    rb 3
    .size = $
end virtual

align 16
EAX2ASCII_UInt32_LPad:
; ---------------------------------------------------------------------------
; INPUT:
;   EAX = unsigned value to convert
;   EDI = ASCII buffer for converted value
;    DL = width of the field (value is padded on the left side)
;    CL = padding character (can be '0' or space or anything else)
; ---------------------------------------------------------------------------
    pusha
    movzx     edx, dl

    sub       esp, loc1.size
    mov       ebp, esp
    mov       [ebp + loc1.PadChar], cl
    ;
    ; Format the value into stack buffer
    ;
    mov       esi, edi
    mov       edi, ebp
    call      EAX2ASCII_UInt32
    ;
    ; # of spaces for padding = EDX - ECX
    ;
    sub       edx, ecx
    jbe       .copy_result

    mov       al, [ebp + loc1.PadChar]

.pad:
    mov       [esi], al
    add       esi, 1
    sub       edx, 1
    jnz       .pad

.copy_result:
    xchg      esi, edi
    rep       movsb
    mov       [edi], cl

    add       esp, loc1.size
    popa
    ret

align 16
EAX2ASCII_Int32:
; ---------------------------------------------------------------------------
; INPUT:
;   EAX = signed value to convert
;   EDI = ASCII buffer for converted value
; OUTPUT:
;   ECX = # of characters stored at EDI (excluding null terminator)
; ---------------------------------------------------------------------------
    pusha

    xor       esi, esi
    add       eax, esi
    jns       .convert
    ;
    ; EAX is negative
    ;
    neg       eax
    mov       byte [edi], '-'
    inc       edi
    inc       esi

.convert:
    call      EAX2ASCII_UInt32
    add       ecx, esi

    mov       [esp + 6*4], ecx     ; Return # of digits stored
    popa
    ret

align 16
EAX2ASCII_UInt32:
; ---------------------------------------------------------------------------
; INPUT:
;   EAX = unsigned value to convert
;   EDI = ASCII buffer for converted value
; OUTPUT:
;   ECX = # of characters stored at EDI (excluding null terminator)
; ---------------------------------------------------------------------------
    pusha
    ;
    ; ECX = 10
    ;
    push      10
    pop       ecx

    xor       esi, esi    ; To count digits pushed on stack

.div_by_10:
    xor       edx, edx
    div       ecx
    ;
    ;  DL = binary digit
    ; EAX = result for further divisions
    ;
    add       dl, '0'
    push      edx
    inc       esi
    ;
    ; Is there more to divide?
    ;
    test      eax, eax
    jnz       .div_by_10
    ;
    ; Now stack has ESI digits.
    ; Need to pop'em all and store at EDI
    ;
    mov       ecx, esi

.store_digit:
    pop       eax
    stosb
    loop      .store_digit

    mov       [edi], cl            ; Terminate with 0
    mov       [esp + 6*4], esi     ; Return # of digits stored

    popa
    ret





