32/16 Integer to ASCIIZ converter

ShiftLeft 0 Tallied Votes 401 Views Share

This will take a value in EAX or AX, convert to ASCII hex with optional padding and upper or lower case

This example would yield "---fc103a"

    push    word 0x222d         ; 32 bit conversion, padd output with '-'
    push    word ASCPntr        ; Pointer to end of conversion buffer
    push    0xfc103a
    call    I2H
    inc     ax                  ; AX points to actual first character

AX pointing to 1 character before actual beginning allows for successive calls with that pointer so essentially one could convert a 1,024 bit value with this algo.

; ============================================================================================
; Converts 32/16 bit value in E(AX) to an ASCIIZ string.

;	ENTER:	ARG3: Flags & padd character
;		ARG2: Pointer to last digit position in ASCIIZ buffer
;		ARG1: Value to be converted, must be 32 bit even if only converting 16

;	LEAVE:	AX = Pointer to beginning of ASCIIZ buffer
;		Only CX & DX altered

;	FLAGS:	Unchanged

; 2015.05.05									4FH - 79 Bytes
; --------------------------------------------------------------------------------------------

    ; Arguments passed by caller
  %define   VALUE     BP +  4		; Arg 1: 16/32 bit value to be converted
  %define    BUFF     BP +  8		; Arg 2: Pointer last position ASCIIZ buffer
  %define FILL_CH     BP + 10 		; Arg 3: Flags & fill character
  %define   FLAGS     BP + 11		
    ; Bit positions in FLAGS
  %define  PADD   0			; Leading chars will be filled with FILL_CH
  %define  WIDE   1			; 32 bit conversion if ON
  %define  CASE   5			; A-F will be converted to lower case
   I2H:	push	bp
   	mov	bp, sp			; Empty proc frame so BP can address args.

	push	di			; Preserve
    ; This guarantees DF will be returned to its original state even if it's already set.
	std				; Auto decrement STOSB
    ; Initialize registers for converesion loop
	mov	eax, [VALUE]		; Get 32 bit value, only 16 might be significant
	mov	 di, [BUFF]		; Get pointer to ASCIIZ string. ES already set
	mov	 dl, [FLAGS]
	mov	 cx, 8			; Default 16 bit converesion
	bt	 dx, WIDE
	jc	.Next			; Flag OFF, doing 16 bit conversion
    ; In order to guarantee padding works correctly, MSB of EAX needs to be striped
    ; otherwise output will be padded with zeros reguardless.
	shr	 cx, 1
	and	eax, 0xffff		; Strip bits 31-16 just in case

    ; Cycle until either EAX or AX is zero or CX is zero. 
 .Next:	push	ax
 	and	al, 15			; Strip bits 7-4
 	or	al, '0'			; Convert to digit
 	cmp	al, '9'			; Is AL a letter
 	jbe	.J0
    ; Convert to alpha and optionally lower case
 	add	al, 7			; Convert to alphabetic character
 	bt	dx, CASE
 	jnc	.J0
	or	al, 32			; Convert to lower case

    ; Keep writing characters until E(AX) is null or CX is null
   .J0:	stosb				; Write to buffer 	
 	pop	ax
 	shr	eax, 4			; Shift next digit position into AL
	loopnz	.Next			; Continue until either ZF=1 or CX=0
    ; Determine if caller wants to padd remainder of buffer
 	bt	dx, PADD
 	jnc	.Done
 	mov	al, [FILL_CH]		; Get fill character from parameters
 	rep	stosb			; Fill remainder of buffer if CX > 0
 .Done:	popf				; DF is restored to its original state
	mov	ax, di			; Return pointer to begining of buffer in AX
	pop	di	
	leave				; Kill procedure frame
	ret	8			; Waste parameters