; codeasb.asm converts an ASCII numeric string to a double word
; binary equivalent
;
; Inputs: SI points to the string that is to be converted. It is edited
; to ensure it is valid data.
; CX has the count of ASCII characters which may exceed the
; count of digits.
; Process: The procedure scans the string to get the count of digits. It
; fetches decimal digit pairs from left to right. The prior
; result is multiplied by 100, the new pair is converted to binary
; and added to the prior result. Each pair in the source is
; processed. (If an odd # of digits are presented, the first digit
; is processed alone.)
; Output: If the conversion is without overflow, carry is reset and EAX
; contains the result.
; If the conversion overflows, carry is set and EAX is undefined.
; If no digits are valid, the result is zero in EAX.
; SI points to the digit following the last character converted
; and CX contains the remaining count.
;
.model small
.386
public codeasb
.code
codeasb proc
push ebx
push edx
push di
push si ; save first character pointer
sub ebx,ebx ; clear the result
sub eax,eax ; and the rest of eax.
cld ; force direction to up
cmp byte ptr[si],'-' ; negative ?
je signed ; yes
cmp byte ptr[si],'+' ; positive
jne unsigned ; no, skip
signed:
inc si ; step over of sign
dec cx ; and counting it
unsigned:
push si ; save for conversion pass
mov di,cx ; save char count
mov dx,0930h ; set '0' in dl and 9 in dh
jcxz numdone
numscan:
lodsb ; get a possible digit
xor al,dl
cmp al,dh ; check if it is a digit
ja numdone
loop numscan
numdone:
pop si ; restore for conversion pass
xchg cx,di ; set original count
sub cx,di ; and get digit count
test cl,1 ; is the count odd ?
jz cxeven ; no, skip
lodsb ; the load of the first byte
and al,15 ; as a binary value.
mov bl,al ; we have a starting value
cxeven:
shr cx,1 ; divide the count by 2
jz outgood ; if the result is zero - out
push ebp
mov ebp,100 ; get multiplier in a register
dopair:
lodsw ; get pair of bytes(reversed)
xchg al,ah ; back in proper order
and ax,0f0fh ; clear zones
aad ; convert pair to binary
xchg eax,ebx ; position accum for mpy
mul ebp ; and make room for digits
or edx,edx ; check for overflow
jnz outoflo ; out if it did
or eax,eax ; check overflow into sign
js outoflo ; out if it did
add eax,ebx ; add new pair in
jo outoflo ; exit if overflow occured
xchg eax,ebx ; put registers back
loop dopair ; do each pair
pop ebp ; restore ebp
outgood: ; go back
mov eax,ebx ; with number in eax
mov cx,di ; remaining count in cx
pop bx ; restore the sign pointer
cmp byte ptr [bx],'-' ; was a minus entered ?
jne positive ; nope
neg eax ; force it minus
positive:
clc ; clear carry(neg could set)
pop di ; restore the entry registers
pop edx ;
pop ebx ;
ret ;
outoflo:
pop ebp ; restore the work registers
stc ; set error then
pop di ; clear sign pointer
pop di ; restore the entry registers
pop edx ;
pop ebx ;
ret
codeasb endp
end