汇编学习(5)

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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值