; PRDEC32.ASM -- Include-able library function file ; Mach32_DecASC: 32-bit unsigned machine integer to ASCII decimal conversion ; K. Heidenstrom (firstname.lastname@example.org) ; Modified: ; ; KH.940729.001 Started ; KH.940730.002 First fully-defined working version, renamed all labels ; KH.941114.003 Version for posting on the net in comp.lang.asm.x86 ; Notes ; ; This function converts a 32-bit unsigned machine longword in DX|AX to ASCII ; decimal representation. It is similar to the itoa() function in C. ; ; Output is controlled by two parameters specified in CX on entry. ; ; CL contains the number of digits desired in the output. This may be any ; value, from 0 to 255, but is normally in the range 1 to 10. ; ; CH contains the padder character for right-justified numbers. If this ; register is set to zero, no padding is used, and only the digits necessary ; to represent the number are output. If CH is not zero, then it is taken ; as an ASCII character to be used to pad the number on the left, to the width ; specified in CL. In this case, a space or a "0" are normally used in CH. ; ; If the number of digits specified in CL is insufficient to contain the value ; represented by DX|AX, then all columns are output as "#" characters (this is ; controlled by the PrDecOvrflowChr equate below). In this case, the routine ; will return with carry set. It will also return with carry set if CL was ; zero (i.e. no digits at all). ; ; The subroutine's stack space requirement is sixteen bytes, or twelve bytes ; plus the stack space required by the output function, whichever is greater. ; ; The output method must be specified at assembly time, by defining a ; PrDec_Output macro. This macro will be assembled into the part of the ; subroutine where the character output is required. The requirements for ; the character output macro are as follows: ; ; On entry, AL contains the character to be displayed or output. ; ; AX DX BP DI These MAY be modified by the macro code. ; BX CX SI These MUST NOT be modified by the macro code. ; DI DS ES These are not used at all by the Mach32_DecASC subroutine. ; ; This last group of registers are not used or changed by the subroutine code, ; and may be set up before entering the subroutine, then used by the output ; macro, and will be returned by the subroutine. This is intended to support ; use of STOSB as the output function macro. DI can be set up before entry to ; the subroutine, and the output function macro can contain a STOSB, and on ; return from the subroutine, DI will point past the last stored character. ; Note that the subroutine does not use, or modify, the direction flag. ; ; The output function macro is executed in left-to-right sequence as the ; digits of the output value are calculated. ; ; The total length of the PrDec_Output macro must be limited to 33 bytes (at ; the moment - this may change), in order to avoid a bad branch error at the ; end of the subroutine. ; ; Example PrDec_Output macros: ; ; MACRO PrDec_Output ; stosb ; Add digit to string being generated ; ENDM ; ; MACRO PrDec_Output ; push bx ; Preserve ; xor bx,bx ; Output to first display page ; mov ah,0Eh ; TTY output ; int 10h ; Output to BIOS ; pop bx ; Restore ; ENDM ; ; MACRO PrDec_Output ; mov dl,al ; Digit to DL ; mov ah,2 ; Char output ; int 21h ; Output to DOS ; ENDM PrDecOvrflowChr = "#" ; Char to display on overflow PROC Mach32_DecASC near ; Func: Convert unsigned long machine integer ; to ASCII decimal representation ; In: DX|AX = Value to be converted ; CL = Number of digits to display ; (normally in range 1 - 10 but all ; values are handled correctly) ; CH = Padder (typically " " or "0", or ; 0 for no leading padding) ; Out: Characters are output according to the ; PrDec_Output macro which must be defined ; before this file is included. ; CF = Overflow status: ; NC = Alright, no overflow ; CY = Overflow occurred ; Lost: Flags (DF is not affected) ; DI, DS, and ES may be modified by the ; output function macro. ; Note: Input value is treated as an unsigned ; longword, in the range 0 - 4294967295. ; Note: If the value won't fit into the number ; of digits specified, all digits are ; output as '#' symbols, indicating ; overflow, and carry is set on return. push si push bp push dx push cx push bx push ax ; Preserve registers test cl,cl jz PrDec_Error ; If no digits specified xchg ax,bx ; Loword to BX mov si,dx ; Hiword to SI ; Check digit position is within range PrDec_DigitLp: cmp cl,11 ; Check that we're at a valid digit jae PrDec_DoPad ; If not yet, just do space padding mov dx,1 ; Init loword of divisor to 1 sub cl,dl ; Get digit position jb PrDec_Exit ; If no digits, or just done last digit ; Calculate divisor in BP|DX as 10 ^ digit position number push cx ; Keep misc info in CL and CH xor bp,bp ; Hiword of divisor to zero PrDec_DivLoop: sub cl,1 ; Count down the shifts jb PrDec_GotDiv ; If done, have divisor push bp ; Push hiword mov ax,dx ; Keep loword shl dx,1 ; Multiply by two rcl bp,1 ; Carry into hiword shl dx,1 ; Multiply by two again rcl bp,1 ; Carry into hiword add dx,ax ; Now add original value to value x 4 pop ax ; Restore old hiword adc bp,ax ; Add hiwords too shl dx,1 ; Now have value x 5, double it again rcl bp,1 ; And hiword jmp SHORT PrDec_DivLoop ; Continue PrDec_GotDiv: pop cx ; Have divisor, restore CX ; Calculate digit by repeatedly dividing value in SI|BX by divisor in BP|DX xor ax,ax ; Count of divides PrDec_CalcLoop: inc ax ; Increment counter cmp al,10 ; Make sure digit is within range ja PrDec_Overflow ; If not, display overflow indication sub bx,dx ; Subtract loword of divisor from value sbb si,bp ; Borrow from hiword jnb PrDec_CalcLoop ; Borrowed below zero yet? If not, loop add bx,dx ; Restore remainder loword adc si,bp ; Restore hiword too add al,"0"-1 ; Calculate digit value in ASCII ; Check value of digit cmp al,"0" ; Is digit zero? jne PrDec_SetZero ; If not test cl,cl ; Final position? jz PrDec_GotDigit ; Force printing final zero PrDec_DoPad: mov al,ch ; If digit is zero, substitute padder jmp SHORT PrDec_GotDigit ; Continue PrDec_Overflow: mov si,-1 ; Force overflow indication from now on mov al,PrDecOvrflowChr ; Indicate overflow PrDec_SetZero: mov ch,"0" ; Had non-zero - no more padding now! PrDec_GotDigit: test al,al jz PrDec_DigitLp ; If zero, and no padding requested ; Output character in AL using appropriate output mode PrDec_Output jmp SHORT PrDec_DigitLp ; Loop for more digits PrDec_Exit: test si,si jz PrDec_Exit2 ; If didn't have overflow, exit no carry PrDec_Error: stc ; If overflow occurred, exit carry set PrDec_Exit2: pop ax pop bx pop cx pop dx pop bp pop si ; Restore registers ret ENDP Mach32_DecASC
|file: /Techref/intel/16bit/math/radix/32b-xd.htm, 7KB, , updated: 2000/2/16 13:34, local time: 2023/2/2 09:18,
|©2023 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?|
<A HREF="http://www.massmind.org/techref/intel/16bit/math/radix/32b-xd.htm"> intel 16bit math radix 32b-xd</A>
|Did you find what you needed?|
Welcome to massmind.org!
Welcome to www.massmind.org!