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

操作系统开发

开发平台:

Visual C++

  1. page 49,132
  2. TITLE EXPROC - Executors for procedures
  3. ;***
  4. ;exproc.asm - executors for procedures
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;
  9. ;****************************************************************************
  10. .xlist
  11. include version.inc
  12. EXPROC_ASM = ON
  13. IncludeOnce architec
  14. IncludeOnce context
  15. IncludeOnce executor
  16. IncludeOnce exint
  17. IncludeOnce extort
  18. IncludeOnce opcontrl
  19. IncludeOnce opid
  20. IncludeOnce opstmt
  21. IncludeOnce qbimsgs
  22. IncludeOnce rtinterp
  23. IncludeOnce rtps
  24. IncludeOnce scanner
  25. IncludeOnce ui
  26. IncludeOnce variable
  27. IncludeOnce pcode
  28. .list
  29. PUSHSS MACRO
  30. endm
  31. assumes cs, CODE
  32. assumes es, NOTHING
  33. assumes ss, DATA
  34. sBegin DATA
  35. externB b$ErrInfo
  36. ParamCnt dw 0
  37. sEnd DATA
  38. extrn B$STMakeTemp:far ;Copy string to temp
  39. externFP __fpmath
  40. sBegin CODE
  41. subttl exStCall,exStCallLess,exStCallS
  42. page
  43. ;***
  44. ;exStCall - Execute CALL statement
  45. ;
  46. ;Purpose:
  47. ; 1.  Activate target PRS
  48. ;
  49. ; 2.  Push return address, allocate and zero frame variables.
  50. ;
  51. ; 3.  Execute the SUB.
  52. ;
  53. ; The stack frame looks like this:
  54. ; <arg 1>
  55. ; <arg 2>
  56. ; . . .
  57. ; <arg n>
  58. ; <oRS of return address>
  59. ; <oText of return address>
  60. ; BP--> <old BP>
  61. ; <old b$curframe> [2]
  62. ; <local variables and FOR temps>
  63. ;
  64. ;
  65. ;******************************************************************
  66. MakeExe exFuncNArgSD,opAIdLd,ET_SD
  67. SkipExHeader
  68. MakeExe exFuncNArgI4,opAIdLd,ET_I4
  69. SkipExHeader
  70. MakeExe exFuncNArgR8,opAIdLd,ET_R8
  71. SkipExHeader
  72. MakeExe exFuncNArgI2,opAIdLd,ET_I2
  73. SkipExHeader
  74. MakeExe exFuncNArgR4,opAIdLd,ET_R4
  75. SkipExHeader
  76. MakeExe exFuncNArgImp,opAIdLd,ET_Imp
  77. inc si
  78. inc si ;Skip over arg count
  79. jmp short Func0Arg
  80. MakeExe exFunc0ArgSD,opIdLd,ET_SD
  81. SkipExHeader
  82. MakeExe exFunc0ArgI4,opIdLd,ET_I4
  83. SkipExHeader
  84. MakeExe exFunc0ArgR8,opIdLd,ET_R8
  85. SkipExHeader
  86. MakeExe exFunc0ArgI2,opIdLd,ET_I2
  87. SkipExHeader
  88. MakeExe exFunc0ArgR4,opIdLd,ET_R4
  89. SkipExHeader
  90. MakeExe exFunc0ArgImp,opIdLd,ET_Imp
  91. Func0Arg:
  92. LODSWTX ;Get oVar
  93. xchg ax,bx
  94. mov ax,[pVarBx] ;Get oPRS
  95. jmp short FuncCall
  96. CallCompiledJ:
  97. jmp CallCompiled
  98. MakeExe exStCallS,opStCallS
  99. SkipExHeader
  100. MakeExe exStCallLess,opStCallLess
  101. SkipExHeader
  102. MakeExe exStCall,opStCall
  103. inc si
  104. inc si ;Skip over count of arguments
  105. LODSWTX ;Get oPRS
  106. FuncCall:
  107. ;ax = oPRS of target
  108. GETRS_SEG es,bx,<SPEED,LOAD>
  109. mov bx,ax
  110. RS_BASE add,bx ; es:bx points to prs
  111. test BPTRRS[bx.PRS_flags],FP_DEFINED   ; Interpreted?
  112. jz CallCompiledJ
  113. CallInterpreted:
  114. inc [b$CurLevel] ;Save any temps from deallocation
  115. push [pGosubLast] ;Save current head of Gosub list
  116. push [grs.GRS_oRsCur] ;Push current oRS
  117. xchg dx,ax ;Save oPRS in dx
  118. mov al,0
  119. xchg al,[grs.GRS_fDirect] ;Get fDirect and set to FALSE
  120. or al,al ;Leaving direct mode?
  121. jz NotInDirect
  122. inc si ;Set LSB to indicate direct mode
  123. or [grs.GRS_flags],FG_RetDir
  124. ;remember there's a ret adr to
  125. ; direct mode buffer on stack.
  126. NotInDirect:
  127. ; Warning: SI is assumed to be at [bp+2] for out of stack error recovery.
  128. ; We need to make sure that fDirect gets reset correctly if we couldn't
  129. ; transfer control to the procedure.
  130. push si ;Push current oTx
  131. push bp
  132. mov bp,sp ;Set up frame pointer
  133. push [b$curframe] ; set up BASIC-frame chain
  134. mov cx,PTRRS[bx].PRS_cbFrameVars ; Local variables
  135. add cx,PTRRS[bx].PRS_cbFrameTemp ; Plus temps
  136. dec cx ; cbFrameVars includes 2 bytes to
  137. dec cx ;  account for pushed b$curframe
  138. mov di,sp
  139. sub di,cx ;Allocate local variables and temps
  140. jc OutOfStack ;Underflow?
  141. cmp di,[b$pEndChk]
  142. jbe OutOfStack ;Not enough stack space left
  143. mov sp,di
  144. mov [b$CurFrame],bp  ;must change b$CurFrame AFTER this chk
  145. ; there will always be a block fill
  146. ; needed
  147. jcxz NoLocals
  148. xor ax,ax
  149. push es
  150. push ss
  151. pop es ;es = ss
  152. shr cx,1 ;Word count
  153. rep stosw ;Zero out local variables
  154. pop es
  155. NoLocals:
  156. mov si,PTRRS[bx.PRS_otxDef] ; si points to procedure header
  157. xchg ax,dx ;Restore oPRS to ax
  158. or ah,80H ;oPrs ==> oRs
  159. call RsActivateCODE ;Activate called proc
  160. RestorePcodeVar 
  161. inc si
  162. inc si
  163. LODSWTX ;Get cbEOS
  164. add si,ax ;Start execution after definition
  165. DispMac
  166. OutOfStack:
  167. mov ax,[bp+2] ;LSB is fDirect flag before
  168. ;we started building the frame
  169. ror al,1 ;move lsb to msb
  170. cbw ;replicate msb into ah
  171. mov [grs.GRS_fDirect],ah ;Set fDirect back to entry state
  172. mov al,ER_OM
  173. mov [b$ErrInfo],OMErr_STK ;note that this is really Out of Stack
  174. ;  space, not Out of Memory
  175. call RtErrorCODE
  176. ;Branched to when user is tracing through a native code call.  Since
  177. ;native code can cause screen output, we need to swap to output screen
  178. ;just in case.
  179. ;
  180. ShowOutputScr:
  181. push bx ;save pPrs
  182. call ShowOutScr
  183. GETRS_SEG es,bx,<SIZE,LOAD> ;[4] restore seg of Rs table
  184. pop bx ;restore pPrs
  185. DbAssertRelB [fDebugScr],e,0,CODE,<exproc: ShowOutScr failed>
  186. ;bx = pPrs of procedure to be called
  187. CallCompiled:
  188. cmp [fDebugScr],0
  189. jne ShowOutputScr ;brif debug screen is visible
  190. DbAssertRel fNonQBI_Active,z,0,CODE,<exproc: fNonQBI_Active should be 0>
  191. mov [fNonQBI_Active],bp ;save pointer to most recent QBI frame
  192. inc [b$cNonQBIFrames]
  193. mov ax,[b$curlevel]
  194. mov [bcurlevel_QBI],ax ;if we end up having to blast the stack
  195. ;  back to the most recent QBI frame,
  196. ;  we need this to restore the proper
  197. ;  setting of b$curlevel
  198. ;Save si and cbParam in last temp
  199. mov di,[grs.GRS_oRsCur]
  200. and di,07FFFH ; mask off high bit
  201. RS_BASE add,di
  202. .errnz MRS_cbFrameTemp - PRS_cbFrameTemp
  203. mov ax,PTRRS[di].MRS_cbFrameTemp ; Get no. of temps for module
  204. neg ax ;Make it oBP
  205. add ax,bp
  206. sub ax,PTRRS[di.MRS_cbFrameVars] ; Point to last temp
  207. xchg di,ax
  208. mov [di],si
  209. xor ax,ax ;Always leave ParamCnt zero
  210. xchg ax,[ParamCnt]
  211. mov [di+2],ax ;Amount of stack to clean up
  212. mov [grs.GRS_otxCur],si ;Save here in case of error
  213. cmp BPTRRS[bx.PRS_procType],PT_SUB
  214. jnz CallCompiledFunc ;call a User Library SUB
  215. call dword ptr [bx.PRS_txd.TXD_oCompiled]  
  216. call RestoreFromCall
  217. CallX:
  218. DispMac
  219. CallCompiledFunc:
  220. test BPTRRS[bx].PRS_flags,FP_CDECL
  221. jnz MakeCall ;Don't push addr. for C
  222. mov cl,BPTRRS[bx.PRS_oType] 
  223. and cl,M_PT_OTYPE ; mask out possible flags
  224. cmp cl,ET_SD ;[15][4] Value returned in regs?
  225. jae MakeCall ;[14]
  226. cmp cl,ET_I4 ;[15][4] Value returned in regs?
  227. jbe MakeCall
  228. ; Type is R4, R8, or CY
  229. ;Return value is always just before saved si in temps
  230. ;di = pointer to last temp
  231. ;cl = PRS_oType
  232. add di,4 ;Make room for si and cbParam
  233. push di
  234.     cmp     cl,ET_R4 ;[14] R4 ? Before ES loaded
  235.     mov     ax,0 ;NOTE: CY flag preserved
  236. push ss
  237. pop es ;es:di points to return temp
  238. stosw
  239. stosw ;Zero return value if R4
  240.     je     @F ;brif R4. Only clear two words
  241. stosw
  242. stosw ;Zero rest of R8 or CY
  243. @@:
  244. MakeCall:
  245.     call    dword ptr [bx.PRS_txd.TXD_oCompiled]
  246. call RestoreFromCall
  247. ;Returning from function - restore 8087 stack
  248. pop cx ;Get no. of 8087 registers saved
  249. jcxz NoTemps
  250. RestoreLoop:
  251. mov bx,sp
  252. fld tbyte ptr DGROUP:[bx] ;Put back on stack
  253. add sp,10 ;Move pointer up
  254. loop RestoreLoop
  255. NoTemps:
  256. mov bx,PTRTX[si-2] ;Get oVar
  257. mov cl,[pVarBx].VAR_flags ;oTyp in low bits
  258. and cl,FV_TYP_MASK
  259. cmp cl,ET_I4 ;Value in (dx:)ax?
  260. jb PushI2
  261. je PushI4
  262. cmp cl,ET_SD
  263. jae PushI2 ;If string, push near address in ax
  264. ;ax points to R4 or R8
  265. xchg ax,bx ;ds:bx points to return value
  266. cmp     cl,ET_R4
  267. jnz PushR8
  268. fld dword ptr [bx] ; copy retval to 87 stack
  269. jmp CallX
  270. PushR8:
  271. fld qword ptr [bx] ; copy retval to 87 stack
  272. jmp CallX
  273. PushI4:
  274. push dx
  275. PushI2:
  276. push ax
  277. jmp CallX
  278. RestoreFromCall:
  279. ;Restore es, si, di and NonQBI flags after native code call
  280. ;Possible return value in dx:ax preserved
  281. ;cx preserved
  282. ;Restore return oTx to si
  283. GETRS_SEG es,bx,<SPEED,LOAD> ;[4] restore seg of Rs table
  284. mov bx,[grs.GRS_oRsCur]
  285. and bh,07FH  ; mask off high bit
  286. RS_BASE add,bx
  287. .errnz MRS_cbFrameTemp - PRS_cbFrameTemp
  288. mov si,PTRRS[bx].MRS_cbFrameTemp ; Get no. of temps for module
  289. neg si ;Make it oBP
  290. sub si,PTRRS[bx.MRS_cbFrameVars] ; Point to last temp
  291. pop bx ; bx = ret address
  292. add sp,[si+bp+2] ;Clean off parameters
  293. push bx ; push ret address back
  294. mov si,[si+bp] ;Restore return oTx
  295. DbAssertRel b$cNonQBIFrames,nz,0,CODE,<exproc: b$cNonQBIFrames == 0>
  296. dec [b$cNonQBIFrames]
  297. DbAssertRel fNonQBI_Active,z,bp,CODE,<exproc: fNonQBI_Active not == bp>
  298. mov [fNonQBI_Active],0 ;reset - - QBI code is active again
  299. call GetEsDi
  300. ret
  301. MakeExe exStFunction,opStFunction
  302. SkipExHeader
  303. MakeExe exStSub,opStSub
  304. LODSWTX ;Get cntEOS
  305. add si,ax
  306. DispMac
  307. MakeExe exStDefFN,opStDefFN
  308. mov si,PTRTX[si+2] ;Get link to EndDef
  309. inc si
  310. inc si ;Skip past link to next DefFn
  311. DispMac
  312. MakeExe exEndSingleDef,opEndSingleDef
  313. ;Move return value from top of stack to expected location
  314. mov bx,[grs.GRS_oPrsCur] ; bx points to active prs in table
  315. RS_BASE add,bx
  316. GETRS_SEG  es
  317. mov cx,PTRRS[bx].PRS_cbFrameVars ;[2] Size of return value + 2
  318. mov di,bp
  319. sub di,cx ;Location for return value
  320. .erre FR_FirstVar EQ -2
  321. dec cx ; make cx the size of the return 
  322. dec cx ; value
  323. mov al,BPTRRS[bx].PRS_oType 
  324. and al,M_PT_OTYPE ; mask out possible flag bits
  325. cmp al, ET_SD ;[4] Returning a string?
  326. jae CopySD
  327. mov si,sp ;for integer ret vals
  328. ;Added with [35]
  329. cmp al,ET_R4
  330. jb DefFnInt
  331. jz DefFnR4
  332. fstp qword ptr [di] ;Store R8 return value in stack
  333. jmp short EndProc
  334. DefFnR4:
  335. fstp dword ptr [di] ;Store R4 return value in stack
  336. jmp short EndProc
  337. DefFnInt:
  338. ;End of [35]
  339. push ss
  340. pop es
  341. rep movsb ;Move up return value
  342. jmp short EndProc
  343. CopySD:
  344. ;pSD already on stack
  345. push di ;Assign string to here
  346. CALLRT B$SASS,Mov ;es is now invalid!!
  347. ;Fall into EndDef
  348. SkipExHeader
  349. MakeExe exStEndDef,opStEndDef
  350. SkipExHeader
  351. MakeExe exStEndProc,opStEndProc
  352. mov bx,[grs.GRS_oPrsCur] ; bx points to active prs in table
  353. RS_BASE add,bx
  354. EndProc:
  355. GETRS_SEG es,di,<SPEED,LOAD> ;[4] fetch seg of Rs table
  356. dec [b$CurLevel]
  357. mov ax,[bp].FR_pGosubLast
  358. mov [pGosubLast],ax
  359. mov al,BPTRRS[bx.PRS_cwParams] ; cw of parameters
  360. xor ah,ah
  361. shl ax,1 ;Change to cb
  362. add ax,FR_MinFrame ;Remove frame
  363. add ax,bp ;Compute sp w/o arguments
  364. xchg ax,di ;destination in stack of return value
  365. mov al,BPTRRS[bx.PRS_oType] ; oTyp of return value
  366. and al,M_PT_OTYPE ; mask out possible flag bits
  367. mov ah,BPTRRS[bx.PRS_procType]
  368. push ax
  369. mov si,[bp].FR_otxRet ;Get oTx of return addr
  370. test si,1 ;LSB = returning to direct mode?
  371. jz NotDirect
  372. mov [grs.GRS_fDirect],-1 ;Going back to direct mode
  373. dec si ;Back to true oTx
  374. and [grs.GRS_flags],NOT FG_RetDir
  375. ;remember there's no ret adr to
  376. push ss
  377. pop ds ;ds=DGROUP
  378. ; direct mode buffer on stack.
  379. NotDirect:
  380. mov ax,[bp].FR_oRsRet ;oRs of return addr
  381. call RsActivateCODE ;Activate caller
  382. pop ax ;ah=procType, al=oTyp of RetVal
  383. lea bx,[bp-2].FR_FirstVar ;Point to high end of return value
  384. push [bp].FR_basBpLink ;[33] Restore old b$curframe
  385. pop [b$CurFrame]
  386. mov bp,[bp].FR_bpLink ;Restore old bp
  387. cmp ah,PT_SUB ;Is it a SUB?
  388. jz NoRetVal ;If a SUB, no return value to copy
  389. xchg bx,si ;Save return oTx in bx
  390. ;Added with [32]
  391. ;Restore values to 8087 stack
  392. mov cx,[di] ;Number of temp reals to restore
  393. jcxz No87Temps
  394. Restore87Loop:
  395. fld tbyte ptr DGROUP:[di+2] ;Put back on stack
  396. add di,10 ;Move pointer up
  397. loop Restore87Loop
  398. No87Temps:
  399. ;End of [32]
  400. push ss
  401. pop es ;es = ss
  402. std ;Reverse order--possibly overlapping
  403. cmp al,ET_SD ;String?
  404. jae ReturnSD
  405. .erre ET_SD EQ (ET_MaxNum+1)
  406. ;Rewritten with [24]
  407.     cmp     al,ET_R4
  408.     je     RetR4
  409. cmp al,ET_R8
  410. jz RetR8
  411. ;Have I2, I4, or CY
  412. cbw
  413. xchg cx,ax
  414. .erre ET_I2 EQ 1 ;cw of I2
  415. .erre ET_I4 EQ 2 ;cw of I4
  416. rep movsw ;Copy return value
  417. SetSi:
  418. mov si,bx ;Return oTx
  419. ValInPlace:
  420. inc di
  421. inc di
  422. cld
  423. NoRetVal:
  424. mov sp,di ;Return val on top of stack
  425. RestorePcodeVar 
  426. DispMac
  427. ReturnSD:
  428. dec si
  429. dec si ;Point to low byte of SD
  430. push si
  431. mov si,bx ;Return oTx
  432. mov [grs.GRS_otxCur],si ;Save in case of error
  433. call B$STMakeTemp ;Make SD a temp - ax = pSD
  434. stosw ;pSD/handle to its place in stack
  435. jmp ValInPlace
  436. ;Added with [24]
  437. RetR4:
  438. fld dword ptr DGROUP:[si-2]
  439. jmp SetSi
  440. RetR8:
  441. fld qword ptr DGROUP:[si-6]
  442. jmp SetSi
  443. ;End of [24]
  444. MakeExe exNoList1,opNoList1
  445. inc si
  446. inc si ;Eat one operand
  447. SkipExHeader
  448. MakeExe exSeg,opSeg
  449. SkipExHeader
  450. MakeExe exByVal,opByVal
  451. DispMac
  452. ;Added with [32]
  453. MakeExe exSave87,opNoList0
  454. ;The following special interface is used to obtain the number
  455. ;of items on the 87/em stack.  This allows us to account for
  456. ;the extended stack with the emulator, with or without an 80x87.
  457. mov bx,10 ;arg to __fpmath to get count
  458. call __fpmath ;AX = # items on the 87/em stack
  459. mov cx,ax ;Count to cx
  460. jcxz EmptyStack ;go if nothing to do
  461. Save87Loop:
  462. sub sp,10 ;Make room for a temp real
  463. mov bx,sp
  464. fstp tbyte ptr DGROUP:[bx]
  465. loop Save87Loop
  466. EmptyStack:
  467. push ax ;Remember how much we saved
  468. DispMac
  469. MakeExe exParamCnt,opNoList1
  470. LODSWTX
  471. mov [ParamCnt],ax ;Remember how much to release
  472. DispMac
  473. ;End of [32]
  474. MakeExe exAddStack,opNoList1
  475. LODSWTX
  476. add sp,ax ;De-allocate stack space
  477. DispMac
  478. MakeExe exDeallocArray,opNoList1 ;oBP
  479. ;De-allocate local array va