1.统计字符串长度,将结果按十六进制字符串格式输出
要求:使用重复前缀和条件设置指令
char s_23[81];
char len[81];
printf("s = ");
scanf("%s", s_23);
_asm{
lea ecx, s_23 //获取字符串存储地址
call s_len
mov ebx, eax //将长度值存入ebx
//转化为十六进制字符串
lea edi, len
mov edx, 8
L23:
mov ecx, 0xf0000000
and ecx, ebx //取出一个十六进制数
shl ebx, 4 //准备好下一个十六进制数
shr ecx, 28 //将取出的十六进制数移至低四位
call H2ASCLL //转化为对应ascll码值
stosb //装入字符
dec edx
jne L23
//设置终止符
xor eax, eax
stosb
}
printf("s的长度为(十六进制):%s H\n", len);
//子程序s_len
//功能:获取字符串长度
//参数:ecx 字符串存储地址
//返回值: eax 字符串长度
s_len:
mov edi, ecx
push ecx //保护ecx
xor eax, eax //置零eax,即终止符'\0'
mov ecx, 0xffffffff
repnz scasb
not ecx
dec ecx //减去终止符的长度
mov eax, ecx //设置返回值
pop ecx
ret
//子程序H2ASCLL
//功能:利用条件设置指令把一位十六进制数转化为对应ascll码值
//参数:ecx 待处理数
//返回值:eax ascll码值
H2ASCLL:
push ebx
push edx
mov eax, ecx
//检测第3位和第1位是否为1
bt cx, 3
setc bl
bt cx, 1
setc dl
and bl, dl
je is_hex_number
add eax, 7
is_hex_number:
add eax, 48
//平衡堆栈
pop edx
pop ebx
ret
2.输入两个十六进制数字符串,转化为数,求和、差,再按十进制数字符串格式输出
char s_hex1[81], s_hex2[81];
char s_sum[81], s_diff[81];
printf("输入两个十六进制数字符串\n");
printf("hex1 = ");
scanf("%s", s_hex1);
printf("hex2 = ");
scanf("%s", s_hex2);
int a4,b;
_asm{
lea ecx, s_hex1
call Hstr2D_plus
mov edi, eax
mov a4, edi
lea ecx, s_hex2
call Hstr2D_plus
mov esi, eax
mov b,esi
//求和
add eax, edi
mov ecx, eax
lea edx, s_sum
call D2Hstr
//求差
mov eax, edi
sub eax, esi
test eax, eax
jge L24
neg eax
L24:
mov ecx, eax
lea edx, s_diff
call D2Hstr
}
printf("和为:%s H\n", s_sum);
printf("差为:%s H\n", s_diff);
//子程序Hstr2D_plus
//功能:将十六进制字符串转化为数据,并考虑前导空格
//参数:ecx 字符串存储地址
//返回值:eax 转化后的数据
Hstr2D_plus:
push ebx
push edx
push edi
xor eax, eax //eax置零
mov edi, 16 //乘数为16
//删除前导空格
is_blank:
lodsb
mov cl, al
call judge_hex
test eax, eax
cmp cl, ' '
je is_blank
dec esi
//开始转化
L_Hstr2D_plus:
mov bl, [ecx] //取下一个字符
inc ecx
test bl, bl //若为终止符,结束循环
je end_Hstr2D_plus
mul edi //乘16
//将十六进制字符转化为对应数字值
sub bl, 48
cmp bl, 10
jb not_char
sub bl, 7
not_char:
movzx ebx, bl
add eax, ebx
jmp L_Hstr2D_plus
end_Hstr2D_plus:
//平衡堆栈
pop edi
pop edx
pop ebx
ret
//子程序judge_hex
//功能:判定字符是否为十六进制字符
//参数:ecx 待处理字符
//返回值:eax 判定结果,1表示是十六进制字符,0表示不是
judge_hex:
xor eax, eax //eax置零
cmp cl, '0'
jb end_judge
cmp cl, '9'
jbe is_hex
cmp cl, 'A'
jb end_judge
cmp cl, 'Z'
jbe is_hex
cmp cl, 'a'
jb end_judge
cmp cl, 'z'
ja end_judge
is_hex:
inc eax
end_judge:
ret
//子程序D2Hstr
//功能:将数据转化为十六进制字符串
//参数:ecx 待转化数据 edx 字符串存储地址
D2Hstr:
//初始化
mov ebx, ecx
push edi
mov edi, edx
mov ecx, 8
L:
mov eax, 0xf0000000
and eax, ebx //取出高4位
shr eax, 28
shl ebx, 4
cmp al, 10 //判断对应十六进制是数字还是字母
jl Number_D2Hstr
add al, 7 //如果对应十六进制是字母,则多加7
Number_D2Hstr:
add al, 48 //转化为对应ascll码值
stosb
loop L
mov eax, 0
stosb
pop edi
ret
3.输入四个整数,视为128位数据,求1的个数(位操作)
unsigned int a[5];
int count;
printf("输入四个整数:");
for(int i=0; i<4; i++)
scanf("%u", &a[i]);
_asm{
lea esi, a
xor edx, edx //edx置零
xor ebx, ebx //ebx置零
mov ecx, 16 //4*32/8=16
L25_out:
lodsb
push ecx //保护外层循环计数器
mov ecx, 8
L25_in:
bt ax, 0 //检测位
setc bl
add edx, ebx //统计是否为1
shr al, 1
loop L25_in
pop ecx //恢复外层循环计数器
loop L25_out
mov count, edx
}
printf("1的个数为:%d\n", count);
4.输入一个字符串,视为位串,求连续为0的最大长度(位操作)
char s_26[81];
unsigned int n;
printf("输入任意字符串:");
scanf("%s", s_26);
_asm{
lea esi, s_26
xor edx, edx //edx置零
xor ebx, ebx //ebx置零
L26_out:
lodsb
test al, al
je END_26
mov ecx, 8
L26_in:
bt ax, 0
jc not_zero
inc ebx
jmp next
not_zero:
cmp ebx, edx
jb is_shorter1
mov edx, ebx
is_shorter1:
xor ebx, ebx //ebx置零
next:
shr al, 1
loop L26_in
jmp L26_out
END_26:
cmp ebx, edx
jb is_shorter2
mov edx, ebx
is_shorter2:
mov n, edx
}
printf("连续为0的最大长度为: %d", n);