⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssoperat.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	page	49,132
	TITLE	ssoperat - scan intrinsic unary functions and operators
;***
;ssoperat - scan support for intrinsic unary operantors and functions
;
;	Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
;   Scan unary operators and intrinsic functions.
;   Also contains scan dispatches for functions that have no arguments.
;
;
;****************************************************************************

	.xlist
	include 	version.inc
SSOPERAT_ASM = ON
	IncludeOnce	pcode		
	IncludeOnce	qbimsgs
	IncludeOnce	ssint
	IncludeOnce	variable
	.list


assumes ds, DATA
assumes es, DATA
assumes ss, DATA


	subttl Ss_FnString
	page

sBegin	CODE

	extrn	exFnString_SD:near
	extrn	exFnString_I2:near


sEnd	CODE

sBegin	SCAN


	extrn	tCo1toNotSD:byte	


assumes cs, SCAN

	;Table to map ET type to coercion table index
	;Added with [11]

Index	=	0
BadType	=	-1
Next	MACRO	Cond
IFNB	<Cond>
IFE	Cond
	exitm
ENDIF
ENDIF
	db	Index
Index	=	Index+1
	ENDM

mpScanType	label	byte
	db	BadType		;Records
I2Ind	=	Index		; Needed in MSdFs to map Forms to I2
	Next			;I2
	Next			;I4
	Next			;R4
	Next			;R8
SdInd	=	Index		;Need for FS
	Next			;SD
TxInd	=	Index		;Need for FT
	db	SdInd		;FS
	.erre	ET_MAX EQ ($-mpScanType-1)

	;Index = number of row/columns in coercion table
	;End of [11]


SsProc	FnString
	pop	ax			;AX = oTyp of argument. Record = ET_RC
	push	ax			;Restore on stack for EnsureArgType
	.erre	ST_Typ_Mask EQ 0ffh	; Assure we can use AL
	cmp	al,ET_MaxNum		; Is it numeric?
	jbe	FnStringI2		; Brif numeric or record
	mov	ax,ET_SD		; Result type is source type SD/TX
	call	EnsureArgType		;Eat the SD
	mov	ax,codeOFFSET exFnString_SD ;Load appropriate executor
	jmp	short FnStringEmitExe	;Go emit the exe and continue

FnStringI2:
	mov	ax,ET_I2		;Require an I2 for last argument
	call	EnsureArgType		;Ensure top argument is correct
	mov	ax,codeOFFSET exFnString_I2	;Was I2
FnStringEmitExe:
	STOSWTX 			;Emit the executor
	    mov     ax,ET_I2		;Eat the I2 count
	call	EnsureArgType
	push	di			;Frame -> oTx
	PushI	ax,ET_SD		;Frame -> oTyp
	jmp	[ScanRet]		;Go handle first arg and type explosion



SsProc	UMi
	xchg	bx,ax			;Executor map to bx
	pop	ax			;AX = oTyp of argument. Record = ET_RC
	pop	dx			;Discard oTx
	mov	cx,ax			;Save copy of type high bits
	.erre	ST_Typ_Mask EQ 0ffh	; Assure CBW is sufficient
	.erre	ET_MAX LT 80h		; Assure CBW is sufficient
	cbw				; Clear flags in scan stack
	dec	ax			; ET_RC --> 0FFFFh
	.erre	ET_RC EQ 0		; Assure JB is sufficient
	cmp	al,ET_MaxNum		;[3] Must be numeric
	jb	MapUM			;[3]
	call	TMError
	.erre	ET_I2 EQ 1		; Assure XOR is sufficient
	xor	ax,ax			; Force valid type (ET_I2)
MapUM:
	add	bx,ax
	add	bx,ax
	mov	ax,cs:[bx]		; Get executor
	STOSWTX 			;Emit executor
	push	di			;Build stack entry
	.errnz	LOW ST_Lit?		; Assure we can use CH
	xor	ch,HIGH ST_Lit? 	;High bits now zero if literal/const

	test	ch,0C0H			;Literal or constant?
	jnz	NotLit
	.errnz	LOW ST_LitX		; Assure we can use CH
	or	ch,HIGH ST_LitX		;Make it a constant
	jmp	short UMiX

NotLit:
	.erre	ST_Typ_Mask EQ 0ffh	; Assure XOR is sufficient
	xor	ch,ch			; Clear flags to make expression
UMiX:
	push	cx
	jmp	[ScanRet]	


	subttl	Ss_0FnETExe
	page
;***
;Ss_0FnETExe - Scan functions with 0 args
;
;Purpose:
;
;   Scan functions with 0 args.
;   These functions always have only one executor and one emitted type.
;   mpOpRule contains the emitted type.
;   mpOpExe contains the executor.
;
;Input:
;
;   ax = opcode
;   bx = opcode * 2
;   es:si   = source code address
;   es:di   = destination code address
;
;Output:
;
;   none
;
;**********************************************************************

SsProc	0FnETExe
	shr	bx,1			;Get rule address
	xor	cx,cx
	mov	cl,mpOpRule[bx] 	;Rule table index is the emitted type
					;cx = type emitted
	jmp	short EmitDxIdFrameX	;Exit through Ss_1FnETETExe


	subttl	Ss_2FnSamePExe
	page
;***
;Ss_2FnSamePExe - Scan routine for functions with 2 arguments and many executors
;
;Purpose:
;
;   This scan routine handles intrinsic functions and operators that:
;	- have 2 arguments
;	- mpOpExe is a pointer to a list of executors entered by type
;	- output type is either the input type or a constant (as
;	  indicated by LOW UNDEFINED in the mpOpRule entry)
;
;   This routine is dispatched by a JMP.
;
;Algorithm:
;
;   Get rule
;   Calculate coercion table address
;      Coerce table mpOpRule[(mpOpRule[opcode].irule)*sizeof(Rule)].pCoerce
;      Coercion table dimension is 2.
;   Enter coercion table based on operand entries on stack
;   Insert any needed coercion
;      If type from table does not match the input types AND
;	    required coercion is integer constant to single constant
;	    change the integer constant to the appropriate single constant
;	Else
;	    Enter the coercion executor table to find the coercion
;	    routine (or an error, if the types are not compatible).
;   Emit executor for current opcode
;   Push emit type entry on stack
;
;Input:
;
;   es:si = pcode emission address
;
;Output:
;
;   si updated
;
;Modifies:
;Exceptions:
;	Ss_Error
;******************************************************************
	page


SsProc	2FnSamePExe
	push	bp			
	mov	bp,sp			

	;Get left side type - records are always errors.

	mov	ax,[bp+6]		; AX = oTyp of left operand
	call	MSdFs			;Record? Map FS to SD

	; Multiply zero relative index by Index, the number of different types

	mov     cx,ax
	shl     cx,1			;*2
IF	Index AND 8
	shl     cx,1
ENDIF
IF	Index AND 2
	add     cx,ax			;*3
ENDIF
	shl     cx,1			;*4 or *6
IF	Index AND 1
	add     cx,ax			;*5 or *7
ENDIF
	.erre	(Index LE 11) AND (Index GE 4)

	;Get right side type - records are always errors.

	mov	ax,[bp+2]		; CX = oTyp of right operand
	pop	bp
	call	MSdFs			;Record? Map FS to SD

	;Get target type from coercion table

	add	ax,cx			;Coercion table index
	mov	cx,bx			;Save opcode*2
	shr	bx,1			;Back to opcode (byte index)
	mov	bl,mpOpRule[bx] 	;Get the rule table index
	xor	bh,bh
	mov	dx,bx			;Preserve tRuleByte index for exit
	shl	bx,1			;To word index
	mov	bx,tRuleWord[bx]	;Coercion table address
	xlat	byte ptr cs:[bx]	;Get result type
	cbw
	call	EnsureArgType		; Coerce right side expression
	call	EnsureArgType		; Coerce left side expression
	mov	bx,cx			; Opcode*2 back to bx
	mov	bx,mpOpExe[bx]		;Get executor address map
	xchg	dx,bx
	mov	cl,tRuleByte[bx]	;cx = rule table byte
	xor	ch,ch

EmitTypeExeIdFrameX:
	;ax = argument type (UNDEFINED if type mismatch)
	;cx = rule table byte
	;dx = executor map address

	;Emit executor for current opcode

	cmp	ax,UNDEFINED
	jnz	EmitValidTypeExe
	mov	ax,ET_I2		;This type valid for all users
EmitValidTypeExe:
	mov	bx,dx			;Exe map address to bx
	dec	ax			;To zero relative
	add	bx,ax
	add	bx,ax
	inc	ax
	mov	dx,WORD PTR cs:[bx]	;Executor address

EmitDxIdFrameX:
	;ax = argument type
	;cx = rule table byte
	;dx = executor

	xchg	dx,ax			;ax = executor, dx = input type
	STOSWTX

	xor	ch,ch			;cx = word oType or LOW UNDEFINED
	jcxz	UpdateOTxStart		; Not a function (nothing to emit)

	;Build stack entry for expression location and type

	cmp	cl,LOW UNDEFINED	;Test for output type = input type
	jne	@F			;Output type not input type (cx = type)
	mov	cx,dx			;Output type is input type (saved in dx)
@@:
	push	di			;Stack expression fragment address
	push	cx			;Stack type for expression fragment
	DbAssertRel cx,be,ET_MAX,SCAN,<EmitIdFrameX:  Unexpected return type>  
	    cmp     cl,ET_SD		; SD result?
	    jb	    @F			;Exit if not
	    mov     [SsOTxHeapMove],di	;Assume it can move the heap
@@:
X1FnPExe:
	jmp	[ScanRet]		;Return to scan loop

UpdateOTxStart: 			
	mov	[SsOTxStart],di 	; Update clear stack location
	jmp	X1FnPExe		


	subttl	Ss_1FnPExe
	page
;***
;Ss_1FnPExe - Scan routine for functions with 1 argument and many executors
;
;Purpose:
;
;   This scan routine handles intrinsic functions and operators that:
;      - have 1 argument
;      - mpOpExe is a pointer to a list of executors entered by type
;      - output type depends on the tRuleByte entry as follows:
;	    the input type (indicated by LOW UNDEFINED)
;	    a constant (as indicated by an ET_xx constant)
;	    no emitted type (as indicated by 0)
;
;Algorithm:
;
;   Get rule
;   Calculate coercion table address
;      Coercion table tRuleWord[mpOpRule[opcode].irule].pCoerce
;      Coercion table dimension is 1.
;   Pop operand from stack.
;   Enter appropriate coercion table to find input type.
;   Insert any needed coercion
;      If type from table does not match the input types AND
;	    required coercion is integer constant to single constant

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -