📄 evaluate.asm
字号:
.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 + -