Annotation of coherent/b/lib/libc/gen/i8086/atof.s, revision 1.1

1.1     ! root        1: ////////
        !             2: /
        !             3: / Intel 8086 C runtime.
        !             4: / convert ascii string to double binary.
        !             5: / small model.
        !             6: /
        !             7: ////////
        !             8: 
        !             9:        .globl  atof_
        !            10:        .globl  _fpac_
        !            11: 
        !            12: ////////
        !            13: /
        !            14: / ** atof_ -- convert ascii string to double binary.
        !            15: /
        !            16: / this routine converts a floating point number from ascii into double
        !            17: / precision floating point binary. it is c callable. conversion  stops
        !            18: / on the first illegal character. there is no error status passed back
        !            19: / for bad numbers or over/underflows. this version of atof does decvax
        !            20: / floating point; it can be changed to do ieee trivially (look at  the
        !            21: / conversion routine in n0/lex.c to see how to do this).
        !            22: /
        !            23: / calling sequence:
        !            24: /      double  atof();
        !            25: /      double  d;
        !            26: /      char    *p;
        !            27: /      d = atof(p);
        !            28: /
        !            29: / outputs:
        !            30: /      _fpac_=result.
        !            31: /
        !            32: / uses:
        !            33: /      ax, bx, cx, dx
        !            34: /
        !            35: ////////
        !            36: 
        !            37: string =       8                       / the string argument
        !            38: binexp =       -2                      / binary exponant
        !            39: decexp =       -4                      / decimal exponant (byte)
        !            40: flags  =       -3                      / flags (byte)
        !            41: fldexp =       -4                      / for clearing flags/decexp
        !            42: num    =       -12                     / a scratch double.
        !            43: 
        !            44: claim  =       12                      / number of bytes of autos.
        !            45: negnum =       0x01                    / negative number (must be 01)
        !            46: negexp =       0x02                    / negative exponant
        !            47: gotdot =       0x04                    / got dot flag
        !            48: 
        !            49: ten:   .byte   10                      / a 10 in the code segment.
        !            50: 
        !            51: atof_: push    si                      / standard
        !            52:        push    di                      / c
        !            53:        push    bp                      / function
        !            54:        mov     bp,sp                   / linkage
        !            55: 
        !            56:        sub     sp,$claim               / get space for autos
        !            57:        cld                             / make lodsb increment si.
        !            58: 
        !            59:        sub     cx,cx                   / zero out the
        !            60:        mov     bx,cx                   / big register used to
        !            61:        mov     di,cx                   / hold doubles
        !            62:        mov     dx,cx                   / during conversion (dx,di,bx,cx)
        !            63:        mov     fldexp(bp),cx           / clear flags, decexp
        !            64:        mov     binexp(bp),$65+128      / initialise binary exponant
        !            65: 
        !            66:        mov     si,string(bp)           / get string argument.
        !            67: 
        !            68: l0:    lodsb                           / al=character.
        !            69:        cmpb    al,$040                 / is it a space?
        !            70:        je      l0                      / loop on white space
        !            71:        cmpb    al,$011                 / is it a tab?
        !            72:        je      l0                      / loop on white space
        !            73: 
        !            74:        cmpb    al,$'+                  / plus sign ??
        !            75:        je      l1                      / yes, eat it up.
        !            76:        cmpb    al,$'-                  / minus sign ??
        !            77:        jne     l2                      / no, go get number.
        !            78:        incb    flags(bp)               / set "negnum" flag.
        !            79: 
        !            80: l1:    lodsb                           / al=character.
        !            81: 
        !            82: l2:    cmpb    al,$'.                  / decimal point character ??
        !            83:        jne     l3                      / jump if not.
        !            84:        testb   flags(bp),$gotdot       / have we seen a dot ??
        !            85:        jnz     l12                     / yes, quit.
        !            86:        orb     flags(bp),$gotdot       / we have seen one now.
        !            87:        jmp     l1                      / go on.
        !            88: 
        !            89: l3:    subb    al,$'0                  / remove ascii bias.
        !            90:        cmpb    al,$9                   / legal digit ??
        !            91:        ja      l6                      / no (ja makes < '0' look huge)
        !            92:        testb   dh,$0xF8                / do we have 5 bits ??
        !            93:        jz      l4                      / yes.
        !            94:        incb    decexp(bp)              / nope, toss significance.
        !            95:        jmp     l5                      / done with this digit.
        !            96: 
        !            97: l4:    call    shlreg                  / multiply
        !            98:        call    storeg                  / the big
        !            99:        call    shlreg                  / register
        !           100:        call    shlreg                  / by
        !           101:        call    addreg                  / 10 (8+2 = 10).
        !           102:        cbw                             / ax = new digit.
        !           103:        add     cx,ax                   / add into the low word.
        !           104:        call    ripple                  / ripple carries.
        !           105: 
        !           106: l5:    testb   flags(bp),$gotdot       / are we after the "." ??
        !           107:        jz      l1                      / jump if not.
        !           108:        decb    decexp(bp)              / yes, adjust scale.
        !           109:        jmp     l1                      / go get another digit.
        !           110: 
        !           111: l6:    cmpb    al,$'e-'0               / exponant ??
        !           112:        jz      l7                      / yes.
        !           113:        cmpb    al,$'E-'0               / perhaps ??
        !           114:        jnz     l12                     / nope, all done.
        !           115: 
        !           116: l7:    push    dx                      / get a work register.
        !           117:        subb    dh,dh                   / dh=exponant.
        !           118:        lodsb                           / al=character.
        !           119:        cmpb    al,$'+                  / positive ??
        !           120:        je      l8                      / yes, eat it up.
        !           121:        cmpb    al,$'-                  / negative ??
        !           122:        jne     l9                      / nope, its first character.
        !           123:        orb     flags(bp),$negexp       / set flag.
        !           124: 
        !           125: l8:    lodsb                           / al=character.
        !           126: 
        !           127: l9:    subb    al,$'0                  / remove any ascii bias.
        !           128:        cmpb    al,$9                   / legal ??
        !           129:        ja      l10                     / nope, all done.
        !           130:        xchgb   dh,al                   / al=old exponant, dh=digit.
        !           131:        mulb    cs:ten                  / old=10*old.
        !           132:        addb    dh,al                   / exp=10*old+digit
        !           133:        jmp     l8                      / loop until the end of exp.
        !           134: 
        !           135: l10:   testb   flags(bp),$negexp       / was the exponant lt 0 ??
        !           136:        jz      l11                     / nope.
        !           137:        negb    dh                      / fix it up.
        !           138: 
        !           139: l11:   addb    decexp(bp),dh           / fix up decimal exponant.
        !           140:        pop     dx                      / recover work register.
        !           141: 
        !           142: l12:   mov     ax,di                   / quick
        !           143:        or      ax,bx                   / check
        !           144:        or      ax,cx                   / for
        !           145:        or      ax,dx                   / zero.
        !           146:        jnz     l13                     / jump if non zero.
        !           147:        jmp     l25                     / zero is easy.
        !           148: 
        !           149: l13:   movb    al,decexp(bp)           / al=decimal exponant.
        !           150:        orb     al,al                   / check its sign.
        !           151:        jle     l18                     / jump if not multiply scaling.
        !           152: 
        !           153: l14:   call    storeg                  / save big reg in "num".
        !           154:        call    shlreg                  / can it take a * 5 ??
        !           155:        jc      l15                     / nope
        !           156:        call    shlreg                  / well ??
        !           157:        jc      l15                     / nope
        !           158:        call    addreg                  / last try ??
        !           159:        jc      l15                     / nope
        !           160:        inc     binexp(bp)              / yes, 5*2 = 10
        !           161:        jmp     l17                     / go test if all done.
        !           162: 
        !           163: l15:   call    lodreg                  / fetch number.
        !           164:        call    shrreg                  / figure out
        !           165:        call    shrreg                  / 5/4 of the old
        !           166:        call    addreg                  / number.
        !           167:        jnc     l16                     / harumph, overflow.
        !           168:        call    rcrreg                  / easily
        !           169:        inc     binexp(bp)              / repaired, though.
        !           170: 
        !           171: l16:   add     binexp(bp),$3           / 5/4 * 8 = 10
        !           172: 
        !           173: l17:   decb    decexp(bp)              / are we done ??
        !           174:        jnz     l14                     / nope
        !           175:        jmp     l23                     / yup
        !           176: 
        !           177: l18:   jz      l23                     / jump if no scaling
        !           178: 
        !           179: l19:   or      dx,dx                   / first
        !           180:        js      l20                     / we
        !           181:        call    shlreg                  / left
        !           182:        dec     binexp(bp)              / justify the
        !           183:        jmp     l19                     / fraction.
        !           184: 
        !           185: l20:   call    shrreg                  / position number
        !           186:        call    storeg                  / get it in
        !           187:        movb    al,$32                  / al=step counter.
        !           188: 
        !           189: l21:   testb   al,$0x01                / odd iteration ??
        !           190:        jz      l22                     / nope.
        !           191:        call    shrreg                  / yes, 4/5 = 0.110011001100
        !           192:        call    shrreg                  / so do two extra shifts.
        !           193: 
        !           194: l22:   call    shrreg                  / shift over and
        !           195:        add     num+0(bp),cx            / add it
        !           196:        adc     num+2(bp),bx            / into
        !           197:        adc     num+4(bp),di            / the
        !           198:        adc     num+6(bp),dx            / number.
        !           199:        decb    al                      / any more loops ??
        !           200:        jnz     l21                     / yes.
        !           201: 
        !           202:        call    lodreg                  / result in
        !           203:        sub     binexp(bp),$3           / 1/10 = 4/5 * 1/8
        !           204:        incb    decexp(bp)              / done ??
        !           205:        jnz     l19                     / jump if not.
        !           206: 
        !           207: l23:   dec     binexp(bp)              / shift left until
        !           208:        call    shlreg                  / the hidden bit
        !           209:        jnc     l23                     / appears.
        !           210:        addb    ch,$1                   / round just below
        !           211:        call    ripple                  / the last bit we keep.
        !           212:        jnc     l24                     / no carry on rounding.
        !           213:        call    shrreg                  / carry flips hidden bit and
        !           214:        inc     binexp(bp)              / fix exponant.
        !           215: 
        !           216: l24:   movb    al,$8                   / al=step counter.
        !           217: l24a:  call    shrreg                  / slide the number down
        !           218:        decb    al                      / to make room for
        !           219:        jnz     l24a                    / the exponant.
        !           220:        movb    dh,binexp(bp)           / get binary exponant.
        !           221:        rcrb    flags(bp),$1            / sign in c.
        !           222:        call    rcrreg                  / finish up the number.
        !           223: 
        !           224: l25:   mov     _fpac_+6,dx             / store
        !           225:        mov     _fpac_+4,di             / the
        !           226:        mov     _fpac_+2,bx             / big
        !           227:        mov     _fpac_+0,cx             / number
        !           228: 
        !           229:        mov     sp,bp                   / do
        !           230:        pop     bp                      / standard
        !           231:        pop     di                      / c
        !           232:        pop     si                      / function
        !           233:        ret                             / return.
        !           234: 
        !           235: ////////
        !           236: /
        !           237: / ** shrreg -- shift big register right.
        !           238: / ** rcrreg -- shift big register right, using carry.
        !           239: /
        !           240: ////////
        !           241: 
        !           242: shrreg:        shr     dx,$1                   / do first word and
        !           243:        jmp     l30                     / finish up in common code.
        !           244: 
        !           245: rcrreg:        rcr     dx,$1                   / do first word.
        !           246: 
        !           247: l30:   rcr     di,$1                   / shift down the
        !           248:        rcr     bx,$1                   / other three
        !           249:        rcr     cx,$1                   / words and
        !           250:        ret                             / return
        !           251: 
        !           252: ////////
        !           253: /
        !           254: / ** lodreg -- load big register from "num"
        !           255: /
        !           256: ////////
        !           257: 
        !           258: lodreg:        mov     dx,num+6(bp)            / load
        !           259:        mov     di,num+4(bp)            / the
        !           260:        mov     bx,num+2(bp)            / big
        !           261:        mov     cx,num+0(bp)            / register and
        !           262:        ret                             / return
        !           263: 
        !           264: ////////
        !           265: /
        !           266: / ** storeg -- store big register into "num"
        !           267: /
        !           268: ////////
        !           269: 
        !           270: storeg:        mov     num+6(bp),dx            / store
        !           271:        mov     num+4(bp),di            / the
        !           272:        mov     num+2(bp),bx            / big
        !           273:        mov     num+0(bp),cx            / register and
        !           274:        ret                             / return
        !           275: 
        !           276: ////////
        !           277: /
        !           278: / ** addreg -- add "num" to big register.
        !           279: /
        !           280: ////////
        !           281: 
        !           282: addreg:        add     cx,num+0(bp)            / add the
        !           283:        adc     bx,num+2(bp)            / big register to
        !           284:        adc     di,num+4(bp)            / the
        !           285:        adc     dx,num+6(bp)            / number and
        !           286:        ret                             / return
        !           287: 
        !           288: ////////
        !           289: /
        !           290: / ** ripple -- ripple c bit into register
        !           291: /
        !           292: ////////
        !           293: 
        !           294: ripple:        adc     bx,$0                   / ripple 
        !           295:        adc     di,$0                   / carry
        !           296:        adc     dx,$0                   / bits and
        !           297:        ret                             / return
        !           298: 
        !           299: ////////
        !           300: /
        !           301: / ** shlreg -- shift big register left
        !           302: /
        !           303: ////////
        !           304: 
        !           305: shlreg:        shl     cx,$1                   / shift
        !           306:        rcl     bx,$1                   / big
        !           307:        rcl     di,$1                   / register
        !           308:        rcl     dx,$1                   / left and
        !           309:        ret                             / return

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.