字符串处理指令:
lods: 从[esi]传给累加器,根据df和操作字长调整esi
stos: 从累加器传给[edi],根据df和操作字长调整edi
movs: 直接从[esi]传到[edi],,根据df和操作字长调整esi和edi
scas: 累加器与[edi]相减比较,不影响操作数,影响标志位
cmps: [esi]与[edi]相减比较,不影响操作数,影响标志位
重复前缀:
rep: 若ecx=0,结束重复,否则ecx减1,重复操作
repz/repe: 若ecx=0或zf=0,结束重复,否则ecx减1,重复操作
repnz/repne: 若ecx=0或zf=1,结束重复,否则ecx减1,重复操作
1.字符串拼接
char s1[81], s2[81], s3[81];
printf("s1 = ");
scanf("%s", s1);
printf("s2 = ");
scanf("%s", s2);
_asm{
lea edi, s3
lea esi, s1 //獲取s1存儲地址
L1:
movsb
cmp [esi-1], 0
jne L1
dec edi //刪除s1的終止符
lea esi, s2 //獲取s2存儲地址
L2:
movsb
cmp [esi-1], 0
jne L2
}
printf("s1 + s2 = %s\n", s3);
2.消除字符串标点
char s1[81], s2[81];
printf("s = ");
scanf("%s", s1);
_asm{
lea esi, s1
lea edi, s2
lea edx, judge
R:
lodsb
test al, al
je END
push ebp
push eax
mov ebp, esp
call edx
test eax, eax
pop eax
pop ebp
je L //若判定為標點,則不傳送該字符
stosb
L:
jmp R
END:
mov al, 0 //添加終止符
stosb
}
printf("消除標點后s = %s\n", s2);
return;
_asm{
judge:
push ebx
mov eax, 1
mov bl, [ebp]
cmp bl, 32
jl f
cmp bl, 47
jle is_p
cmp bl, 58
jl f
cmp bl, 64
jle is_p
cmp bl, 91
jl f
cmp bl, 96
jle is_p
cmp bl, 123
jl f
cmp bl, 126
jle is_p
jmp f
is_p:
mov eax, 0
f:
pop ebx
ret
}
note:
32-47 标点1区(32是空格)
58-64 标点2区
91-96 标点3区
123-126 标点4区
48-57 数字
65-90 大写字母
97-122 小写字母
0-31 是打印控制
127是删除
3.求s1中首个出现在s2中的字符的位置
int result;
char s1[81], s2[81];
printf("s1 = ");
scanf("%s", s1);
printf("s2 = ");
scanf("%s", s2);
_asm{
//統計s2長度
lea esi, s2
mov edx, -1
R:
inc edx
lodsb
test al, al
jne R
//初始化
lea esi, s1
mov ebx, -1
L:
lodsb //裝入下一個s1字符
inc ebx //位置加一
test al, al
je END1
mov ecx, edx//初始化ecx為s2長度
lea edi, s2
repne scasb
je END2 //如果ZF=0,説明找到相同字符
jmp L
END1:
mov ebx, -1 //設置位置為-1
END2:
mov result, ebx
}
printf("s1中首個出現在s2的字符位置為 %d\n", result);
4.求s1首次出现s2的位置
int result;
char s1[81], s2[81];
printf("s1 = ");
scanf("%s", s1);
printf("s2 = ");
scanf("%s", s2);
_asm{
//統計s2長度
lea esi, s2
mov edx, -1
R:
inc edx
lodsb
test al, al
jne R
//初始化
lea esi, s1
mov ebx, -1
dec esi
L:
inc esi
inc ebx //位置加一
mov al, [esi]
test al, al
je END1
mov ecx, edx//初始化ecx為s2長度
push esi //保存s1開始匹配位置
lea edi, s2
repe cmpsb //匹配s1子串和s2
pop esi //恢復s1開始匹配位置
jne L
cmp ecx, 0
je END2 //如果ecx=0,説明匹配到和s2相同的子串
END1:
mov ebx, -1 //設置位置為-1
END2:
mov result, ebx
}
printf("s1中首次出現s2位置為 %d\n", result);
5.生成由n个字符c形成的字符串
char c;
int n;
char s[81];
printf("ch = ");
scanf("%c", &c);
printf("n = ");
scanf("%d", &n);
_asm{
mov al, c
mov ecx, n
lea edi, s
lea edx, cstring
//參數壓棧
push ebp
push eax
push ecx
push edi
mov ebp, esp
call edx //調用函數生成字符串
pop ebp //恢復棧幀
}
printf("生成的字符串為: %s\n", s);
return;
_asm{
cstring:
mov edi, [ebp] //獲取參數s
mov ecx, [ebp+4] //獲取參數n
mov al, [ebp+8] //獲取參數c
rep stosb //存儲n此字符c
mov al, 0
stosb //存儲終止符
ret 12
}
内联汇编关键字与外部定义的变量重名时,会优先认定为前者