;功能:查找32位之间的赋值语句是否有语法错误,如果没有就输出,如果有就输出错误;
;为了减少情况判断;特意规定mov后面的第一个参数必须为寄存器。
;赋值语句中32位赋值和16位、8位等情况的赋值语法完全相同,
;所以这里只判断32位赋值的情况,并且假设这里的内存操作数一定是写对的
;用str1来存储要判断的语句,用str2来存储内存操作数的类型。
include irvine32.inc
.data
i dword 1;
c1 byte "改语法不正确:",0;
c2 byte "相等",0;
c3 byte "该语法正确",0;
c4 byte "寄存器的名字写错了:",0;
c5 byte "内存操作数错了:",0;
c6 byte "mov写错:",0;
c7 byte "“,”写错了:",0;
str1 byte "mvo edx,offset sdr",0
str2 byte "sdr qword ?",0;
str3 byte 20 dup(?),0;
k1 byte "mov",0;
k2 byte "eax,ebx,ecx,edx,ebp,esp,esi,edi";
k3 byte "offset ",0;
k4 byte "dword ptr ",0;
.code
main proc
;判断“,”是否正确;
mov edi,offset str3;
mov esi,offset str1;
add esi,7;
movsb;
mov al,byte ptr str3;
cmp al,',';
jne quit1 ;不是‘,’则报错;
;判断mov;
cld; 先取前三个字符;
mov edi,offset str3;
mov esi,offset str1;
mov ecx,3;
rep movsb;
cld; 判断前三个字符是否为"mov"
mov esi,offset k1;
mov edi,offset str3;
mov ecx,3;
repe cmpsb;
je L1;
jmp quit2 ;不是mov报错
L1:
;判断第一个参数是否寄存器;
;取中间3个字符
mov edi,offset str3;
mov esi,offset str1;
add esi,4;
mov ecx,3;
rep movsb;
mov edx,offset str3;
mov esi,offset k2;
L2: ;循环判断是否是寄存器
cld;
cmp i,9;
je L3; ;判断完了还不是寄存器,跳出循环;
push esi;
mov edi,offset str3;
mov ecx,3;
repe cmpsb;
je L3; 判断出是寄存器了,跳出循环
pop esi;
inc i;
add esi,4;
jmp L2;
L3:
cmp i,9; 判断跳出循环的原因是什么,是找到了还是没找到;
je quit3; 没找到报错
mov eax,lengthof str1
sub eax,9;
cmp eax,3;
jne n1; 判断第二个数如果不是3个字符,则应该为内存操作数;
;16、8的寄存器的情况不予考虑。
;判断第2个数是不是寄存器
mov i,1;
mov edi,offset str3;
mov esi,offset str1;
add esi,8;
mov ecx,3;
rep movsb;
mov esi,offset k2;
L4:
cld;
cmp i,9;
je L5;
push esi;
mov edi,offset str3;
mov ecx,3;
repe cmpsb;
je L5;
pop esi;
inc i;
add esi,4;
jmp L4;
L5:
cmp i,9;
je n1
;第二变量的变量名长度为三个字节可能是32位寄存器也可能是内存操作数
mov edx,offset c3;
call writestring;
call crlf;
jmp next;
;判断是否是取地址;
n1:
mov edi,offset str3;
mov esi,offset str1;
add esi,8;
mov ecx,7;
rep movsb;
cld; 判断
mov esi,offset k3;
mov edi,offset str3;
mov ecx,7;
repe cmpsb;
jne n2;
mov eax,lengthof str1; 判断后面有没有内存操作数
cmp eax,16;
je quit4;
mov edx,offset c3;
call writestring;
call crlf;
jmp next;
;判断是否是类型转换成32位的可是必须是高的才能转成低的;
n2:
mov edi,offset str3;
mov esi,offset str1;
add esi,8;
mov ecx,10;
rep movsb;
;mov edx,offset str3;
;call writestring;
;call crlf;
cld; 判断
mov esi,offset k4;
mov edi,offset str3;
mov ecx,10;
repe cmpsb;
jne n3;
mov eax,lengthof str1; 判断后面有没有内存操作数
cmp eax,19;
je quit4;
mov eax,lengthof str1; 判断后面的内存操作数是不是不低于32位的;
sub eax,18;
;call writeint;
;call crlf;
mov esi,offset str2;
add esi,eax;
mov al, byte ptr [esi];
cmp al,'d';
je b1;
cmp al,'q';
jne quit4;
b1:
mov edx,offset c3;
call writestring;
call crlf;
jmp next;
n3:
;判断如果有常量的字节数是否为32位;
mov ebx,lengthof str1;
sub ebx,8;
mov edi,offset str1;
add edi,8;
mov al,' ';
mov ecx,ebx
repne scasb; 扫描是否变量名中含有空格,有的话,报错;
jz quit4;
mov ebx,lengthof str2;
mov eax,lengthof str1
sub eax,8;
cmp ebx,eax;
jna quit4; 变量名的长度比定义的还长,报错;
mov edi,offset str3;
mov esi,offset str2;
add esi,eax;
movsb;
mov al, byte ptr str3;
cmp al,'d';
jne quit4;
mov edx,offset c3;
call writestring;
call crlf;
jmp next;
quit1:;","不对时,输出提示语;
mov edx,offset c7;
call writestring;
call crlf;
jmp next;
quit2:;"mov"不对时,输出提示语;
mov edx,offset c6;
call writestring;
call crlf;
jmp next;
quit3:;寄存器不对时,输出提示语;
mov edx,offset c4;
call writestring;
call crlf;
jmp next;
quit4:;内存操作数不对时,输出提示语;
mov edx,offset c5;
call writestring;
call crlf;
next:
exit
main endp
end main