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

操作系统开发

开发平台:

Visual C++

  1. page 49,132
  2. TITLE exfor - FOR/NEXT executors
  3. ;***
  4. ;exfor - FOR/NEXT executors
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; This module contains all executors for FOR and NEXT.
  10. ;
  11. ; In general, these executors are very speed critical.
  12. ;
  13. ; FOR executors are:
  14. ;
  15. ; exStFor<Step|><I2|I4|R4|R8|CY>
  16. ;
  17. ; <Step|> - indicates whether there is a STEP clause.  This variant has
  18. ;   one more argument then other variants.
  19. ;
  20. ; <type> - FOR receives stack arguments of a specific type
  21. ;
  22. ; NEXT executors are:
  23. ;
  24. ; exStNext<Step|><Id|><type>
  25. ;
  26. ; <Step|> - NEXT in the case that no STEP clause was found can be made
  27. ;   faster, as the STEP need not be loaded, and no checking is
  28. ;   necessary for the STEP sign.
  29. ;
  30. ; <Id|> - This variation is for listability.  Due to memory movement,
  31. ; it is always necessary to execute a exIdRf before the NEXT.
  32. ; The lister can't tell whether to list this op without help.
  33. ; This is a usability issue.  The variants without Id are made
  34. ; to share code with Id variants to conserve size.
  35. ;
  36. ; <type> - NEXT is specific by type.  R8 data type FOR/NEXT are less
  37. ;  speed critical than other types.  Size considerations require
  38. ;  that R8 NEXT variants share code.
  39. ;
  40. ;
  41. ;****************************************************************************
  42. .8087
  43. .xlist
  44. include  version.inc
  45. EXFOR_ASM = ON
  46. IncludeOnce context
  47. IncludeOnce executor
  48. IncludeOnce exint
  49. IncludeOnce opcontrl
  50. IncludeOnce rtinterp
  51. IncludeOnce variable
  52. .list
  53. extrn B$CMI4:far
  54. GetpFrame   MACRO ;Re-defining macro in exint.inc
  55. xchg bx,ax ;;Get oBP to bx
  56. add bx,bp
  57. ENDM
  58. assumes cs, CODE
  59. assumes es, NOTHING
  60. assumes ss, DATA
  61. sBegin CODE
  62. subttl FOR I2 Variants
  63. page
  64. MakeExe exStForI2,opStFor
  65. LODSWTX  ;Pick up offset to FOR block
  66. GetpFrame
  67. pop cx
  68. mov [pFrame],cx  ;Limit to FOR block
  69. pop ax ;Initial value for variable
  70. pop bx ;Address of variable value
  71. mov si,PTRTX[si] ;Text branch to the operand of NEXT
  72. jmp StNextForI2 ;FOR entry in matching NEXT executor
  73. MakeExe exStForStepI2,opStForStep
  74. LODSWTX  ;Pick up offset to FOR block
  75. GetpFrame
  76. pop cx ;Step
  77. mov [pFrame],cx  ;Step to FOR block
  78. pop ax ;Limit
  79. mov [pFrame+2],ax ;Limit to FOR block
  80. pop dx ;Initial value
  81. pop bx ;Address of index variable value
  82. mov [bx],dx  ;Assign initial value to variable
  83. mov si,PTRTX[si] ;Branch to the NEXT operand
  84. jmp StNextStepForI2  ;FOR entry in matching NEXT executor
  85. subttl FOR I4 Variants
  86. page
  87. MakeExe exStForI4,opStFor
  88. xor ax,ax ;Supply the STEP for the user
  89. push ax
  90. inc ax
  91. push ax ; push an (I4)1 and use the same NEXT
  92. SkipExHeader
  93. MakeExe exStForStepI4,opStForStep
  94. LODSWTX  ;Pick up offset to FOR block
  95. GetpFrame
  96. pop [pFrame] ;Step second word
  97. pop [pFrame+2] ;Step first word
  98. pop [pFrame+4] ;Limit second word
  99. pop [pFrame+6] ;Limit first word
  100. pop cx ;Initial value second word
  101. pop dx ;Init value first word
  102. xchg ax,FrameReg ;ax = FOR block address
  103. pop bx ;pVar
  104. mov si,PTRTX[si] ;Branch to the NEXT operand
  105. jmp StNextForI4 ;Exit through NEXT code
  106. ;ax    = FOR block address
  107. ;ds:bx = var address
  108. ;dx/cx = initial value
  109. subttl FOR R4 Variants
  110. page
  111. ;NonSTEP variants
  112. MakeExe exStForR4,opStFor
  113. fld1 ;NonSTEP variants push a 1 for STEP
  114. SkipExHeader
  115. ;Step variants
  116. MakeExe exStForStepR4,opStForStep
  117. LODSWTX  ;Pick up offset to FOR block
  118. GetpFrame
  119. fstp dword ptr [pFrame] ;Get step
  120. fstp dword ptr [pFrame+4] ;Get limit
  121. xchg ax,FrameReg ;ax = FOR block address
  122. mov si,PTRTX[si] ;Skip to NEXT
  123. pop bx ;pVar
  124. jmp StForNextR4 ;Exit through NEXT with
  125. ;  pFrame = FOR block address
  126. ;  bx = variable
  127. subttl FOR R8 Variants
  128. page
  129. MakeExe exStForR8,opStFor
  130. ;R8 without step is fast enough and smaller if FOR simply supplies the step
  131. fld1
  132. SkipExHeader
  133. MakeExe exStForStepR8,opStForStep
  134. LODSWTX  ;Pick up offset to FOR block
  135. GetpFrame
  136. fstp qword ptr [pFrame] ;Get step
  137. fstp qword ptr [pFrame+8] ;Get limit
  138. xchg ax,FrameReg ;ax = FOR block address
  139. mov si,PTRTX[si] ;Skip to NEXT
  140. pop bx ;Variable address
  141. jmp StForNextR8 ;Exit through NEXT with
  142. ;  pFrame or ax = FOR block address
  143. ;  bx = variable
  144. subttl FOR CY Variants
  145. page
  146. subttl NEXT I2 Variants Without STEP
  147. page
  148. MakeExe exStNextI2,opStNext
  149. SkipExHeader
  150. MakeExe exStNextIdI2,opStNextId
  151. LODSWTX  ;Pick up oBp of parameters
  152. GetpFrame
  153. mov cx,[pFrame]  ;Pick up Limit
  154. pop bx ;Var ref
  155. mov ax,[bx]  ;Load index value
  156. inc ax ;Perform the step
  157. jo NextI2OverflowErr ;Error - overflow
  158. StNextForI2: ;FOR entry in matching NEXT executor
  159. mov [bx],ax  ;Store in variable
  160. cmp ax,cx ;Test var against limit
  161. jg ExitLoop ;Loop end conditions met
  162. NextCont:
  163. mov si,PTRTX[si] ;Branch to beyond FOR
  164. DispMac  ;And on with the show
  165. ExitLoop:
  166. inc si ;Skip operand
  167. inc si
  168. DispMac  ; and go
  169. NextI2OverflowErr:
  170. jmp exMathErrOVF
  171. subttl NEXT I2 Variants With STEP
  172. page
  173. StepDown:
  174. cmp [bx],ax  ;Test var against limit
  175. jge NextCont ;Take another lap
  176. jmp short ExitLoop ;Skip operand and continue
  177. MakeExe exStNextStepI2,opStNext
  178. SkipExHeader
  179. MakeExe exStNextIdStepI2,opStNextId
  180. LODSWTX  ;Pick up oBp of parameters
  181. GetpFrame
  182. mov cx,[pFrame]  ;Pick up step
  183. mov ax,[pFrame+2] ;Pick up Limit
  184. pop bx ;Var ref
  185. add [bx],cx  ;Add step to variable
  186. NextI2OverflowErrJ:
  187. jo NextI2OverflowErr ;Error - overflow
  188. StNextStepForI2: ;FOR continuation
  189. or cx,cx ;Test sign of step
  190. js StepDown ;Negative step
  191. cmp [bx],ax  ;Test var against limit
  192. jg ExitLoop ;Loop end conditions met
  193. mov si,PTRTX[si] ;Branch to beyond FOR
  194. DispMac  ;And on with the show
  195. subttl Next I4 Variants
  196. page
  197. MakeExe exStNextStepI4,opStNext
  198. SkipExHeader ;Extra op for listability
  199. MakeExe exStNextIdStepI4,opStNextId
  200. LODSWTX  ;Pick up oBp of parameters
  201. GetpFrame
  202. mov cx,[pFrame]
  203. mov dx,[pFrame+2] ;dx/ax = step
  204. xchg ax,FrameReg ;ax = FOR block address
  205. pop bx ;Var ref
  206. ;Add in step - error if overflow.
  207. add cx,[bx]  ;Add in low word of value
  208. adc dx,[bx+2] ;Add in high word of value + PSW.C
  209. jo NextI2OverflowErrJ ;Error if overflow
  210. ;Entry for FOR code.
  211. ;dx/cx = index value
  212. ;ds:bx = pVar
  213. ;ax    = pFOR block
  214. StNextForI4:
  215. ;Perform assignment to variable
  216. mov [bx+2],dx
  217. mov [bx],cx  ;Assignment complete
  218. ;Compare var to limit.
  219. push dx
  220. push cx ;Push current value
  221. xchg FrameReg,ax ;Restore FOR block address
  222. push [pFrame+6]
  223. push [pFrame+4] ;Push limit
  224. call B$CMI4 ; Compare two I4s on the stack
  225.     lahf ;Put flags in AH
  226. test byte ptr [pFrame+3],80H ;Test sign of step
  227. jnz NextNegStepI4 ;Negative step
  228. sahf
  229. ja NextLeave ;Leave loop if index > limit
  230. jmp short NextContI4R4R8 ;Exit through shared code
  231. NextNegStepI4:
  232. sahf
  233. jb NextLeave ;Leave loop if index < limit
  234. jmp short NextContI4R4R8
  235. subttl NEXT R4 Variants
  236. page
  237. ;There are no nonSTEP versions of R4 NEXT as FOR simply supplies the STEP
  238. ; when the user doesn't.
  239. MakeExe exStNextStepR4,opStNext
  240. SkipExHeader
  241. MakeExe exStNextIdStepR4,opStNextId
  242. LODSWTX  ;Pick up oBp of parameters
  243. GetpFrame
  244. pop ax ;Address of variable
  245. ;Need to:
  246. ; 1. add STEP to the variable whose address is in ax
  247. ; 2. compare LIMIT to variable whose value is on the stack.
  248. ; 3. compare sign of step with this previous compare to get the
  249. ;    final disposition.
  250. ;Add STEP.
  251. ;   The mathpack entry point does not modify the variable in the case
  252. ;   that an error (such as overflow or underflow) is detected.
  253. ;   ax     = index variable address
  254. ;   pFrame = FOR block address
  255. fld dword ptr [pFrame] ;Load the step
  256. xchg ax,bx ;bx points to variable
  257. fadd dword ptr [bx] ;Add variable to step
  258. DbPub StForNextR4
  259. StForNextR4: ;Entry from R4 FOR executors
  260. ;Compare index variable with limit
  261. ;   bx = index variable address
  262. ;   ax or pFrame = FOR block address
  263. fst dword ptr [bx] ; and store in variable
  264. xchg ax,FrameReg
  265. fld dword ptr [pFrame+4] ;Load the limit
  266. fcompp ;Compare to the variable
  267. fstsw DGROUP:stat ;fstsw ax is 80287 only
  268. fwait
  269. mov ax,DGROUP:stat  ;Put status word in ax
  270. .errnz LOW MATH_R4SignMask
  271. test byte ptr[pFrame+3],HIGH MATH_R4SignMask ;Test for Sign of step
  272. NextComR4R8X:
  273. jnz NextNegStep ;Negative step
  274. sahf
  275. jb NextLeave ;Leave loop if si > di
  276. NextContI4R4R8:
  277. mov si,PTRTX[si] ;Continue loop
  278. DispMac
  279. NextLeave:
  280. inc si ;Skip oTxt field
  281. inc si
  282. DispMac  ; and continue
  283. NextNegStep:
  284. sahf
  285. ja NextLeave ;Leave loop
  286. jmp short NextContI4R4R8
  287. sEnd CODE
  288. sBegin DATA
  289. public Stat
  290. Stat dw (?)
  291. sEnd DATA
  292. sBegin CODE
  293. subttl EXIT FOR
  294. page
  295. ;exStExitFor and exStExitDo are simply a GOTO at execution time.
  296. MakeExe exStExitDo,opStExitDo
  297. SkipExHeader
  298. MakeExe exStExitFor,opStExitFor
  299. jmp short NextContI4R4R8 ;Branch to the exit point
  300. ; like a NEXT loop continuation
  301. subttl NEXT R8 Variants
  302. page
  303. ;There are no nonSTEP versions of R8 NEXT as FOR simply supplies the STEP
  304. ; when the user doesn't.
  305. MakeExe exStNextStepR8,opStNext
  306. SkipExHeader
  307. MakeExe exStNextIdStepR8,opStNextId
  308. LODSWTX  ;Pick up oBp of parameters
  309. GetpFrame
  310. pop ax ;Address of variable
  311. ;Need to:
  312. ; 1. add STEP to the variable whose address is in ax.
  313. ; 2. compare LIMIT to variable whose value is on the stack.
  314. ; 3. compare sign of step with this previous compare to get the
  315. ;    final disposition.
  316. ;Add STEP.
  317. ;   The mathpack entry point does not modify the variable in the case
  318. ;   that an error (such as overflow or underflow) is detected.
  319. ;
  320. ;   ax     = index variable address
  321. ;   pFrame = FOR block address
  322. fld qword ptr [pFrame] ;Load the step
  323. xchg ax,bx ;bx points to variable
  324. fadd qword ptr [bx] ;Add variable to step
  325. StForNextR8: ;Entry from R8 FOR executors
  326. ;Compare index variable with limit
  327. ;   bx = index variable address
  328. ;   ax or pFrame = FOR block address
  329. fst qword ptr [bx] ;Store in variable
  330. xchg ax,FrameReg
  331. fld qword ptr [pFrame+8] ;Load the limit
  332. fcompp ;Compare to the variable
  333. fstsw stat ;fstsw ax is 80287 only
  334. fwait
  335. mov ax,stat  ;Put status word in ax
  336. .errnz LOW MATH_R8SignMask
  337. test byte ptr[pFrame+7],HIGH MATH_R8SignMask ;Test for Sign of step check
  338. jmp NextComR4R8X
  339. subttl NEXT CY Variants
  340. page
  341. ;There are no nonSTEP versions of CY NEXT as FOR simply supplies the STEP
  342. ; when the user doesn't.
  343. sEnd
  344. end