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

操作系统开发

开发平台:

Visual C++

  1. page 49,132
  2. TITLE ssif - scan support for IF related opcodes
  3. ;***
  4. ;ssif.asm
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ; Scan IF statement opcodes.
  10. ;
  11. ;   Runtime behavior of IF-THEN-ELSE opcodes:
  12. ;   ----------------------------------------
  13. ;      <exp> opStIf(oText)      - branch to oText if exp is zero (false)
  14. ;      <exp> opStIfLab(label)      - branch to label if exp is non-zero (true)
  15. ;      <exp> opStIfLabDirect(label) - branch to label if exp is non-zero (true)
  16. ;      opStElse(oText)      - unconditionally branch to oText
  17. ;      opStElseLab(label)      - unconditionally branch to label
  18. ;      opStElseLabDirect(label)     - unconditionally branch to label
  19. ;      opStElseNop      - nop
  20. ;      <exp> opStIfBlock(oText)     - branch to oText if exp is zero (false)
  21. ;      <exp> opStElseIf(oText)      - branch to oText if exp is zero (false)
  22. ;      opStEndIfBlock      - nop
  23. ;
  24. ;   NOTE: When in direct mode, Parser emits opStIfLabDirect instead of
  25. ;         opStIfLab, and opStElseLabDirect instead of opStElseLab.
  26. ;
  27. ;   Single line IF statement syntax to pcode mappings:
  28. ;   -------------------------------------------------
  29. ;
  30. ;      Syntax:  IF <exp> GOTO <label>
  31. ;   
  32. ;      Pcode:   <exp> opStIfLab(label)
  33. ;
  34. ;      ============================================================
  35. ;      Syntax:  IF <exp> THEN <stmt list>
  36. ;   
  37. ;                            +--------------+
  38. ;      Pcode:   <exp> opStIf(|) <stmt list> | opBol
  39. ;   
  40. ;      ============================================================
  41. ;      Syntax:  IF <exp> THEN <label> ELSE <label>
  42. ;   
  43. ;      Pcode:   <exp> opStIfLab(label) opStElseNop opStElseLab(label)
  44. ;
  45. ;      ============================================================
  46. ;      Syntax:  IF <exp> THEN <label> ELSE <stmt list>
  47. ;   
  48. ;      Pcode:   <exp> opStIfLab(label) opStElseNop <stmt list>
  49. ;
  50. ;      NOTE:    <stmt list> can contain more single line IF stmts
  51. ;   
  52. ;      ============================================================
  53. ;      Syntax:  IF <exp> THEN <stmt list> ELSE <label>
  54. ;   
  55. ;                            +-------------------------+
  56. ;      Pcode:   <exp> opStIf(|) <stmt list> opStElse(|)|opStElseLab(label)|opBol
  57. ;                                                    +--------------------+
  58. ;
  59. ;      ============================================================
  60. ;      Syntax:  IF <exp> THEN <stmt list> ELSE <stmt list>
  61. ;   
  62. ;                            +--------------------------+
  63. ;      Pcode:   <exp> opStIf(|) <stmt list> opStElse(|) | <stmt list> | opBol
  64. ;                                                    +----------------+
  65. ;   
  66. ;   Block IF statement syntax to pcode mappings:
  67. ;   -------------------------------------------
  68. ;      Syntax:  IF <exp> THEN
  69. ;   
  70. ;      Pcode: <exp> opStIfBlock(oText to <exp> before ELSEIF, or oText
  71. ;       beyond ELSE/END IF opcode)
  72. ;   
  73. ;      ============================================================
  74. ;      Syntax:  ELSEIF <exp> THEN
  75. ;   
  76. ;      Pcode:   opBol <exp> opStElseIf(oTx beyond ELSEIF/ELSE/END IF)
  77. ;
  78. ;        +- to beyond END IF
  79. ;      Bound:   opBol exBranch(|) <exp> opStElseIf(oTx past ELSEIF/ELSE/END IF) 
  80. ;
  81. ;      NOTE:    Scanner inserts exBranch(oText to beyond END IF opcode)
  82. ;               after the opBol and before <exp>, so code falling into the
  83. ;               ELSEIF will branch beyond END IF without evaluating <exp>.
  84. ;   
  85. ;      ============================================================
  86. ;      Syntax:  ELSE 
  87. ;   
  88. ;      Pcode:   opStElse(oText to beyond END IF opcode)
  89. ;   
  90. ;      ============================================================
  91. ;      Syntax:  END IF
  92. ;   
  93. ;      Pcode:   opStEndIfBlock
  94. ;   
  95. ; The scan routines within this module depend on the BOL scan routine
  96. ; to bind unbound line IF and ELSE operands.  The BOL scan routine
  97. ; binds all IF/ELSE frame entries until it discovers a Block IF/ELSE
  98. ; entry, some other control structure frame that can't be bound, or
  99. ; the bottom of the stack.
  100. ;
  101. ; For speed, the IF and ELSE scan routines set a flag to let BOL know
  102. ; that a line version of IF or ELSE has been pushed.  The flag is
  103. ; cleared by BOL after binding all line IF and ELSE entries.
  104. ;
  105. ; The IF and ELSE scan routines will not push a Block frame on the stack 
  106. ; when there is a Line frame already on the stack.
  107. ;
  108. ;
  109. ;****************************************************************************
  110. .xlist
  111. include version.inc
  112. SSIF_ASM = ON
  113. IncludeOnce qbimsgs
  114. IncludeOnce opmin
  115. IncludeOnce ssint
  116. IncludeOnce variable
  117. .list
  118. assumes ds, DATA
  119. assumes es, NOTHING
  120. assumes ss, DATA
  121. assumes cs, SCAN
  122. sBegin SCAN
  123. subttl Static data area definitons.
  124. page
  125. ;***
  126. ;Ss_If, Ss_IfBlock
  127. ;Purpose:
  128. ; Scan entries for IF.
  129. ;
  130. ; Scan tasks for IF include:
  131. ; - ensuring the entry type is a fundamental, non string data type.
  132. ; - selecting the IF executor varient for the argument data type.
  133. ; - binding the label of opStIfLab<Direct|>
  134. ; - pushing an IF frame on the scan stack as follows:
  135. ; push  UNDEFINED for start of block IF exBranch chain
  136. ; push  oTx of IF operand
  137. ; push  IF frame label (identifying Standard, Block, or Label IF)
  138. ;
  139. ;Input:
  140. ; Standard scan entrypoint
  141. ;Output:
  142. ; Standard scan exit
  143. ;***************************************************************************
  144. SsProc IfLab
  145. mov dx,STYP_IfLab ;Type of stack entry for IF w/ a label
  146. jmp short SsIfCom
  147. SsProc IfBlock
  148. mov dx,STYP_IfBlock ;Type of stack entry for block IF
  149. jmp short SsIfCom ;Common IF code
  150. SsProc If
  151. mov dx,STYP_IF ;Push an IF entry on the stack
  152. SsIfCom:
  153. or SsFlags,SSF_If ;Set end of line IF handling flag
  154. pop ax ;Get type of last expression
  155. pop cx ;Remove expression address
  156. cCall MapOpToExeNumeric ;Type explode the executor
  157. STOSWTX ;Emit the executor
  158. PUSHI ax,UNDEFINED ;Push end of Block IF ExBranch chain
  159. push di ;Push operand address
  160. push dx ;Push frame type
  161. test dx,STYP_Lab ;Is this an IF w/ a label 
  162. jnz SsIfLab  ;Brif yes
  163. MOVSWTX ;Skip the operand in source and dest.
  164. SsIfComX:
  165. mov bx,sp
  166. sub bx,2
  167. mov [SsBosStack],bx  ; Reset BOS SP mark for 1 Line If
  168. mov [SsOTxStart],di  ; Reset DOS oTx mark for 1 Line If
  169. jmp [ScanRet]
  170. SsIfLab:
  171. mov ax,PTRTX[si+2]
  172. sub ax,opBos ; Is this an opBos?
  173. jz @F ; Brif yes
  174. dec ax ; Is this an opBosSp
  175. jne ElsePresent ; Brif yes. Works ok!
  176. @@:
  177. push [ScanRet] ; Save exit address
  178. mov [ScanRet],scanOFFSET BindIfLab ; We need to clean up
  179. ElsePresent:
  180. ;Bind the label for this If
  181. mov cx,1 ;need to bind 1 label
  182. jmp LabelBindCur ;Bind label to current scope and return to
  183. ;to main scan loop
  184. BindIfLab:
  185. pop [ScanRet] ; Restore loop address
  186. mov bx,di ; Insert at current location
  187. call InsertBranch ; Insert exBranch.  CY set if error.
  188. jc SsIfComX ; Brif error
  189. mov bx,sp ; Get stack frame pointer
  190. lea ax,[di-2] ; oTx of exBranch operand
  191. mov [bx].FIF_Id,STYP_Else ; Allow BOL update
  192. mov [bx].FIF_oTx,ax  ; Update in frame
  193. jmp SsIfComX ; Exit
  194. ;***
  195. ;Ss_Else,Ss_ElseNop
  196. ;Purpose
  197. ; Scan ELSE varients.
  198. ;
  199. ; opElseLab<|Direct> requires label binding only.  These are always
  200. ; immediately preceeded by an opStElseNop or opStElse.  Therefore,
  201. ; opElseLab<|Direct> does not need to examine or push a stack entry.
  202. ; So, opElseLab<|Direct> are scanned as label reference opcodes like
  203. ; GOTO.
  204. ;
  205. ; Scan tasks for other Else variants are:
  206. ; - emit executor
  207. ; - walk stack frames to find first non-Else/non-ElseNop frame
  208. ; - check for if frame, check errors:
  209. ;   + IF nesting error if frame is not an IF
  210. ; - change IF stack frame to ELSE stack frame
  211. ;   + frame type is Block if IF was a Block type
  212. ;   + set ELSE variant frame type
  213. ;   + opStElseNop just changes frame to Set STYP_Lab bit -
  214. ;     it requires no further binding.
  215. ;   + leave address of exBranch chain, will be bound at ENDIF time
  216. ;   + set address of ELSE operand
  217. ; - bind IF to address of ELSE if it was not a label varient of IF
  218. ;
  219. ; Scan tasks for ELSEIF are:
  220. ; - ensure the entry type is a fundamental, non string data type.
  221. ; - select and emit the ELSEIF executor varient for the argument 
  222. ;   data type.
  223. ; - insert an exBranch at BOS for exit from IF clause.
  224. ; - check for an IF frame, check errors:
  225. ;   + IF nesting error if top frame is not an IF
  226. ;   + BLOCK IF error if IF is not a BLOCK IF.
  227. ; - insert new exBranch into chain
  228. ; - change Block IF frame to an ELSEIF frame on the scan stack as follows:
  229. ; set  new start of exBranch chain
  230. ; set  oTx of ELSEIF operand
  231. ; leave IF frame id so next ELSEIF sees a BLOCK IF entry
  232. ;
  233. ;Input:
  234. ; Standard scanner convention
  235. ;Output:
  236. ; Standard scanner convention
  237. ;***************************************************************************
  238. SsProc ElseIf
  239. pop ax ;Get type of last expression
  240. pop dx ;Remove expression address
  241. cCall MapOpToExeNumeric ;Type explode the executor
  242. ; ax = executor
  243. STOSWTX ;Emit it
  244. mov bx,sp ;point to stack frame
  245. mov cx,[bx.FIF_oTxBranch] ;get next entry in ExBranch chain
  246. call InsertBranchBos  ;insert exBranch after opBos
  247. ;bx = oTx after exBranch operand
  248. jc ElseIfScopeError ;Quit if OME
  249. xchg ax,bx ;ax = oTx after exBranch operand
  250. mov bx,sp ;point to stack frame
  251. cmp [bx.FIF_Id],STYP_IfBlock ;ELSEIF must match block IF
  252. jnz ElseIfScopeError ;brif nesting error
  253. dec ax
  254. dec ax ;point to exBranch operand
  255. mov [bx.FIF_oTxBranch],ax ;set next link in exBranch chain
  256. mov cx,[bx.FIF_oTx]  ;get if operand address
  257. mov [bx.FIF_oTx],di  ;set addr of else operand
  258. xchg ax,bx ;bx = ptr to txt
  259. MOVSWTX  ;skip operand in source and destination
  260. inc bx
  261. inc bx ;move past exBranch operand
  262. xchg bx,cx ;bx = ptr to if operand, cx points past
  263. ;inserted exbranch
  264. mov PTRTX[bx],cx ;Bind if to ElseIf expression
  265. SsElseIfX:
  266. jmp short SsIfComX
  267. ;Error processing for Else opcodes.
  268. ElseIfScopeError:
  269. mov cx,STYP_Else ;push an ELSE frame for ELSEIF error
  270. ElseScopeError:
  271. mov ax,MSG_ElseWI ;ELSE without IF error
  272. call SsError
  273. cmp cx,STYP_ElseNop  ;is this ElseNop?
  274. jz SsElseIfX ;brif ElseNop - don't push a frame
  275. PushI ax,UNDEFINED ;Flag no exbranch chain
  276. push di ;push else operand location
  277. push cx ;push else frame
  278. MOVSWTX  ;skip operand in source and dest
  279. or [SsFlags],SSF_IF ;need BOS If processing to remove frame
  280. ElseScopeErrX:
  281. jmp short SsElseIfX  ;continue scanning
  282. SsProc ElseNop
  283. mov cx,STYP_ElseNop  ;Signal no stack entry
  284. jmp short SsElseCom
  285. SsProc Else
  286. mov cx,STYP_Else ;Prepare to build ELSE frame
  287. SsElseCom:
  288. STOSWTX ; and emit it
  289. mov bx,sp ;set up Frame addressablity
  290. sub bx,SIZE FIF ;Adjust for following add
  291. ; Skip all nested single line else's currently on scan stack. Walk
  292. ; back to first non-single else frame. If this frame is not an IF/ELSEIF
  293. ; frame, then we have a scoping error. Multiple Single else frames can
  294. ; be on the stack if a nested single if occurs in a single line else clause.
  295. SkipSingleElseLoop:
  296. add bx,SIZE FIF ;point to next stack frame
  297. mov ax,[bx.FIF_Id] ;ax = frame type
  298. cmp ax,STYP_Else ;is this a single line else frame?
  299. jz SkipSingleElseLoop ;brif so, examine next frame
  300. cmp ax,STYP_ElseNop  ;is this a frame left from an if <lab>?
  301. jz SkipSingleElseLoop ;brif so, examine next frame
  302. ; bx - points to first non-single else stack frame.
  303. ; ax - frame type of stack frame
  304. ; cx - else variant we are processing
  305. test ax,STYP_If or STYP_Block
  306. jz ElseScopeError ;Not an IF on the stack - scoping error.
  307. mov dx,[bx.FIF_oTx]  ;dx = oTx of preceding if operand
  308. test ax,STYP_Block ;is frame for BLOCK IF variant?
  309. jz NotBlockElse ;brif not - single line variant
  310. or cx,STYP_Block ;make this a block else
  311. NotBlockElse:
  312. DbAssertRel cx,nz,<STYP_IfBlock OR STYP_Lab>,SCAN,<Ss_ElseNop:saw opElseNop after BLOCK IF>
  313. or SsFlags,SSF_IF ;we may need BOL If processing
  314. mov [bx.FIF_Id],cx ;set frame as processed
  315. test cx,STYP_Lab ;is this ElseNop?
  316. jnz SsElseX  ;brif so, no binding needed
  317. mov [bx.FIF_oTx],di  ;emit else op location for else binding
  318. MOVSWTX  ;skip operand in source and dest
  319. mov bx,dx ;bx = If operand location
  320. mov PTRTX[bx],di ;bind previous IF/ELSEIF to ELSE
  321. SsElseX:
  322. jmp SsIfComX
  323. EndIfScopeError:
  324. push ax ;Restore stack state
  325. mov ax,MSG_EWI ;ENDIF without block IF
  326. call SsError
  327. jmp short EndifX
  328. SsProc EndIf
  329. STOSWTX  ; and emit it
  330. pop ax
  331. test ax,STYP_Block ;Is it a Block type frame entry
  332. jz EndIfScopeError ;Not a block IF or ELSE
  333. pop bx ;Pop stack frame
  334. mov PTRTX[bx],di ;Bind block IF or ELSE to this location
  335. pop bx ;get ptr to start of exBranch chain
  336. call BindExitCur ;call common EXIT chain binder
  337. EndifX:
  338. jmp [ScanRet] ; and continue
  339. ;MapOpToExeNumeric
  340. ;Purpose:
  341. ; Type explode to executor for this opcode.
  342. ;
  343. ; This routine works for full type explosion for numeric
  344. ; data types only
  345. ;Input: 
  346. ; ax = type from stack entry
  347. ; bx = opcode * 2
  348. ;Output:
  349. ;       ax = executor
  350. ;Preserves:
  351. ; cx,dx
  352. public MapOpToExeNumeric
  353. MapOpToExeNumeric:
  354. mov bx,mpOpExe[bx] ;Load the exe map address
  355. .erre ST_Typ_Mask EQ 0ffh ; Assure CBW is sufficient
  356. cbw ; Clear flags in scan stack
  357. .erre ET_RC EQ 0 ; Assure that DEC is sufficient
  358. dec ax ; ET_RC -> 0FFFFh
  359. cmp al,ET_MaxNum ; Detect user defined type
  360. jb MapType  ;SD and record version not in language
  361. call TMError 
  362. .erre ET_I2 EQ 1 ; Assure XOR is sufficient
  363. xor ax,ax ; Use I2 executor
  364. MapType:
  365. add bx,ax
  366. add bx,ax ;Index to executor for this type
  367. mov ax,word ptr cs:[bx] ; Load executor, zero relative
  368. ret
  369. subttl Opcode to executor maps for IF
  370. page
  371. public mStIfBlockOpExe
  372. mStIfBlockOpExe:
  373. DWEXT exStIfBlockI2
  374. DWEXT exStIfBlockI4
  375. DWEXT exStIfBlockR8
  376. DWEXT exStIfBlockR8
  377. public mStIfLabDirectOpExe
  378. mStIfLabDirectOpExe:
  379. DWEXT exStIfLabDirectI2
  380. DWEXT exStIfLabDirectI4
  381. DWEXT exStIfLabDirectR8
  382. DWEXT exStIfLabDirectR8
  383. public mStIfOpExe
  384. mStIfOpExe:
  385. DWEXT exStIfI2
  386. DWEXT exStIfI4
  387. DWEXT exStIfR8
  388. DWEXT exStIfR8
  389. public mStIfLabOpExe
  390. mStIfLabOpExe:
  391. DWEXT exStIfLabI2
  392. DWEXT exStIfLabI4
  393. DWEXT exStIfLabR8
  394. DWEXT exStIfLabR8
  395. public mStIfGotoLabOpExe
  396. mStIfGotoLabOpExe:
  397. DWEXT exStIfGotoLabI2
  398. DWEXT exStIfGotoLabI4
  399. DWEXT exStIfGotoLabR8
  400. DWEXT exStIfGotoLabR8
  401. public mStElseIfOpExe
  402. mStElseIfOpExe:
  403. DWEXT exStElseIfI2
  404. DWEXT exStElseIfI4
  405. DWEXT exStElseIfR8
  406. DWEXT exStElseIfR8
  407. sEnd SCAN
  408. end