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

📄 evaluate.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	.code


;==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==-==
;
;Evaluate the expresion in the buffer and produce a 32 bit value.
;
;First all numbers/labels are converted into 32 bit numbers, operators are
;just stored.
;
EvaluateData	proc	near
	lea	esi,EvaluateBuffer	;source data.
	call	ExpandLine
	;
	lea	esi,EvaluateBuffer	;source data.
	lea	edi,EvaluateBuffer2	;destination.
	mov	b[edi],-1		;pre-terminate it.
@@0:	;
	;skip spaces/tabs and insert any operators.
	;
	lodsb
	or	al,al
	jz	@@3		;go strieght to the end.
	cmp	al,' '		;skip spaces.
	jz	@@0
	cmp	al,9		;skip tabs.
	jz	@@0
	cmp	al,'*'
	jz	@@0_1
	;
	cmp	al,'$'
	jnz	@@NotPC0
	;
	cmp	b[esi],'0'		;followed by valid hex digit?
	jc	@@CheckAlpha1
	cmp	b[esi],'9'+1
	jc	@@NotPC0
	;
@@CheckAlpha1:	cmp	b[esi],'A'
	jc	@@CheckAlpha2
	cmp	b[esi],'F'+1
	jc	@@NotPC0
	;
@@CheckAlpha2:	cmp	b[esi],'a'
	jc	@@IsPC
	cmp	b[esi],'f'+1
	jc	@@NotPC0
	;
@@IsPC:	mov	ecx,ProgramCounter	;Get program counter.
	mov	edx,ProgramCounter+4
	mov	b[edi],0
	mov	[edi+1],ecx
	mov	d[edi+5],edx
	mov	b[edi+9],-1		;preset terminator.
	add	edi,9		;move to next field.
	jmp	@@0
	;
@@NotPC0:	cmp	al,'%'
	jz	@@0_0
	cmp	al,'"'
	jz	@@0_0
	cmp	al,"'"
	jz	@@0_0
	cmp	al,'-'
	jz	@@0_1
	cmp	al,'+'
	jz	@@0_1
	cmp	al,'/'
	jz	@@0_1
	cmp	al,'('
	jz	@@0_1
	cmp	al,')'
	jz	@@0_1
	cmp	al,'&'		;AND
	jz	@@0_1
	cmp	al,'|'		;OR
	jz	@@0_1
	;
	cmp	al,'<'
	jnz	@@NotLeft0
	cmp	b[esi],'<'
	jnz	@@9	;NotLeft0
	inc	esi		;skip second shift operator.
	jmp	@@0_1
	;
@@NotLeft0:	cmp	al,'>'
	jnz	@@NotRight0
	cmp	b[esi],'>'
	jnz	@@9	;NotRight0
	inc	esi
	jmp	@@0_1
	;
@@NotRight0:	jmp	@@0_0
@@0_1:	mov	b[edi],al		;store this operator.
	mov	b[edi+1],-1		;make sure its terminated.
	inc	edi		;step over it.
	jmp	@@0		;keep looking.
@@0_0:	dec	esi		;move back to last data.
	;
	;first decide if this is decimal,hex,binary,label or a string.
	;
	xor	dl,dl		;reset number flag.
	xor	ah,ah		;default to decimal.
	push	esi
@@1:	lodsb
	call	UpperChar
	cmp	al,'0'		;check for digits.
	jc	@@1_0		;/
	cmp	al,'9'+1		;/
	jnc	@@1_0		;/
	mov	dl,1		;flag some numbers found.
	jmp	@@1		;keep looking.
@@1_0:	or	al,al		;end of string?
	jz	@@2		;/
	cmp	al,'%'
	jz	@@1_3		;set flag for binary.
	cmp	al,'$'
	jnz	@@1_6		;check set flag for hex?
	;
	mov	al,[esi]
	cmp	al,'0'		;is it 0-9?
	jc	@@1_7		;/
	cmp	al,'9'+1		;/
	jc	@@1_2		;go for hex.
	call	UpperChar
	cmp	al,'A'		;is it A-F?
	jc	@@1_7		;/
	cmp	al,'F'+1		;/
	jc	@@1_2		;go for hex.
	;
@@1_7:	mov	al,[esi-1]		;get '$' again.
@@1_6:	cmp	al,"'"
	jz	@@1_4		;set string.
	cmp	al,'"'
	jz	@@1_4		;set string.
	cmp	al,'-'		;/
	jz	@@2		;/
	cmp	al,'+'		;/
	jz	@@2		;/
	cmp	al,'*'		;/
	jz	@@2		;/
	cmp	al,'/'		;/
	jz	@@2		;/
	cmp	al,'('		;/
	jz	@@2		;/
	cmp	al,')'		;/
	jz	@@2		;/
	cmp	al,'&'
	jz	@@2
	cmp	al,'|'
	jz	@@2
	cmp	al,'<'
	jz	@@2
	cmp	al,'>'
	jz	@@2
	cmp	al,' '		;/
	jz	@@2		;/
	or	dl,dl		;did we find any numbers first?
	jz	@@1_1		;assume its a label.
	cmp	al,'H'
	jz	@@1_2		;assume its hex.
	;
	;look to see if this is the end of the string.
	;
	cmp	b[esi],0
	jz	@@1_5
	cmp	b[esi],' '
	jz	@@1_5
	cmp	b[esi],9
	jz	@@1_5
	cmp	b[esi],'-'
	jz	@@1_5
	cmp	b[esi],'+'
	jz	@@1_5
	cmp	b[esi],'*'
	jz	@@1_5
	cmp	b[esi],'/'
	jz	@@1_5
	cmp	b[esi],'('
	jz	@@1_5
	cmp	b[esi],')'
	jz	@@1_5
	cmp	b[esi],'&'
	jz	@@1_5
	cmp	b[esi],'|'
	jz	@@1_5
	cmp	b[esi],'<'
	jz	@@1_5
	cmp	b[esi],'>'
	jz	@@1_5
	cmp	al,'A'
	jc	@@1_5
	cmp	al,'F'+1
	jc	@@1_2		;assume its hex at last.
@@1_5:	cmp	al,'B'
	jz	@@1_3		;assume its binary.
	pop	esi
@@1_1:	mov	ah,3		;set flag for label.
	jmp	@@2
@@1_2:	mov	ah,1		;set flag for hex.
	jmp	@@2
@@1_3:	mov	ah,2		;set flag for binary.
	jmp	@@2
@@1_4:	mov	ah,4		;set flag for string.
@@2:	pop	esi
	;
	;now convert this number into a useful format.
	;
	or	ah,ah		;Decimal?
	jz	@@DecGet
	dec	ah		;Hex?
	jz	@@HexGet
	dec	ah		;binary?
	jz	@@BinGet
	dec	ah
	jz	@@LabGet		;assume label then.
	jmp	@@StrGet		;get a string.
@@DecGet:	;
	;Convert this number from decimal to internal.
	;
	mov	b[edi],0		;Set number flag.
	inc	edi		;move to value field.
	push	edi
	xor	edx,edx
	xor	ecx,ecx		;reset accumulator.
	xor	edi,edi
@@DecGet_0:	lodsb
	or	al,al		;finished this number?
	jz	@@DecGet_1
	cmp	al,' '
	jz	@@DecGet_1
	cmp	al,9
	jz	@@DecGet_1
	cmp	al,'-'
	jz	@@DecGet_2
	cmp	al,'+'
	jz	@@DecGet_2
	cmp	al,'*'
	jz	@@DecGet_2
	cmp	al,'/'
	jz	@@DecGet_2
	cmp	al,'('
	jz	@@DecGet_2
	cmp	al,')'
	jz	@@DecGet_2
	cmp	al,'&'
	jz	@@DecGet_2
	cmp	al,'|'
	jz	@@DecGet_2
	cmp	al,'<'
	jz	@@DecGet_2
	cmp	al,'>'
	jz	@@DecGet_2
	sub	al,'0'		;make it a real number.
	movzx	ebp,al		;/
	shl	ecx,1
	rcl	edx,1
	rcl	edi,1
	mov	eax,ecx
	mov	ebx,edx
	shl	ecx,1
	rcl	edx,1
	rcl	edi,1
	shl	ecx,1
	rcl	edx,1
	rcl	edi,1
	add	ecx,eax
	adc	edx,ebx
	adc	edi,0
	add	ecx,ebp
	adc	edx,0
	adc	edi,0
	or	edi,edi
	jz	@@DecGet_0
	pop	edi
	jmp	@@13
@@DecGet_2:	dec	esi		;move back to operator.
@@DecGet_1:	pop	edi
	mov	[edi],ecx
	mov	[edi+4],edx
	mov	b[edi+8],-1		;preset terminator.
	add	edi,8		;move to next field.
	jmp	@@3
@@HexGet:	;
	;get a hex number.
	;
	mov	b[edi],0		;Set number flag.
	inc	edi		;move to value field.
	xor	edx,edx
	xor	ecx,ecx		;reset accumulator.
	xor	ebp,ebp
	cmp	b[esi],'$'		;$ at the start?
	jnz	@@HexGet_0
	inc	esi		;skip the $
@@HexGet_0:	lodsb
	call	UpperChar
	or	al,al		;finished this number?
	jz	@@HexGet_1
	cmp	al,'H'
	jz	@@HexGet_1
	cmp	al,' '
	jz	@@HexGet_1
	cmp	al,9
	jz	@@HexGet_1
	cmp	al,'-'
	jz	@@HexGet_2
	cmp	al,'+'
	jz	@@HexGet_2
	cmp	al,'*'
	jz	@@HexGet_2
	cmp	al,'/'
	jz	@@HexGet_2
	cmp	al,'('
	jz	@@HexGet_2
	cmp	al,')'
	jz	@@HexGet_2
	cmp	al,'&'
	jz	@@HexGet_2
	cmp	al,'|'
	jz	@@HexGet_2
	cmp	al,'<'
	jz	@@HexGet_2
	cmp	al,'>'
	jz	@@HexGet_2
	cmp	al,'0'
	jc	@@9		;bad value!
	cmp	al,'9'+1
	jc	@@HexGet_3
	cmp	al,'A'
	jc	@@9		;bad value!
	cmp	al,'F'+1
	jnc	@@9		;bad value.
@@HexGet_3:	cmp	al,'A'		;number or alpha?
	jc	@@HexGet_4
	sub	al,'A'		;make it real.
	add	al,10		;/
	jmp	@@HexGet_5
@@HexGet_4:	sub	al,'0'		;make it real.
@@HexGet_5:	cmp	bp,16+1
	jz	@@13
	inc	bp
	movzx	eax,al
	shl	ecx,1		;move current value up a nibble.
	rcl	edx,1
	shl	ecx,1
	rcl	edx,1
	shl	ecx,1
	rcl	edx,1
	shl	ecx,1
	rcl	edx,1
	add	ecx,eax
	adc	edx,0		;add in new value.
	jmp	@@HexGet_0		;keep looking.
@@HexGet_2:	dec	esi		;move back to operator.
@@HexGet_1:	mov	[edi],ecx
	mov	[edi+4],edx
	mov	b[edi+8],-1		;preset terminator.
	add	edi,8		;move to next field.
	jmp	@@3
@@BinGet:	;
	;get a binary number.
	;
	mov	b[edi],0		;Set number flag.
	inc	edi		;move to value field.
	xor	edx,edx
	xor	ecx,ecx		;reset accumulator.
	xor	ebp,ebp
	cmp	b[esi],'%'		;% at the start
	jnz	@@BinGet_0
	inc	esi		;step over the %
@@BinGet_0:	lodsb
	call	UpperChar
	or	al,al		;finished this number?
	jz	@@BinGet_1
	cmp	al,'B'
	jz	@@BinGet_1
	cmp	al,' '
	jz	@@BinGet_1
	cmp	al,9
	jz	@@BinGet_1
	cmp	al,'-'
	jz	@@BinGet_2
	cmp	al,'+'
	jz	@@BinGet_2
	cmp	al,'*'
	jz	@@BinGet_2
	cmp	al,'/'
	jz	@@BinGet_2
	cmp	al,'('
	jz	@@BinGet_2
	cmp	al,')'
	jz	@@BinGet_2
	cmp	al,'&'
	jz	@@BinGet_2
	cmp	al,'|'
	jz	@@BinGet_2
	cmp	al,'<'
	jz	@@BinGet_2
	cmp	al,'>'
	jz	@@BinGet_2
	cmp	al,'0'
	jc	@@9		;bad value!
	cmp	al,'1'+1
	jnc	@@9		;bad value.
	sub	al,'0'		;make it real.
	cmp	bp,64
	jz	@@13		;overflow error.
	inc	bp
	movzx	eax,al
	shl	ecx,1		;move current value up a bit.
	rcl	edx,1
	add	ecx,eax
	adc	edx,0		;add in new value.
	jmp	@@BinGet_0		;keep looking.
@@BinGet_2:	dec	esi		;move back to operator.
@@BinGet_1:	mov	[edi],ecx
	mov	[edi+4],edx
	mov	b[edi+8],-1		;preset terminator.
	add	edi,8		;move to next field.
	jmp	@@3
@@LabGet:	;
	;get a label value.
	;
	pushm	edi,esi
	call	GetSymbolValue	;get the value
	popm	edi,esi
	jc	@@12
	mov	b[edi],0
	inc	edi
	mov	[edi],ecx
	mov	[edi+4],edx
	mov	b[edi+8],-1
	add	edi,8		;next entry.
@@LabGet_0:	lodsb
	or	al,al
	jz	@@3		;end of this item.
	cmp	al,' '
	jz	@@LabGet_1
	cmp	al,9
	jz	@@LabGet_1
	cmp	al,'-'
	jz	@@LabGet_1
	cmp	al,'+'
	jz	@@LabGet_1
	cmp	al,'*'
	jz	@@LabGet_1
	cmp	al,'/'
	jz	@@LabGet_1
	cmp	al,'&'
	jz	@@LabGet_1
	cmp	al,'|'
	jz	@@LabGet_1
	cmp	al,'<'
	jz	@@LabGet_1
	cmp	al,'>'
	jz	@@LabGet_1
	cmp	al,'('
	jz	@@LabGet_1
	cmp	al,')'
	jnz	@@LabGet_0
@@LabGet_1:	dec	esi
	jmp	@@3
@@StrGet:	;
	;get a string value. If only one character then it will be put
	;in the buffer as a number. If more than 1 character then it
	;will be returned as is after quotes have been removed with CX
	;holding its length.
	;
	lodsb			;get quote type.
	xchg	ah,al
	cmp	b[esi+1],ah		;matching quote?
	jnz	@@StrGet_0		;copy the string.
	mov	b[edi],0		;set number flag.
	inc	edi
	lodsb			;get the character.
	movzx	eax,al
	mov	[edi],eax
	mov	d[edi+4],0		;set value in buffer.
	mov	b[edi+8],-1		;preset terminator.
	add	edi,8		;move to next field.
	lodsb			;get closing quote.
	jmp	@@3
	;
@@StrGet_0:	lea	edi,EvaluateBuffer	;copy over itself.
	push	ds
	pop	es
@@StrGet_1:	lodsb
	stosb
	cmp	al,ah		;matching quote?
	jz	@@StrGet_2		;end of string.
	or	al,al
	jz	@@10		;missing quote.
	jmp	@@StrGet_1
@@StrGet_2:	dec	edi
	mov	b[edi],0		;terminate it.
	sub	edi,offset EvaluateBuffer
	mov	ecx,edi		;set string length.
	mov	ax,-2		;set flags for a string.
	stc
	ret
@@3:	;
	;check if any more values to be converted.
	;
	cmp	b[esi-1],0		;end of this expresion?
	jnz	@@0
	sub	edi,Offset EvaluateBuffer2 ;get length of expresion.
	mov	ecx,edi		;/
	inc	ecx		;include terminator.
	lea	esi,EvaluateBuffer2
	lea	edi,EvaluateBuffer
	push	ds
	pop	es
	;
	;If buffer starts with an operator (+-() then insert a value of
	;zero at the start of the buffer.
	;
	mov	al,[esi]
	cmp	al,'-'
	jz	@@3_0
	cmp	al,'+'
	jz	@@3_0
	cmp	al,'&'
	jz	@@3_0
	cmp	al,'|'
	jz	@@3_0
	cmp	al,'<'
	jz	@@3_0
	cmp	al,'>'
	jz	@@3_0
	cmp	al,'*'
	jz	@@9
	cmp	al,'/'
	jz	@@9
	cmp	al,'('
	jz	@@3_1
	cmp	al,')'
	jz	@@9
	jmp	@@3_2
@@3_0:	mov	b[edi],0
	mov	d[edi+1],0
	mov	d[edi+5],0
	add	edi,9
	jmp	@@3_2
@@3_1:	mov	b[edi],0
	mov	d[edi+1],0
	mov	d[edi+5],0
	mov	b[edi+9],'+'
	add	edi,10
@@3_2:	rep	movsb		;copy it back into the buffer.
	;
	;now expand any parenthesis
	;
@@ParenLook:	lea	esi,EvaluateBuffer
	xor	dl,dl		;reset found flag.
	xor	dh,dh		;reset open flag.
@@ParenLook_0:	cmp	b[esi],-1		;end of the line?
	jz	@@ParenLook_1
	cmp	b[esi],'('		;opening?
	jz	@@ParenLook_4
	or	dh,dh
	jnz	@@b0
	cmp	b[esi],')'
	jz	@@14		;Missing opening parenthesis.
@@b0:	inc	esi
	cmp	b[esi-1],0		;number?
	jnz	@@ParenLook_0
	add	esi,8		;skip number.
	jmp	@@ParenLook_0		;keep looking.
@@ParenLook_4:	mov	dh,1
	mov	ebp,esi		;store this position.
	inc	esi		;move over it
	jmp	@@ParenLook_0		;find closing or next!
@@ParenLook_1:	or	dh,dh		;find anything?
	jz	@@ParenLook_10
	;
	mov	esi,ebp		;Opening pos again.
@@ParenLook_11: cmp	b[esi],-1
	jz	@@10		;missing closing.
	cmp	b[esi],')'
	jz	@@ParenLook_12
	inc	esi
	cmp	b[esi-1],0
	jnz	@@ParenLook_11
	add	esi,8
	jmp	@@ParenLook_11
@@ParenLook_12:	;
	;copy current line into a buffer and copy section between
	;parenthesis into normal buffer.
	;
	push	ds
	pop	es
	push	esi
	lea	esi,EvaluateBuffer
	lea	edi,EvaluateBuffer3
	mov	ecx,MaxLineLength/4
	rep	movsd		;copy it.
	pop	esi
	;
	;copy section between , BP+1 & SI-1 to start of buffer.
	;
	pushm	ebp,esi
	dec	esi
	inc	ebp
	sub	esi,ebp
	mov	ecx,esi
	inc	ecx
	mov	esi,ebp
	lea	edi,EvaluateBuffer
	sub	esi,offset EvaluateBuffer
	add	esi,offset EvaluateBuffer3 ;use 3 as source.
	;
	;If buffer starts with an operator (+-() then insert a value of
	;zero at the start of the buffer.
	;
	mov	al,[esi]
	cmp	al,'-'
	jz	@@P3_0
	cmp	al,'+'
	jz	@@P3_0
	cmp	al,'&'
	jz	@@P3_0
	cmp	al,'|'
	jz	@@P3_0
	cmp	al,'<'
	jz	@@9
	cmp	al,'>'
	jz	@@9
	cmp	al,'*'
	jz	@@9
	cmp	al,'/'
	jz	@@9
	cmp	al,'('
	jz	@@P3_1
	cmp	al,')'
	jz	@@9
	jmp	@@P3_2
@@P3_0:	mov	b[edi],0
	mov	d[edi+1],0
	mov	d[edi+5],0
	add	edi,9
	jmp	@@P3_2
@@P3_1:	mov	b[edi],0
	mov	d[edi+1],0

⌨️ 快捷键说明

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