home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
pcmag
/
vol9n05.arc
/
ATOF.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-10-26
|
5KB
|
142 lines
title ATOF - ASCII to Binary Floating Point
page 55,132
; ATOF.ASM --- Convert ASCII String to Binary
; Floating Point Number on 80x87 Stack
; (also requires FALOG from FALOG.ASM)
;
; Copyright (C) 1989 Ziff Davis Communications
; PC Magazine * Ray Duncan
;
; Call with: DS:SI = address of string in the form
; [sign][digits][.[digits]][E|e[sign][exp]]
; leading blanks or tabs are ignored
;
; Returns: ST(0) = binary floating point value
; DS:SI = address+1 of terminator
;
; Uses: Nothing
;
; This routine gives no warning in the event of
; overflow, and terminates on the first invalid character.
;
; Make sure coprocessor has been properly initialized
; with a previous call to INIT87!
blank equ 20h ; ASCII blank character
tab equ 09h ; ASCII tab character
_DATA segment word public 'DATA'
int10 dw 10 ; integer constant 10
digit dw 0 ; current converted digit
places dw 0 ; number of decimal places
_DATA ends
_TEXT segment word public 'CODE'
assume cs:_TEXT,ds:_DATA
extrn falog:near ; we need FALOG routine
public atof
atof proc near ; ASCII to floating point
push ax ; save registers
push cx
push dx
call convert ; convert mantissa
neg dx ; save -1 * decimal places
mov places,dx
or al,20h ; fold char to lower case
cmp al,'e' ; is exponent present?
je atof1 ; yes, jump
fldz ; assume zero exponent
jmp atof2
atof1: call convert ; convert exponent
atof2: fiadd places ; adjust exponent for
; dec. places in mantissa
call falog ; raise 10 to power
fmul ; exponent * mantissa
pop dx ; restore registers
pop cx
pop ax
ret ; return ST(0) = result
atof endp
;
; CONVERT: Called by ATOF to convert ASCII number
; with possible sign and/or decimal point
; Call with: DS:SI = address of string
; Returns: ST(0) = result
; AL = first unconvertable character
; DX = number of digits after decimal point
; DS:SI = address+1 of character in AL
; Uses: AH, CX
;
convert proc near ; convert numeric field
fldz ; initialize result
xor cx,cx ; initialize sign
mov dx,-1 ; initialize decimal count
conv1: lodsb ; scan off whitespace
cmp al,blank ; ignore leading blanks
je conv1
cmp al,tab ; ignore leading tabs
je conv1
cmp al,'+' ; if + sign proceed
je conv2
cmp al,'-' ; is it - sign?
jne conv3 ; no, test if numeric
dec cx ; yes, set flag
conv2: lodsb ; get next character
conv3: cmp al,'0' ; is character valid?
jb conv4 ; jump if not '0' to '9'
cmp al,'9'
ja conv4 ; jump if not '0' to '9'
and ax,0fh ; isolate lower four bits
mov digit,ax ; and save digit value
fimul int10 ; previous value * 10
fiadd digit ; accumulate new digit
or dx,dx ; past decimal point?
js conv2 ; no, convert next digit
inc dx ; yes, count digits
jmp conv2 ; convert next digit
conv4: cmp al,'.' ; is it decimal point?
jne conv5 ; no, proceed
inc dx ; indicate decimal found
jmp conv2 ; convert more digits
conv5: jcxz conv6 ; jump if result pos.
fchs ; make result negative
conv6: or dx,dx ; decimal point found?
jns conv7 ; yes, jump
xor dx,dx ; no, return zero places
conv7: ret ; return ST(0) = result
convert endp
_TEXT ends
end