ssdo.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:8k
源码类别:
操作系统开发
开发平台:
Visual C++
- page 49,132
- TITLE ssdo - scan support for DO/WHILE related opcodes
- ;***
- ;ssdocase.asm
- ;
- ; Copyright <C> 1987, Microsoft Corporation
- ;
- ;Purpose:
- ; Scan DO/LOOP, and WHILE/WEND statement opcodes.
- ;
- ; Runtime behavior of LOOP opcodes:
- ; ---------------------------------
- ; <exp> opStDoWhile(oText) - branch to oText if exp is zero (false)
- ; <exp> opStWhile(oText) - branch to oText if exp is zero (false)
- ; <exp> opStDoUntil(oText) - branch to oText if exp is non-zero (true)
- ; opStLoop(oText) - unconditionally branch to oText
- ; opStWend(oText) - unconditionally branch to oText
- ; opStDo - nop
- ; <exp> opStLoopWhile(oText) - branch to oText if exp is non-zero (true)
- ; <exp> opStLoopUntil(oText) - branch to oText if ext is zero (false)
- ; <exp> opStExitDo(oText) - unconditionally branch to oText
- ;
- ; DO [WHILE | UNTIL]/LOOP and WHILE/WEND statement syntax to pcode mappings:
- ; --------------------------------------------------------------------------
- ;
- ; Syntax: DO WHILE <exp> ... LOOP
- ;
- ; +-----------------+
- ; Pcode: opBol | <exp> opStDoWhile(|) ... opStLoop(|)|
- ; +-----------------------------------+
- ;
- ; ============================================================
- ; Syntax: WHILE <exp> ... WEND
- ;
- ; +-----------------+
- ; Pcode: opBol | <exp> opStWhile(|) ... opStWend(|)|
- ; +---------------------------------+
- ;
- ; Note: WHILE/WEND and DO WHILE/LOOP have different opcodes for
- ; listability, but are functionally equivilent. They both
- ; map to the same runtime executors for size reduction.
- ;
- ; ============================================================
- ; Syntax: DO UNTIL <exp> ... LOOP
- ;
- ; +-----------------+
- ; Pcode: opBol | <exp> opStDoUntil(|) ... opStLoop(|)|
- ; +-----------------------------------+
- ;
- ; DO/LOOP [WHILE | UNTIL] statement syntax to pcode mappings:
- ; -----------------------------------------------------------
- ;
- ; Syntax: DO ... LOOP WHILE <exp>
- ;
- ;
- ; Pcode: opStDo| ... <exp> opStLoopWhile(|)
- ; +-------------------------+
- ;
- ; ============================================================
- ; Syntax: DO ... LOOP UNTIL <exp>
- ;
- ;
- ; Pcode: opStDo| ... <exp> opStLoopUntil(|)
- ; +-------------------------+
- ;
- ; ============================================================
- ; Syntax: EXIT DO
- ;
- ; Pcode: opStExitDo(otext) to beyond opStLoop*
- ;
- ; Note the scan routine for EXIT DO is the same as EXIT FOR and is
- ; in ssfor.asm.
- ;
- ;
- ;****************************************************************************
- .xlist
- include version.inc
- IncludeOnce qbimsgs
- IncludeOnce ssint
- .list
- assumes ds, DATA
- assumes es, NOTHING
- assumes ss, DATA
- assumes cs, SCAN
- sBegin SCAN
- subttl Static data area definitons.
- page
- ;***
- ;Ss_Do, Ss_DoLoop, Ss_While
- ;Purpose:
- ; Scan entries for DO, DO WHILE, DO UNTIL, and WHILE.
- ;
- ; Scan tasks for DO WHILE, DO UNTIL, and WHILE include:
- ; - ensuring the entry type is a fundamental, non string data type.
- ; - selecting the DO executor varient for the argument data type.
- ; - pushing a DO/WHILE frame on the scan stack as follows:
- ; push oTx of DO operand
- ; push oTx of opcode after opBol for return branch from LOOP/WEND
- ; push DO frame label (identifying DO WHILE, DO UNTIL, WHILE)
- ;
- ; Scan tasks for DO
- ; - push a DO frame on the scan stack as follows:
- ; push junk
- ; push oTx of opCode after DO for return branch
- ; push DO frame label
- ;Input:
- ; Standard scan entrypoint
- ;Output:
- ; Standard scan exit
- ;***************************************************************************
- SsProc While ;WHILE entry point
- mov dh,high STYP_While ;Specify a WHILE frame
- jmp short DoLoopCom
- SsProc DoLoop ;DO WHILE, and DO UNTIL scan
- mov dh,high STYP_Do ;Specify a DO frame
- DoLoopCom:
- pop ax ;Get oTyp of last expression
- pop cx ;Discard coercion point (None used)
- push bx ;Save opcode * 2
- cCall MapOpToExeNumeric ;Type explode the executor
- STOSWTX ;Emit the executor
- pop bx
- shr bx,1 ;bx = opcode (byte offset to mpOpRule)
- mov dl,mpOpRule[bx] ;dl = Do varient
- mov bx,[SsOTxStart] ; BX = oTx after BOS
- mov ax,di ;di = oTx of exit branch
- jmp short SsDoCom
- SsProc Do ;DO scan
- STOSWTX ;Emit the executor
- mov bx,di
- mov ax,UNDEFINED ;No initial exit branch
- mov dx,STYP_Do ;just a plain old DO frame
- SsDoCom:
- push ax ;Push head of exit branch chain
- push bx ;Push return branch oTx
- push dx ;Push frame type
- cmp dx,STYP_Do ;is this a DO...LOOP?
- jz SsDoSkip ;brif so, no operand to emit
- mov ax,UNDEFINED ;UNDEFINED will terminate Exit chain
- STOSWTX ;emit Exit chain terminator
- inc si
- inc si ;skip source operand
- SsDoSkip:
- jmp [ScanRet]
- page
- ;***
- ;Ss_LoopWhile, Ss_Loop
- ;Purpose:
- ; Scan entries for LOOP WHILE, LOOP UNTIL, LOOP, and WEND.
- ;
- ; Scan tasks for LOOP WHILE and LOOP UNTIL include:
- ; - ensure the entry type is a fundamental, non string data type.
- ; - emit the LOOP executor varient for the argument data type.
- ; - pop DO frame, check errors
- ; + DO nesting error if top frame is not a DO
- ; + DO nesting error if frame is DO WHILE, DO UNTIL
- ; - bind LOOP to DO
- ; - bind EXIT DO chain to end of LOOP
- ;
- ; Scan tasks for LOOP and WEND
- ; - emit executor
- ; - pop DO/WHILE frame, check errors
- ; + nesting error if top frame is not a matching DO/WHILE
- ; + DO nesting error if frame is plain DO
- ; - bind LOOP to DO opBol
- ; - bind EXIT DO chain and DO operand to end of LOOP
- ;
- ;Input:
- ; Standard scan entrypoint
- ;Output:
- ; Standard scan exit
- ;***************************************************************************
- SsProc LoopWhile
- pop ax ;Get oTyp of last expression
- pop cx ;Discard coercion point (None used)
- push bx
- cCall MapOpToExeNumeric ;Type explode the executor
- pop bx
- jmp short LoopCom
- SsProc Wend
- mov dh,high STYP_While ;need to look for a While stack entry
- jmp short WendCom
- SsProc Loop
- LoopCom:
- mov dh,high STYP_Do ;need to find a DO on the stack
- WendCom:
- STOSWTX ;Emit the executor
- shr bx,1 ;bx = opcode (byte offset to mpOpRule)
- mov dl,mpOpRule[bx] ;dx = Do varient
- pop ax ;ax = frame type
- mov cx,MSG_Loop ;assume a LOOP w/o DO error
- cmp dh,ah ;is this a matching DO/WHILE frame?
- jne LoopError ;brif not - scoping error
- cmp dh,high STYP_While ;is this a WHILE/WEND match?
- je LoopScopeOk ;brif so - scope ok
- mov dh,dl
- or dh,al
- jz LoopScopeOk ;have a DO -> LOOP
- jpe LoopErrMsg ;scope error - either
- ;DO WHILE -> LOOP UNTIL, or
- ;DO UNTIL -> LOOP WHILE
- cmp dl,al ;is this DO WHILE -> LOOP WHILE,
- ;or DO UNTIL -> LOOP UNTIL?
- je LoopErrMsg ;brif so - scope error
- LoopScopeOk:
- pop ax ;oTx for Loop branch
- STOSWTX ;bind LOOP to DO
- inc si
- inc si ;skip over operand in source
- pop bx ;oTx of DO [WHILE|UNTIL],WHILE operand
- call BindExitCur ;bind all loop EXIT paths
- LoopExit:
- jmp [ScanRet]
- LoopError:
- cmp dh,high STYP_Do ;is this a LOOP without DO?
- jz LoopErrMsg ;brif so
- mov cx,ER_WE ;WEND without WHILE
- LoopErrMsg:
- push ax ;put back frame type on stack
- xchg ax,cx
- call SsError
- MOVSWTX ;skip operand
- jmp short LoopExit ;exit
- subttl Opcode to executor maps for Do
- page
- public mStWhileOpExe
- mStWhileOpExe:
- DWEXT exStI2While
- DWEXT exStI4While
- DWEXT exStR8While
- DWEXT exStR8While
- public mStDoWhileOpExe
- mStDoWhileOpExe:
- DWEXT exStDoI2While
- DWEXT exStDoI4While
- DWEXT exStDoR8While
- DWEXT exStDoR8While
- public mStDoUntilOpExe
- mStDoUntilOpExe:
- DWEXT exStDoI2Until
- DWEXT exStDoI4Until
- DWEXT exStDoR8Until
- DWEXT exStDoR8Until
- public mStLoopWhileOpExe
- mStLoopWhileOpExe:
- DWEXT exStLoopI2While
- DWEXT exStLoopI4While
- DWEXT exStLoopR8While
- DWEXT exStLoopR8While
- public mStLoopUntilOpExe
- mStLoopUntilOpExe:
- DWEXT exStLoopI2Until
- DWEXT exStLoopI4Until
- DWEXT exStLoopR8Until
- DWEXT exStLoopR8Until
- sEnd SCAN
- end