fout.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:7k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. TITLE FOUT - Free-format numeric output
  2. ;***
  3. ; FOUT - Free-format numeric output
  4. ;
  5. ; Copyright <C> 1986, Microsoft Corporation
  6. ;
  7. ;Purpose:
  8. ; Floating Point versions of the routines in IFOUT.ASM
  9. ;
  10. ; This file is dragged in by the label B$FloatCONASC
  11. ;
  12. ;
  13. ;******************************************************************************
  14. INCLUDE switch.inc
  15. INCLUDE rmacros.inc ; Runtime Macro Defintions
  16. USESEG _DATA
  17. USESEG _BSS
  18. USESEG _TEXT
  19. USESEG RT_TEXT 
  20. USESEG XIB ; XIB and XIE must bracket XI!
  21. USESEG XI ;initializer segment
  22. USESEG XIE
  23. USESEG INIT_CODE
  24. INCLUDE seg.inc 
  25. INCLUDE baslibma.inc
  26. INCLUDE rtps.inc ; constants shared with QBI
  27. INCLUDE idmac.inc
  28. sBegin _DATA
  29. externW B$AC
  30. externW B$DAC
  31. sEnd _DATA
  32. sBegin _BSS
  33. externB b$SIGN  ; defined in CONASC.ASM
  34. externB b$VTYP ; defined in GWDATA.ASM
  35. sEnd _BSS
  36. assumes CS,RT_TEXT
  37. sBegin RT_TEXT 
  38. externNP B$ASCRND
  39. ;***
  40. ;B$FloatFOUTBX - Free-format numeric output for non-integers
  41. ;
  42. ;Purpose:
  43. ; Format number for printing, using BASIC's formatting rules.
  44. ;
  45. ;Entry:
  46. ; BX = ptr to Number to be formatted
  47. ; [b$VTYP] = VT_R4, VT_R8 or VT_CY
  48. ;
  49. ;Exit:
  50. ; BX = Address of ASCII string, terminated by 00
  51. ; AX = Length of string (not including terminating 00)
  52. ;
  53. ;Uses:
  54. ; Per convention.
  55. ;
  56. ;Exceptions:
  57. ; None.
  58. ;****
  59. PUBLIC B$FloatFOUTBX
  60. cProc B$FloatFOUTBX,<NEAR>,<ES,SI,DI>       
  61. cBegin
  62. PUSH DS
  63. POP ES
  64. MOV AL,[b$VTYP]
  65. AND AX,0FH ;mask I4s to count of bytes to move
  66. MOV SI,BX
  67. MOV DI,OFFSET DGROUP:B$AC ;point to B$AC
  68. CMP AX,4 ;<= 4 byte quantity?
  69. JBE FourByteVar  ;brif so
  70. SUB DI,4 ;use DAC instead of AC
  71. FourByteVar:
  72. XCHG AX,CX
  73. SHR CX,1 ;Count of words
  74. REP MOVSW
  75. CALL B$FloatCONASC ;Most of the work's done here
  76. ;Number has been converted to ASCII and is sitting at buffer pointed to by DI.
  77. ; SI = address of result buffer
  78. ; CX = number of significant figures
  79. ; DL has the base 10 exponent of the right end of the digit string.
  80. MOV BX,7 ; If SP, use 7 digits, but limit 7 to right
  81. CMP [b$VTYP],VT_R8 ; What type?
  82. JB RNDDIG ; If I2 or R4, use R4 parameters
  83. MOV BX,16 ; For R8 or I4, 16 digits, limit 16 to right
  84. RNDDIG:
  85. MOV AL,BL
  86. CALL B$ASCRND ;Round to AL digits
  87. MOV AX,DX ; [AX] = exponent
  88. PUSH DX ; save it also
  89. CWD ; sign extend
  90. XOR AX,DX ; [AX] = ABS(exponent)
  91. SUB AX,DX ; adjust
  92. POP DX ; [DX] = exponent
  93. CMP AX,BX ;Too many digits to right of decimal point?
  94. JG SCINOT ;If so, use scientific notation
  95. MOV AX,DX
  96. ADD AX,CX ; AL=number of digits to left of dec.pt.
  97. CMP AX,BX ; Too many?
  98. JG SCINOT ;If so, use scientific notation
  99. XCHG AX,CX ;CX has digits needed to left of dec. pt.
  100. XCHG AX,BX ;BX has digits available from buffer
  101. OR CX,CX ;Any to left?
  102. JLE LESS1 ;If not, start with decimal point
  103. LEFTDP:
  104. MOVSB ;Move digits to final buffer
  105. DEC BX ;Limit to available digits
  106. LOOPNZ LEFTDP
  107. MOV AL,"0"
  108. REP STOSB ;Fill in with place-holding zeros if needed
  109. JZ PUTEND ;If out of digits, were done(flags from DEC BX)
  110. PUTDP:
  111. MOV AL,"."
  112. STOSB ;Put in decimal point
  113. MOV AL,"0" ;Used only if we came from LESS1
  114. REP STOSB ;Add leading zeros if a small number
  115. MOV CX,BX ;Number of digits left
  116. REP MOVSB
  117. PUTEND:
  118. MOV BX,OFFSET DGROUP:b$SIGN ;Leave pointer to buffer
  119. MOV AX,DI
  120. SUB AX,BX ;Length of string
  121. MOV BYTE PTR[DI],0 ;Put in terminating zero
  122. cEnd
  123. LESS1:
  124. ;Come here if number is less than one and therefore has no digits to
  125. ;left of the decimal point.
  126. NEG CX ;Number of place-holding zeros needed
  127. JMP PUTDP ;   after the decimal point
  128. SCINOT:
  129. MOVSB ;Move first digit to final buffer
  130. DEC CX ;Account for digit already moved
  131. JZ EXP ;Skip decimal point if only one digit
  132. MOV AL,"."
  133. STOSB
  134. ADD DX,CX ; Correct exponent for decimal point position
  135. REP MOVSB ;All other digits go after decimal point
  136. EXP:
  137. MOV AX,"+E"  ;Prepare "E+" if positive exponent
  138. OR DX,DX ; Check exponent sign
  139. JNS POSEXP
  140. NEG DX ; Force exponent positive
  141. MOV AH,"-"
  142. POSEXP:
  143. CMP [b$VTYP],VT_R8 ; Is type double precision?
  144. JNZ SCISNGL
  145. DEC AX ;Convert the "E" to "D"
  146. SCISNGL:
  147. STOSW
  148. MOV AX,DX ; [AX] = exponent
  149. MOV BL,100
  150. DIV BL ; [AL] = hundreds count
  151. OR AL,AL ; See if any
  152. JZ SCISMALL ; jump if not
  153. OR AL,"0" ; turn into hundreds digit
  154. STOSB ; add leading digit
  155. SCISMALL:
  156. XCHG AL,AH ; get remainder here
  157. AAM ;Convert binary to unpacked BCD
  158. XCHG AL,AH
  159. OR AX,"00"  ;Add ASCII bias
  160. STOSW
  161. JMP PUTEND
  162. ;
  163. ; Rewritten and moved here from CONASC.ASM
  164. ;
  165. ;***
  166. ;B$FloatCONASC - Convert number to ASCII
  167. ;
  168. ;Purpose:
  169. ; Convert number to a string of ASCII digits with no leading or
  170. ; trailing zeros. Return base 10 exponent and count of digits.
  171. ; No integer values will be passed to this routine.
  172. ;
  173. ;Entry:
  174. ; B$AC has SP number OR B$DAC has DP or CY number
  175. ;
  176. ;Exit:
  177. ; CX = number of significant figures (decimal point to right)
  178. ; DL = base 10 exponent
  179. ; SI = Address of first digit (non-zero unless number is zero)
  180. ; [b$SIGN] has sign - blank if positive, "-" if negative
  181. ;
  182. ;Uses:
  183. ; Uses all.
  184. ;****
  185. cProc B$FloatCONASC,<NEAR,PUBLIC>
  186. cBegin
  187. MOV SI,OFFSET DGROUP:B$DAC ;address of location to put final R8
  188. CMP b$VTYP,VT_R8 ;Is it an R8
  189. JE CONASC2  ;brif so, we are ready to convert
  190. GOT_R4: 
  191. DbAssertRelB  b$VTYP,E,VT_R4,RT_TEXT,<Unknown value for b$VTYP in CONASC>
  192. MOV BX,OFFSET DGROUP:B$AC ;point to AC for R4s
  193. fld dword ptr [bx] ;Load the R4
  194. fstp qword ptr [si] ;And store it as an R8
  195. FWAIT ;ensure stored
  196. CONASC2:
  197. Call   FAR PTR B$I8_OUTPUTHack ;math coversion from R8 to ascii string
  198. ; At this point $i8_output returns the following conditions
  199. ; DS:SI - pointer to converted string (first byte is length)
  200. ; AX - 1 if number was ok, 0 if indefinite
  201. ; BL - sign character: either ' ' or '-'
  202. ; DX - base 10 exponent (left of digits)
  203. ; CX,BH - smashed
  204. CONASC3:
  205. MOV b$SIGN,BL ;save sign char
  206. LODSB ;AL = length of strings
  207. CBW
  208. CMP AX,1 ;See if single digit
  209. JNZ ModExp ;If not, go modify exponent
  210. CMP BYTE PTR [SI],"0" ;Else see if number is zero
  211. JZ NoModExp ;If so, leave exponent alone
  212. ModExp:
  213. SUB DX,AX ;DX = base 10 exponent (right of digits)
  214. NoModExp:
  215. XCHG AX,CX ;return num digits in CX
  216. cEnd
  217. sEnd RT_TEXT
  218. assumes CS,_TEXT
  219. sBegin _TEXT
  220. externNP $i8_output ;math pack string conversion
  221. ;***
  222. ;B$I8_OUTPUTHack  - Hack to call B$I8_OUTPUT near from _TEXT.
  223. ;
  224. ;Purpose:
  225. ; Hack to call B$I8_OUTPUT near from _TEXT.
  226. ; Convert number to a string of ASCII digits.
  227. ;
  228. ;Entry:
  229. ; DS:SI - ptr to 8 byte double precision number.
  230. ;
  231. ;Exit:
  232. ; DS:SI - pointer to converted string (first byte is length)
  233. ; AX - 1 if number was ok, 0 if indefinite
  234. ; BL - sign character: either ' ' or '-'
  235. ; DX - base 10 exponent
  236. ; CX,BH - smashed
  237. ;
  238. ;Uses:
  239. ; Uses all but BP,DI.
  240. ;****
  241. cProc B$I8_OUTPUTHack,<FAR>,<BP,DI>
  242. cBegin
  243. cCall $i8_output ;math coversion from R8 to ascii string
  244. ; At this point $i8_output returns the following conditions
  245. ; DS:SI - pointer to converted string (first byte is length)
  246. ; AX - 1 if number was ok, 0 if indefinite
  247. ; BL - sign character: either ' ' or '-'
  248. ; DX - base 10 exponent
  249. ; DI,CX,BH - smashed
  250. cEnd
  251. sEnd _TEXT
  252. END