home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 April
/
Chip_1997-04_cd.bin
/
prezent
/
cb
/
data.z
/
FFMT.ASM
< prev
next >
Wrap
Assembly Source File
|
1997-01-16
|
16KB
|
1,112 lines
; *******************************************************
; * *
; * Delphi Runtime Library *
; * Floating point formatting routines *
; * *
; * Copyright (c) 1995,96 Borland International *
; * *
; *******************************************************
TITLE FFMT
.386
.MODEL FLAT
INCLUDE SE.ASM
; TFloatRec layout
fdExponent EQU (WORD PTR 0)
fdNegative EQU (BYTE PTR 2)
fdDigits EQU (BYTE PTR 3)
fdRecSize EQU 24
; TFloatValue constants
fvExtended EQU 0
fvCurrency EQU 1
; TFloatFormat constants
ffGeneral EQU 0
ffExponent EQU 1
ffFixed EQU 2
ffNumber EQU 3
ffCurrency EQU 4
; 1E18 as a 64-bit integer
Const1E18Lo EQU 0A7640000H
Const1E18Hi EQU 00DE0B6B3H
; Externals
EXTRN FPower10:NEAR
EXTRN CurrencyString:DWORD
EXTRN CurrencyFormat:BYTE
EXTRN NegCurrFormat:BYTE
EXTRN ThousandSeparator:BYTE
EXTRN DecimalSeparator:BYTE
; Publics
PUBLIC FloatToText,FloatToTextFmt,FloatToDecimal,TextToFloat
.CODE
; Constants
DCon10 DD 10
DCon100 DD 100
DCon1000 DD 1000
DCon10000 DD 10000
FCon1E18 DT 1E18
; 8087 control word
; Infinity control = 1 Affine
; Rounding Control = 0 Round to nearest or even
; Precision Control = 3 64 bits
; All interrupts masked
CWNear DW 133FH
; INF and NAN strings
INFNAN DB 'INFNAN'
; function FloatToText(Buffer: PChar; const Value; ValueType: TFloatValue;
; Format: TFloatFormat; Precision, Digits: Integer): Integer;
FloatToText:
ARG BufferArg,DWORD,1
ARG Value,DWORD,1
ARG ValueType,BYTE,4
ARG Format,BYTE,4
ARG Precision,DWORD,1
ARG Digits,DWORD,1
LOC Buffer,DWORD,1
LOC FloatRec,BYTE,fdRecSize
ENTRY FAR
PUSH EDI
PUSH ESI
PUSH EBX
MOV Buffer,EAX
MOV EAX,19
CMP CL,fvExtended
JNE @@2
MOV EAX,Precision
CMP EAX,2
JGE @@1
MOV EAX,2
@@1: CMP EAX,18
JLE @@2
MOV EAX,18
@@2: MOV Precision,EAX
PUSH EAX
MOV EAX,9999
CMP Format,ffFixed
JB @@3
MOV EAX,Digits
@@3: PUSH EAX
LEA EAX,FloatRec
CALL FloatToDecimal
MOV EDI,Buffer
MOVZX EAX,FloatRec.fdExponent
SUB EAX,7FFFH
CMP EAX,2
JAE @@4
LEA ESI,INFNAN[EAX+EAX*2]
MOV ECX,3
REP MOVSB
JMP @@7
@@4: LEA ESI,FloatRec.fdDigits
MOVZX EBX,Format
CMP BL,ffExponent
JE @@6
CMP BL,ffCurrency
JA @@5
MOVSX EAX,FloatRec.fdExponent
CMP EAX,Precision
JLE @@6
@@5: MOV BL,ffGeneral
@@6: CALL DWORD PTR FormatVector[EBX*4]
@@7: MOV EAX,EDI
SUB EAX,Buffer
POP EBX
POP ESI
POP EDI
EXIT
FormatVector LABEL DWORD
DD PutFGeneral
DD PutFExponent
DD PutFFixed
DD PutFNumber
DD PutFCurrency
; Get digit or '0' if at end of digit string
GetDigit:
LODSB
OR AL,AL
JNE @@1
MOV AL,'0'
DEC ESI
@@1: RET
; Store '-' if number is negative
PutSign:
CMP FloatRec.fdNegative,0
JE @@1
MOV AL,'-'
STOSB
@@1: RET
; Convert number using ffGeneral format
PutFGeneral:
CALL PutSign
MOVSX ECX,FloatRec.fdExponent
XOR EDX,EDX
CMP ECX,Precision
JG @@1
CMP ECX,-3
JL @@1
OR ECX,ECX
JG @@2
MOV AL,'0'
STOSB
CMP BYTE PTR [ESI],0
JE @@6
MOV AL,DecimalSeparator
STOSB
NEG ECX
MOV AL,'0'
REP STOSB
JMP @@3
@@1: MOV ECX,1
INC EDX
@@2: LODSB
OR AL,AL
JE @@4
STOSB
LOOP @@2
LODSB
OR AL,AL
JE @@5
MOV AH,AL
MOV AL,DecimalSeparator
STOSW
@@3: LODSB
OR AL,AL
JE @@5
STOSB
JMP @@3
@@4: MOV AL,'0'
REP STOSB
@@5: OR EDX,EDX
JE @@6
XOR EAX,EAX
XOR ECX,ECX
JMP PutFloatExp
@@6: RET
; Convert number using ffExponent format
PutFExponent:
CALL PutSign
CALL GetDigit
MOV AH,DecimalSeparator
STOSW
MOV ECX,Precision
DEC ECX
@@1: CALL GetDigit
STOSB
LOOP @@1
MOV AH,'+'
MOV ECX,Digits
CMP ECX,4
JB PutFloatExp
XOR ECX,ECX
; JMP PutFloatExp
; Store exponent
; In AH = Positive sign character ('+' or 0)
; ECX = Minimum number of digits (0..4)
PutFloatExp:
MOV AL,'E'
MOV BL,FloatRec.fdDigits
MOVSX EDX,FloatRec.fdExponent
DEC EDX
; JMP PutExponent
; Store exponent
; In AL = Exponent character ('E' or 'e')
; AH = Positive sign character ('+' or 0)
; BL = Zero indicator
; ECX = Minimum number of digits (0..4)
; EDX = Exponent
PutExponent:
STOSB
OR BL,BL
JNE @@0
XOR EDX,EDX
JMP @@1
@@0: OR EDX,EDX
JGE @@1
MOV AL,'-'
NEG EDX
JMP @@2
@@1: OR AH,AH
JE @@3
MOV AL,AH
@@2: STOSB
@@3: XCHG EAX,EDX
PUSH EAX
MOV EBX,ESP
@@4: XOR EDX,EDX
DIV DCon10
ADD DL,'0'
MOV [EBX],DL
INC EBX
DEC ECX
OR EAX,EAX
JNE @@4
OR ECX,ECX
JG @@4
@@5: DEC EBX
MOV AL,[EBX]
STOSB
CMP EBX,ESP
JNE @@5
POP EAX
RET
; Convert number using ffFixed or ffNumber format
PutFFixed:
PutFNumber:
CALL PutSign
; Store number in fixed point format
PutNumber:
MOV EDX,Digits
CMP EDX,18
JB @@1
MOV EDX,18
@@1: MOVSX ECX,FloatRec.fdExponent
OR ECX,ECX
JG @@2
MOV AL,'0'
STOSB
JMP @@4
@@2: XOR EBX,EBX
CMP Format,ffFixed
JE @@3
MOV EAX,ECX
DEC EAX
MOV BL,3
DIV BL
MOV BL,AH
INC EBX
@@3: CALL GetDigit
STOSB
DEC ECX
JE @@4
DEC EBX
JNE @@3
MOV AL,ThousandSeparator
STOSB
MOV BL,3
JMP @@3
@@4: OR EDX,EDX
JE @@7
MOV AL,DecimalSeparator
STOSB
JECXZ @@6
MOV AL,'0'
@@5: STOSB
DEC EDX
JE @@7
INC ECX
JNE @@5
@@6: CALL GetDigit
STOSB
DEC EDX
JNE @@6
@@7: RET
; Convert number using ffCurrency format
PutFCurrency:
XOR EBX,EBX
MOV BL,CurrencyFormat
MOV ECX,0003H
CMP FloatRec.fdNegative,0
JE @@1
MOV BL,NegCurrFormat
MOV ECX,040FH
@@1: CMP BL,CL
JBE @@2
MOV BL,CL
@@2: ADD BL,CH
LEA EBX,MoneyFormats[EBX+EBX*4]
MOV ECX,5
@@10: MOV AL,[EBX]
CMP AL,'@'
JE @@14
PUSH ECX
PUSH EBX
CMP AL,'$'
JE @@11
CMP AL,'*'
JE @@12
STOSB
JMP @@13
@@11: CALL PutCurSym
JMP @@13
@@12: CALL PutNumber
@@13: POP EBX
POP ECX
INC EBX
LOOP @@10
@@14: RET
; Store currency symbol string
PutCurSym:
PUSH ESI
MOV ESI,CurrencyString
TEST ESI,ESI
JE @@1
MOV ECX,[ESI-4]
REP MOVSB
@@1: POP ESI
RET
; Currency formatting templates
MoneyFormats LABEL BYTE
DB '$*@@@'
DB '*$@@@'
DB '$ *@@'
DB '* $@@'
DB '($*)@'
DB '-$*@@'
DB '$-*@@'
DB '$*-@@'
DB '(*$)@'
DB '-*$@@'
DB '*-$@@'
DB '*$-@@'
DB '-* $@'
DB '-$ *@'
DB '* $-@'
DB '$ *-@'
DB '$ -*@'
DB '*- $@'
DB '($ *)'
DB '(* $)'
; function FloatToTextFmt(Buffer: PChar; const Value; ValueType: TValueType;
; Format: PChar): Integer;
FloatToTextFmt:
ARG BufferArg,DWORD,1
ARG Value,DWORD,1
ARG ValueType,BYTE,4
ARG Format,DWORD,1
LOC Buffer,DWORD,1
LOC ThousandSep,BYTE,4
LOC Scientific,BYTE,4
LOC Section,DWORD,1
LOC DigitCount,DWORD,1
LOC DecimalIndex,DWORD,1
LOC FirstDigit,DWORD,1
LOC LastDigit,DWORD,1
LOC DigitPlace,DWORD,1
LOC DigitDelta,DWORD,1
LOC FloatRec,BYTE,fdRecSize
ENTRY FAR
PUSH EDI
PUSH ESI
PUSH EBX
MOV Buffer,EAX
MOV EDI,EDX
MOV EBX,ECX
MOV ECX,2
CMP BL,fvExtended
JE @@1
MOV EAX,[EDI].d0
OR EAX,[EDI].d4
JE @@2
MOV ECX,[EDI].d4
SHR ECX,31
JMP @@2
@@1: MOVZX EAX,[EDI].w8
OR EAX,[EDI].d0
OR EAX,[EDI].d4
JE @@2
MOVZX ECX,[EDI].w8
SHR ECX,15
@@2: CALL FindSection
JE @@5
CALL ScanSection
MOV EAX,DigitCount
MOV EDX,9999
CMP Scientific,0
JNE @@3
SUB EAX,DecimalIndex
MOV EDX,EAX
MOV EAX,18
@@3: PUSH EAX
PUSH EDX
LEA EAX,FloatRec
MOV EDX,EDI
MOV ECX,EBX
CALL FloatToDecimal
MOV AX,FloatRec.fdExponent
CMP AX,8000H
JE @@5
CMP AX,7FFFH
JE @@5
CMP BL,fvExtended
JNE @@6
CMP AX,18
JLE @@6
CMP Scientific,0
JNE @@6
@@5: PUSH ffGeneral
PUSH 15
PUSH 0
MOV EAX,Buffer
MOV EDX,EDI
MOV ECX,EBX
CALL FloatToText
JMP @@8
@@6: CMP FloatRec.fdDigits,0
JNE @@7
MOV ECX,2
CALL FindSection
JE @@5
CMP ESI,Section
JE @@7
CALL ScanSection
@@7: CALL ApplyFormat
@@8: POP EBX
POP ESI
POP EDI
EXIT
; Find format section
; In ECX = Section index
; Out ESI = Section offset
; ZF = 1 if section is empty
FindSection:
MOV ESI,Format
JECXZ @@2
@@1: LODSB
CMP AL,"'"
JE @@4
CMP AL,'"'
JE @@4
OR AL,AL
JE @@2
CMP AL,';'
JNE @@1
LOOP @@1
MOV AL,[ESI]
OR AL,AL
JE @@2
CMP AL,';'
JNE @@3
@@2: MOV ESI,Format
MOV AL,[ESI]
OR AL,AL
JE @@3
CMP AL,';'
@@3: RET
@@4: MOV AH,AL
@@5: LODSB
CMP AL,AH
JE @@1
OR AL,AL
JNE @@5
JMP @@2
; Scan format section
ScanSection:
PUSH EBX
MOV Section,ESI
MOV EBX,32767
XOR ECX,ECX
XOR EDX,EDX
MOV DecimalIndex,-1
MOV ThousandSep,DL
MOV Scientific,DL
@@1: LODSB
@@2: CMP AL,'#'
JE @@10
CMP AL,'0'
JE @@11
CMP AL,'.'
JE @@13
CMP AL,','
JE @@14
CMP AL,"'"
JE @@15
CMP AL,'"'
JE @@15
CMP AL,'E'
JE @@20
CMP AL,'e'
JE @@20
CMP AL,';'
JE @@30
OR AL,AL
JNE @@1
JMP @@30
@@10: INC EDX
JMP @@1
@@11: CMP EDX,EBX
JGE @@12
MOV EBX,EDX
@@12: INC EDX
MOV ECX,EDX
JMP @@1
@@13: CMP DecimalIndex,-1
JNE @@1
MOV DecimalIndex,EDX
JMP @@1
@@14: MOV ThousandSep,1
JMP @@1
@@15: MOV AH,AL
@@16: LODSB
CMP AL,AH
JE @@1
OR AL,AL
JNE @@16
JMP @@30
@@20: LODSB
CMP AL,'-'
JE @@21
CMP AL,'+'
JNE @@2
@@21: MOV Scientific,1
@@22: LODSB
CMP AL,'0'
JE @@22
JMP @@2
@@30: MOV DigitCount,EDX
CMP DecimalIndex,-1
JNE @@31
MOV DecimalIndex,EDX
@@31: MOV EAX,DecimalIndex
SUB EAX,ECX
JLE @@32
XOR EAX,EAX
@@32: MOV LastDigit,EAX
MOV EAX,DecimalIndex
SUB EAX,EBX
JGE @@33
XOR EAX,EAX
@@33: MOV FirstDigit,EAX
POP EBX
RET
; Apply format string
ApplyFormat:
CMP Scientific,0
JE @@1
MOV EAX,DecimalIndex
XOR EDX,EDX
JMP @@3
@@1: MOVSX EAX,FloatRec.fdExponent
CMP EAX,DecimalIndex
JG @@2
MOV EAX,DecimalIndex
@@2: MOVSX EDX,FloatRec.fdExponent
SUB EDX,DecimalIndex
@@3: MOV DigitPlace,EAX
MOV DigitDelta,EDX
MOV ESI,Section
MOV EDI,Buffer
LEA EBX,FloatRec.fdDigits
CMP FloatRec.fdNegative,0
JE @@10
CMP ESI,Format
JNE @@10
MOV AL,'-'
STOSB
@@10: LODSB
CMP AL,'#'
JE @@20
CMP AL,'0'
JE @@20
CMP AL,'.'
JE @@10
CMP AL,','
JE @@10
CMP AL,"'"
JE @@25
CMP AL,'"'
JE @@25
CMP AL,'E'
JE @@30
CMP AL,'e'
JE @@30
CMP AL,';'
JE @@40
OR AL,AL
JE @@40
@@11: STOSB
JMP @@10
@@20: CALL PutFmtDigit
JMP @@10
@@25: MOV AH,AL
@@26: LODSB
CMP AL,AH
JE @@10
OR AL,AL
JE @@40
STOSB
JMP @@26
@@30: MOV AH,[ESI]
CMP AH,'+'
JE @@31
CMP AH,'-'
JNE @@11
XOR AH,AH
@@31: MOV ECX,-1
@@32: INC ECX
INC ESI
CMP [ESI].b0,'0'
JE @@32
CMP ECX,4
JB @@33
MOV ECX,4
@@33: PUSH EBX
MOV BL,FloatRec.fdDigits
MOVSX EDX,FloatRec.fdExponent
SUB EDX,DecimalIndex
CALL PutExponent
POP EBX
JMP @@10
@@40: MOV EAX,EDI
SUB EAX,Buffer
RET
; Store formatted digit
PutFmtDigit:
CMP DigitDelta,0
JE @@3
JL @@2
@@1: CALL @@3
DEC DigitDelta
JNE @@1
JMP @@3
@@2: INC DigitDelta
MOV EAX,DigitPlace
CMP EAX,FirstDigit
JLE @@4
JMP @@7
@@3: MOV AL,[EBX]
INC EBX
OR AL,AL
JNE @@5
DEC EBX
MOV EAX,DigitPlace
CMP EAX,LastDigit
JLE @@7
@@4: MOV AL,'0'
@@5: CMP DigitPlace,0
JNE @@6
MOV AH,AL
MOV AL,DecimalSeparator
STOSW
JMP @@7
@@6: STOSB
CMP ThousandSep,0
JE @@7
MOV EAX,DigitPlace
CMP EAX,1
JLE @@7
MOV DL,3
DIV DL
CMP AH,1
JNE @@7
MOV AL,ThousandSeparator
STOSB
@@7: DEC DigitPlace
RET
; procedure FloatToDecimal(var Result: TFloatDecimal; const Value;
; ValueType: TValueType; Precision, Decimals: Integer);
FloatToDecimal:
ARG Result,DWORD,1
ARG Value,DWORD,1
ARG ValueType,BYTE,4
ARG Precision,DWORD,1
ARG Decimals,DWORD,1
LOC StatWord,WORD,2
LOC Exponent,DWORD,1
LOC Temp,QWORD,1
LOC BCDValue,TBYTE,1
ENTRY FAR
PUSH EDI
PUSH ESI
PUSH EBX
MOV EBX,EAX
MOV ESI,EDX
CMP CL,fvExtended
JE @@1
CALL CurrToDecimal
JMP @@2
@@1: CALL ExtToDecimal
@@2: POP EBX
POP ESI
POP EDI
EXIT
; Convert Extended to decimal
ExtToDecimal:
MOV AX,[ESI].w8
MOV EDX,EAX
AND EAX,7FFFH
JE @@1
CMP EAX,7FFFH
JNE @@10
CMP [ESI].w6,8000H
JE @@2
INC EAX
@@1: XOR EDX,EDX
@@2: MOV [EBX].fdDigits,0
JMP @@31
@@10: FLD TBYTE PTR [ESI]
SUB EAX,3FFFH
IMUL EAX,19728
SAR EAX,16
INC EAX
MOV Exponent,EAX
MOV EAX,18
SUB EAX,Exponent
FABS
CALL FPower10
FRNDINT
FLD FCon1E18
FCOMP
FSTSW StatWord
FWAIT
TEST StatWord,mC0+mC3
JE @@11
FIDIV DCon10
INC Exponent
@@11: FBSTP BCDValue
LEA EDI,[EBX].fdDigits
MOV EDX,9
FWAIT
@@12: MOV AL,BCDValue[EDX-1].b0
MOV AH,AL
SHR AL,4
AND AH,0FH
ADD AX,'00'
STOSW
DEC EDX
JNE @@12
XOR AL,AL
STOSB
@@20: MOV EDI,Exponent
ADD EDI,Decimals
JNS @@21
XOR EAX,EAX
JMP @@1
@@21: CMP EDI,Precision
JB @@22
MOV EDI,Precision
@@22: CMP EDI,18
JAE @@26
CMP [EBX].fdDigits[EDI],'5'
JB @@25
@@23: MOV [EBX].fdDigits[EDI],0
DEC EDI
JS @@24
INC [EBX].fdDigits[EDI]
CMP [EBX].fdDigits[EDI],'9'
JA @@23
JMP @@30
@@24: MOV [EBX].fdDigits.w0,'1'
INC Exponent
JMP @@30
@@26: MOV EDI,18
@@25: MOV [EBX].fdDigits[EDI],0
DEC EDI
JS @@30
CMP [EBX].fdDigits[EDI],'0'
JE @@25
@@30: MOV EAX,Exponent
MOV DX,[ESI].w8
@@31: SHR DX,15
MOV [EBX].fdExponent,AX
MOV [EBX].fdNegative,DL
RET
; Convert Currency to decimal
CurrToDecimal:
MOV EAX,[ESI].d0
MOV EDX,[ESI].d4
MOV ECX,EAX
OR ECX,EDX
JE @@20
OR EDX,EDX
JNS @@1
NEG EDX
NEG EAX
SBB EDX,0
@@1: XOR ECX,ECX
MOV EDI,Decimals
OR EDI,EDI
JGE @@2
XOR EDI,EDI
@@2: CMP EDI,4
JL @@4
MOV EDI,4
@@3: INC ECX
SUB EAX,Const1E18Lo
SBB EDX,Const1E18Hi
JNC @@3
DEC ECX
ADD EAX,Const1E18Lo
ADC EDX,Const1E18Hi
@@4: MOV Temp.d0,EAX
MOV Temp.d4,EDX
FILD Temp
MOV EDX,EDI
MOV EAX,4
SUB EAX,EDX
JE @@5
FIDIV DCon10[EAX*4-4]
@@5: FBSTP BCDValue
LEA EDI,[EBX].fdDigits
FWAIT
OR ECX,ECX
JNE @@11
MOV ECX,9
@@10: MOV AL,BCDValue[ECX-1].b0
MOV AH,AL
SHR AL,4
JNE @@13
MOV AL,AH
AND AL,0FH
JNE @@14
DEC ECX
JNE @@10
JMP @@20
@@11: MOV AL,CL
ADD AL,'0'
STOSB
MOV ECX,9
@@12: MOV AL,BCDValue[ECX-1].b0
MOV AH,AL
SHR AL,4
@@13: ADD AL,'0'
STOSB
MOV AL,AH
AND AL,0FH
@@14: ADD AL,'0'
STOSB
DEC ECX
JNE @@12
MOV EAX,EDI
LEA ECX,[EBX].fdDigits[EDX]
SUB EAX,ECX
@@15: MOV BYTE PTR [EDI],0
DEC EDI
CMP BYTE PTR [EDI],'0'
JE @@15
MOV EDX,[ESI].d4
SHR EDX,31
JMP @@21
@@20: XOR EAX,EAX
XOR EDX,EDX
MOV [EBX].fdDigits,AL
@@21: MOV [EBX].fdExponent,AX
MOV [EBX].fdNegative,DL
RET
; function TextToFloat(var Buffer; var Value;
; ValueType: TFloatValue): Boolean;
TextToFloat:
ARG Buffer,DWORD,1
ARG Value,DWORD,1
ARG ValueType,BYTE,4
LOC Temp,DWORD,1
LOC CtrlWord,WORD,1
ENTRY FAR
PUSH EDI
PUSH ESI
PUSH EBX
MOV ESI,EAX
MOV EDI,EDX
MOV EBX,ECX
FSTCW CtrlWord
FCLEX
FLDCW CWNear
FLDZ
CALL SkipBlanks
MOV BH,[ESI]
CMP BH,'+'
JE @@1
CMP BH,'-'
JNE @@2
@@1: INC ESI
@@2: MOV ECX,ESI
CALL GetDigitStr
XOR EDX,EDX
MOV AL,[ESI]
CMP AL,DecimalSeparator
JNE @@3
INC ESI
CALL GetDigitStr
NEG EDX
@@3: CMP ECX,ESI
JE @@9
MOV AL,[ESI]
AND AL,0DFH
CMP AL,'E'
JNE @@4
INC ESI
PUSH EDX
CALL GetExponent
POP EAX
ADD EDX,EAX
@@4: CALL SkipBlanks
CMP BYTE PTR [ESI],0
JNE @@9
MOV EAX,EDX
CMP BL,fvCurrency
JNE @@5
ADD EAX,4
@@5: CALL FPower10
CMP BH,'-'
JNE @@6
FCHS
@@6: CMP BL,fvExtended
JE @@7
FISTP QWORD PTR [EDI]
JMP @@8
@@7: FSTP TBYTE PTR [EDI]
@@8: FSTSW AX
TEST AX,mIE+mOE
JNE @@10
MOV AL,1
JMP @@11
@@9: FSTP ST(0)
@@10: XOR EAX,EAX
@@11: FCLEX
FLDCW CtrlWord
FWAIT
POP EBX
POP ESI
POP EDI
EXIT
; Skip blanks
SkipBlanks:
@@1: LODSB
OR AL,AL
JE @@2
CMP AL,' '
JE @@1
@@2: DEC ESI
RET
; Process string of digits
; Out EDX = Digit count
GetDigitStr:
XOR EAX,EAX
XOR EDX,EDX
@@1: LODSB
SUB AL,'0'+10
ADD AL,10
JNC @@2
FIMUL DCon10
MOV Temp,EAX
FIADD Temp
INC EDX
JMP @@1
@@2: DEC ESI
RET
; Get exponent
; Out EDX = Exponent (-4999..4999)
GetExponent:
XOR EAX,EAX
XOR EDX,EDX
MOV CL,[ESI]
CMP CL,'+'
JE @@1
CMP CL,'-'
JNE @@2
@@1: INC ESI
@@2: MOV AL,[ESI]
SUB AL,'0'+10
ADD AL,10
JNC @@3
INC ESI
IMUL EDX,10
ADD EDX,EAX
CMP EDX,500
JB @@2
@@3: CMP CL,'-'
JNE @@4
NEG EDX
@@4: RET
END