|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.