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

📄 evaluate.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	mov	d[edi+5],0
	mov	b[edi+9],'+'
	add	edi,10
@@P3_2:	rep	movsb
	mov	b[edi],-1		;make sure its terminated.
	;
	;Evaluate the expresion
	;
	call	CalculateNum
	push	ds
	pop	es
	popm	ebp,esi
	jc	@@9		;bad number!
	;
	;put result somewhere safe.
	;
	pushm	esi,ebp
	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer2
	mov	ecx,9
	rep	movsb
	popm	esi,ebp
	;
	;insert new value.
	;
	mov	edx,esi
	lea	esi,EvaluateBuffer3
	lea	edi,EvaluateBuffer
	mov	ecx,ebp
	sub	ecx,offset EvaluateBuffer	;how much to copy back.
	or	ecx,ecx
	jz	@@ParenLook_6
	rep	movsb		;move up to parenthesis.
@@ParenLook_6:	lea	esi,EvaluateBuffer2
	mov	ecx,9
	rep	movsb		;copy new value.
	mov	esi,edx
	inc	esi		;point to data after closing paren
	sub	esi,offset EvaluateBuffer
	mov	ecx,esi
	add	esi,offset EvaluateBuffer3
	sub	ecx,MaxLineLength
	neg	ecx		;get length remaining.
	rep	movsb		;copy the rest.
@@ParenLook_5:	jmp	@@ParenLook
@@ParenLook_10:	;
	;Calculate real number now!
	;
	call	CalculateNum
	jc	@@9
	;
	;now move the result into a useful place.
	;
	lea	esi,EvaluateBuffer+1
	lea	edi,EvaluateBuffer
	cmp	b[edi],0		;final check for a number.
	jnz	@@9
	movsd
	movsd			;shift the result!
	lea	esi,EvaluateBuffer
	test	w[esi+4],1 shl 31
	jnz	@@CheckNeg
	mov	eax,[esi]
	and	eax,VarSizeMask
	mov	edx,eax
	mov	eax,[esi+4]
	and	eax,VarSizeMask+4
	or	eax,edx
	jnz	@@13
	jmp	@@ItsOk
@@CheckNeg:	xor	eax,eax
	xor	edx,edx
	sub	eax,[esi]
	sbb	edx,[esi+4]
	and	eax,VarSizeMask
	and	edx,VarSizeMask+4
	or	eax,edx
	jnz	@@13
@@ItsOk:	;
	;set flags for succesful exit.
	;
	clc
	ret
@@15:	mov	ax,16
	jmp	@@11
@@14:	mov	ax,17
	jmp	@@11
@@13:	mov	ax,18
	jmp	@@11
@@12:	mov	ax,19
	jmp	@@11
@@10:	mov	ax,16
	jmp	@@11
@@9:	mov	ax,21
@@11:	stc
	ret
EvaluateData	endp


;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
;
;convert the number in the buffer into a real number.
;
CalculateNum	proc	near
@@ShlExpand:	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer2
	push	ds
	pop	es
	xor	bx,bx		;reset expansion flag.
@@ShlExpand_0:	cmp	b[esi],'<'
	jz	@@ShlExpand_2		;do the addition.
	mov	ebp,edi		;point to current value.
	movsb			;move type byte.
	cmp	b[esi-1],0		;is it a number?
	jnz	@@ShlExpand_1
	mov	ecx,[esi]
	movsd			;move the value.
	mov	edx,[esi]		;setup the accumulator.
	movsd
@@ShlExpand_1:	cmp	ds:b[ebp],-1		;last value?
	jnz	@@ShlExpand_0		;keep looking.
	jmp	@@ShlExpand_3
@@ShlExpand_2:	inc	esi		;move to next number.
	cmp	b[esi],0		;check its a number.
	jnz	@@9		;bad expresion.
	mov	eax,ecx
	mov	ecx,[esi+1]
	or	ecx,ecx
	jz	@@ShlLoop99
@@ShlLoop:	shl	eax,1
	rcl	edx,1
	jc	@@10
	loop	@@ShlLoop
@@ShlLoop99:	mov	ds:[ebp+1],eax
	mov	ds:[ebp+5],edx		;store the result.
	add	esi,9		;point to next entry.
	mov	bl,1		;flag action.
	jmp	@@ShlExpand_0		;go look for more action.
@@ShlExpand_3:	mov	b[ResultBuffer+8],0
	sub	edi,offset EvaluateBuffer2 ;get length of expresion.
	mov	ecx,edi		;/
	inc	ecx		;include terminator.
	lea	esi,EvaluateBuffer2
	lea	edi,EvaluateBuffer
	rep	movsb		;copy it back into the buffer.
	or	bl,bl		;did we expand anything?
	jnz	@@ShlExpand		;do it again till no more work.
@@ShrExpand:	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer2
	push	ds
	pop	es
	xor	bx,bx		;reset expansion flag.
@@ShrExpand_0:	cmp	b[esi],'>'
	jz	@@ShrExpand_2		;do the addition.
	mov	ebp,edi		;point to current value.
	movsb			;move type byte.
	cmp	b[esi-1],0		;is it a number?
	jnz	@@ShrExpand_1
	mov	ecx,[esi]
	movsd			;move the value.
	mov	edx,[esi]		;setup the accumulator.
	movsd
@@ShrExpand_1:	cmp	ds:b[ebp],-1		;last value?
	jnz	@@ShrExpand_0		;keep looking.
	jmp	@@ShrExpand_3
@@ShrExpand_2:	inc	esi		;move to next number.
	cmp	b[esi],0		;check its a number.
	jnz	@@9		;bad expresion.
	mov	eax,ecx
	mov	ecx,[esi+1]
	or	ecx,ecx
	jz	@@ShrLoop99
@@ShrLoop:	shr	edx,1
	rcr	eax,1
	loop	@@ShrLoop
@@ShrLoop99:	mov	ds:[ebp+1],eax
	mov	ds:[ebp+5],edx	;store the result.
	add	esi,9		;point to next entry.
	mov	bl,1		;flag action.
	jmp	@@ShrExpand_0		;go look for more action.
@@ShrExpand_3:	mov	b[ResultBuffer+8],0
	sub	edi,offset EvaluateBuffer2 ;get length of expresion.
	mov	ecx,edi		;/
	inc	ecx		;include terminator.
	lea	esi,EvaluateBuffer2
	lea	edi,EvaluateBuffer
	rep	movsb		;copy it back into the buffer.
	or	bl,bl		;did we expand anything?
	jnz	@@ShrExpand		;do it again till no more work.
	;
	;now expand any multiplication
	;
@@MulExpand:	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer2
	push	ds
	pop	es
	xor	bl,bl		;reset expansion flag.
@@MulExpand_0:	cmp	b[esi],'*'
	jz	@@MulExpand_2		;do the multiplication.
	mov	ebp,edi		;point to current value.
	movsb			;move type byte.
	cmp	b[esi-1],0		;is it a number?
	jnz	@@MulExpand_1
	mov	ecx,[esi]
	movsd			;move the value.
	mov	edx,[esi]		;setup the accumulator.
	movsd
@@MulExpand_1:	cmp	ds:b[ebp],-1		;last value?
	jnz	@@MulExpand_0		;keep looking.
	jmp	@@MulExpand_3
@@MulExpand_2:	inc	esi		;move to next number.
	cmp	b[esi],0		;check its a number.
	jnz	@@9		;bad expresion.
	pushm	esi,edi,bx
	inc	esi
	mov	edi,ebp
	inc	edi
	call	Mult64
	lea	ebx,ResultBuffer
	mov	ecx,[ebx]
	mov	edx,[ebx+4]		;get the result.
	mov	eax,[ebx+12]
	or	eax,[ebx+8]
	popm	esi,edi,bx
	jnz	@@10
	mov	ds:[ebp+1],ecx
	mov	ds:[ebp+5],edx	;store the result.
	add	esi,9		;point to next entry.
	mov	bl,1		;flag action.
	jmp	@@MulExpand_0		;go look for more action.
@@MulExpand_3:	sub	edi,offset EvaluateBuffer2 ;get length of expresion.
	mov	ecx,edi		;/
	inc	ecx		;include terminator.
	lea	esi,EvaluateBuffer2
	lea	edi,EvaluateBuffer
	rep	movsb		;copy it back into the buffer.
	or	bl,bl		;did we expand anything?
	jnz	@@MulExpand		;do it again till no more work.
	;
	;expand any division
	;
@@DivExpand:	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer2
	push	ds
	pop	es
	xor	bl,bl		;reset expansion flag.
@@DivExpand_0:	cmp	b[esi],'/'
	jz	@@DivExpand_2		;do the multiplication.
	mov	ebp,edi		;point to current value.
	movsb			;move type byte.
	cmp	b[esi-1],0		;is it a number?
	jnz	@@DivExpand_1
	mov	ecx,[esi]
	movsd			;move the value.
	mov	edx,[esi]		;setup the accumulator.
	movsd
@@DivExpand_1:	cmp	ds:b[ebp],-1		;last value?
	jnz	@@DivExpand_0		;keep looking.
	jmp	@@DivExpand_3
@@DivExpand_2:	inc	esi		;move to next number.
	cmp	b[esi],0		;check its a number.
	jnz	@@9		;bad expresion.
	pushm	esi,edi,ebx,ebp
	inc	esi		;point to divisor.
	mov	eax,[esi]
	mov	ExtraSpace,eax
	mov	eax,[esi+4]
	mov	ExtraSpace+4,eax
	mov	edi,ebp
	inc	edi
	mov	eax,[edi]
	mov	TempWord,eax
	mov	eax,[edi+4]
	mov	TempWord+4,eax
	lea	esi,TempWord
	lea	edi,ExtraSpace
	call	Div64
	lea	ebx,TempWord
	mov	ecx,[ebx]
	mov	edx,[ebx+4]		;get the result.
	popm	esi,edi,ebx,ebp
	mov	ds:[ebp+1],ecx
	mov	ds:[ebp+5],edx	;store the result.
	add	esi,9		;point to next entry.
	mov	bl,1		;flag action.
	jmp	@@DivExpand_0		;go look for more action.
@@DivExpand_3:	sub	edi,offset EvaluateBuffer2 ;get length of expresion.
	mov	ecx,edi		;/
	inc	ecx		;include terminator.
	lea	esi,EvaluateBuffer2
	lea	edi,EvaluateBuffer
	rep	movsb		;copy it back into the buffer.
	or	bl,bl		;did we expand anything?
	jnz	@@DivExpand		;do it again till no more work.
	;
	;now expand any addition/subtraction.
	;
@@AddExpand:	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer2
	push	ds
	pop	es
	xor	bx,bx		;reset expansion flag.
@@AddExpand_0:	cmp	b[esi],-1		;end of the line?
	jz	@@AddExpand_3		;copy back to buffer.
	cmp	b[esi],0
	jz	@@AddExpand_5		;copy number.
	mov	al,[esi]		;get operator.
	inc	esi
	cmp	b[esi],0		;check number next.
	jnz	@@9
	;
	cmp	al,'+'
	jz	@@AddExpand_2		;do the addition.
	cmp	al,'-'
	jz	@@SubExpand_2		;do the subtraction.
	cmp	al,'&'
	jz	@@AndExpand_2		;do the and.
	cmp	al,'|'
	jz	@@OrExpand_2		;do the or.
	;
	jmp	@@9		;dunno what this is!
	;
@@AddExpand_5:	mov	ebp,edi		;point to current value.
	movsb			;move type byte.
	mov	ecx,[esi]
	movsd			;move the value.
	mov	edx,[esi]		;setup the accumulator.
	movsd
	jmp	@@AddExpand_0	;keep looking.
	;
@@AddExpand_2:	add	ecx,[esi+1]
	adc	edx,[esi+5]		;perform addition.
	jnc	@@AddExpand_4
	cmp	ds:d[ebp+5],0
	jns	@@10
@@AddExpand_4:	mov	ds:[ebp+1],ecx
	mov	ds:[ebp+5],edx	;store the result.
	add	esi,9		;point to next entry.
	mov	bl,1		;flag action.
	jmp	@@AddExpand_0		;go look for more action.
	;
@@SubExpand_2:	sub	ecx,[esi+1]
	sbb	edx,[esi+5]		;perform subtraction.
	jmp	@@AddExpand_4
	;
@@AndExpand_2:	and	ecx,[esi+1]
	and	edx,[esi+5]		;perform addition.
	jmp	@@AddExpand_4
	;
@@OrExpand_2: 	or	ecx,[esi+1]
	or	edx,[esi+5]		;perform addition.
	jmp	@@AddExpand_4
	;
@@AddExpand_3:	mov	b[edi],-1
	mov	b[ResultBuffer+8],bh
	or	bh,bh
	jnz	@@9
	sub	edi,offset EvaluateBuffer2 ;get length of expresion.
	mov	ecx,edi		;/
	inc	ecx		;include terminator.
	lea	esi,EvaluateBuffer2
	lea	edi,EvaluateBuffer
	rep	movsb		;copy it back into the buffer.
	or	bl,bl		;did we expand anything?
	jnz	@@AddExpand		;do it again till no more work.
	;
	clc
	ret
	;
@@10:	mov	ax,18
@@9:	stc
	ret
CalculateNum	endp


;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
;
;MULT two 64 bit numbers together
;point EDI at one, ESI at the other,
;result in RESULT, can be 128 bit, to allow checking for overflow
;
MULT64	proc	near
	mov	resultbuffer,0
	mov	resultbuffer+4,0
	mov	resultbuffer+8,0
	mov	resultbuffer+12,0
	mov	eax,[edi]	;move to where it can be worked on
	mov	tempword,eax
	mov	eax,[edi+4]	;ditto second word
	mov	tempword+4,eax
	mov	TempWord+8,0
	mov	TempWord+12,0
	lea	edi,tempword	;point to workspace
	mov	eax,[esi]	;move to where it can be worked on
	mov	tempdiv,eax
	mov	eax,[esi+4]	;sitto second word
	mov	tempdiv+4,eax
	mov	Tempdiv+8,0
	mov	TempDiv+12,0
	lea	esi,tempdiv	;point to workspace
	mov	ecx,64
@@MULTLP:	shr	b[esi+7],1
	rcr	b[esi+6],1
	rcr	b[esi+5],1
	rcr	b[esi+4],1
	rcr	b[esi+3],1
	rcr	b[esi+2],1
	rcr	b[esi+1],1
	rcr	b[esi+0],1
	jnc	@@NOADD
	mov	eax,[edi]
	add	resultbuffer,eax	;this SHOULD be JUST an ADD not ADC!
	mov	eax,[edi+4]
	adc	resultbuffer+4,eax	
	mov	eax,[edi+8]		;this can give you a 64 bit result!!!
	adc	resultbuffer+8,eax	
	mov	eax,[edi+12]
	adc	resultbuffer+12,eax	
@@NOADD:	mov	eax,[edi]
	add	[edi],eax	;this SHOULD be JUST an ADD not ADC!
	mov	eax,[edi+4]
	adc	[edi+4],eax
	mov	eax,[edi+8]
	adc	[edi+8],eax
	mov	eax,[edi+12]
	adc	[edi+12],eax
	loop	@@MULTLP
	ret
Mult64	endp


;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
DIV64	proc	near
	mov	temp,0	;init temp
	mov	temp+4,0	
	mov	ecx,64	;NUMBER OF BITS!!!!!!!
@@DIVLP:	rcl	b[esi+0],1
	rcl	b[esi+1],1
	rcl	b[esi+2],1
	rcl	b[esi+3],1
	rcl	b[esi+4],1
	rcl	b[esi+5],1
	rcl	b[esi+6],1
	rcl	b[esi+7],1
	mov	eax,temp	;get low 'bx'
	adc	temp,eax	;add to itself
	mov	eax,temp+4 
	adc	temp+4,eax
	mov	eax,[edi]
	sbb	temp,eax
	mov	eax,[edi+4]
	sbb	[temp+4],eax
	jnc	@@OKAY
	mov	eax,[edi]
	add	[temp],eax	;this SHOULD be JUST an ADD not ADC!
	mov	eax,[edi+4]
	adc	[temp+4],eax
	stc
@@OKAY:	cmc		;complement carry (diff if jumped from above)
	loop	@@DIVLP
	rcl	b[esi+0],1
	rcl	b[esi+1],1
	rcl	b[esi+2],1
	rcl	b[esi+3],1
	rcl	b[esi+4],1
	rcl	b[esi+5],1
	rcl	b[esi+6],1
	rcl	b[esi+7],1
	ret
Div64	endp


;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
ExpandLine	proc	near
	ret
ExpandLine	endp


;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
;
;Look through symbols for a match.
;
GetSymbolValue	proc	near
	;
	;Check if a register is being used.
	;
	cmp	b[esi+1],0
	jz	@@NotReg
	cmp	b[esi+2],0
	jz	@@Reg16
	cmp	b[esi+2]," "
	jz	@@Reg16
	cmp	b[esi+2],"+"
	jz	@@Reg16
	cmp	b[esi+2],"-"
	jz	@@Reg16
	cmp	b[esi+2],"*"
	jz	@@Reg16
	cmp	b[esi+2],"("
	jz	@@Reg16
	cmp	b[esi+2],")"
	jz	@@Reg16
	cmp	b[esi+2],"/"
	jz	@@Reg16
	cmp	b[esi+2],"&"
	jz	@@Reg16
	cmp	b[esi+2],"<"
	jz	@@Reg16
	cmp	b[esi+2],">"
	jz	@@Reg16
	;
	cmp	b[esi+3],0
	jz	@@Reg32
	cmp	b[esi+3]," "
	jz	@@Reg32
	cmp	b[esi+3],"+"
	jz	@@Reg32
	cmp	b[esi+3],"-"
	jz	@@Reg32
	cmp	b[esi+3],"*"
	jz	@@Reg32
	cmp	b[esi+3],"("
	jz	@@Reg32
	cmp	b[esi+3],")"
	jz	@@Reg32
	cmp	b[esi+3],"/"
	jz	@@Reg32
	cmp	b[esi+3],"&"
	jz	@@Reg32
	cmp	b[esi+3],"<"
	jz	@@Reg32
	cmp	b[esi+3],">"
	jz	@@Reg32
	;
	jmp	@@NotReg
	;
@@Reg16:	push	ebx
	mov	bl,b[esi+2]
	mov	b[esi+2],0
	pushm	ebx,esi
	call	WatchSegAtESI
	popm	ebx,esi
	mov	b[esi+2],bl
	pop	ebx
	jc	@@Reg16g
	call	WatchRegToValue
	mov	edx,eax
	xor	ecx,ecx
	jmp	@@GotReg
	;
@@Reg16g:	push	ebx
	mov	bl,b[esi+2]
	mov	b[esi+2],0
	pushm	ebx,esi
	call	WatchERegAtESI
	popm	ebx,esi
	mov	b[esi+2],bl
	pop	ebx
	jc	@@NotReg
	jmp	@@GetgReg
	;
@@Reg32:	push	ebx
	mov	bl,[esi+3]
	mov	b[esi+3],0
	pushm	ebx,esi
	call	WatchERegAtESI
	popm	ebx,esi
	mov	b[esi+3],bl
	pop	ebx
	jc	@@NotReg
@@GetgReg:	call	WatchRegToValue
	mov	ecx,eax
	xor	edx,edx
	;
@@GotReg:	clc
	ret
@@NotReg:	mov	edi,SymbolList
@@0:	cmp	d[edi],-1		;end of the list?
	jz	@@9
	pushm	esi,edi
	movzx	ecx,SymbolTLen[edi]
	add	edi,SymbolText
@@1:	lodsb
	call	UpperChar
	mov	ah,al
	mov	al,[edi]
	inc	edi
	call	UpperChar
	;
	cmp	al,ah
	jnz	@@3
	loop	@@1
	lodsb
	cmp	al,' '
	jz	@@4
	cmp	al,'+'
	jz	@@4
	cmp	al,'-'
	jz	@@4
	cmp	al,'*'
	jz	@@4
	cmp	al,'('
	jz	@@4
	cmp	al,')'
	jz	@@4
	cmp	al,'/'
	jz	@@4
	cmp	al,'&'
	jz	@@4
	cmp	al,'<'
	jz	@@4
	cmp	al,'>'
	jz	@@4
	or	al,al
	jz	@@4
@@3:	popm	esi,edi
	add	edi,SymbolNext[edi]
	jmp	@@0
@@4:	popm	esi,edi
	mov	ecx,SymbolDWord[edi]
	movzx	edx,SymbolSeg[edi]
	clc
	ret
@@9:	stc
	ret
GetSymbolValue	endp


	.data


EvaluateBuffer	db MaxLineLength dup (?)
EvaluateBuffer2 db MaxLineLength dup (?)
EvaluateBuffer3 db MaxLineLength dup (?)
VarSizeMask	dd 0,0
Temp	dd ?,?
ResultBuffer	dd 2*4 dup (0)
TempDiv	dd 2*4 dup (0)
TempWord	dd 2*4 dup (0)
ExtraSpace	dd 2*4 dup (0)
ProgramCounter	dd 0,0

⌨️ 快捷键说明

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