查找目的字符串中第一次出现的源串,并用rax返回其位置,查找成功则zf置1,失败则zf为0且rax为0

没有见过C中的Strfind是什么样的汇编代码,如有雷同纯属巧合

在这里插入代码片
ExitProcess proto
Str_find    proto
Str_length  proto
Find        proto
.data
target byte "118ABABCD655",0
source byte "ABCD",0
pos    qword ?
.code
main proc 
  mov rsi,offset target ;放入目的串
  mov rdi,offset source ;放入源串
  call Str_find
  jnz notFound
  mov pos,rax
notFound:
  mov ecx,0
  call ExitProcess
main endp
Str_find proc uses rbx rcx rdx rbp rsi rdi r8 r9 r10 r11 r12
;如果目的串中有与源串相同的部分,rax返回源串首字符在目的串中的位置,零标志位置1。如果没有则rax为0,零标志位为0。
  mov rbp,rsp ;保存基址
  mov rcx,rsi
  call Str_length
  mov r10,rax
  mov r8,0;设置计数器
  mov rdx,rdi;保存源串首字符位置
  mov rcx,rdi
  call Str_length
  mov r11,rax
  call Find
  mov rcx,r12 ;用n作为循环计数器
  test rcx,rcx
  jz L4
  inc rsi;预调rsi
L2: 
  dec rsi;减去L8中找到首字符后不一样的字符后rsi加的1
  push rcx
  mov bl,[rdi]
  mov rcx,r10
L6:;遍历目的字符串寻找与源字符串首字符相同的字符
  mov al,byte ptr [rsi]
  inc rsi
  inc r8;计数器记录找到首字母前遍历字符的个数
  cmp al,bl
  loopne L6
  dec rsi;减去L6中找到目的首字符后多余的加1
  mov rcx,r11
L8:;对比两字符串源字符串首字符后的几个字符
  mov bl,byte ptr [rdi]
  mov al,byte ptr [rsi]
  inc rsi
  inc rdi
  inc r8
  cmp al,bl
  loope L8
  jz L3 
  sub r8,2;减去L8中首尾计数器多加的两次1
  mov rdi,rdx;rdi复位
  cmp al,bl;对比上述几个字符的最后一个字符
  je L8 ;相等后后重对比
  pop rcx
  loop L2
  jmp L4
L3:
  sub r8,4;减去匹配成功后r8多加的源串字符数和L8中减去的1
L5:
  mov rax,r8
  mov rbx,0
  test rbx,rbx;零标志位置1
  jmp L1
L4:
  mov rax,0
  test rsi,rsi;零标志位置0
L1:
  mov rsp,rbp;恢复基址
  ret
Str_find endp
Find proc uses rsi rdi rax rbx;查找一共有多少源串首字母(用n表示)
  mov r12,0
  mov rcx,r10
L1:          
  mov al,[rsi]
  mov bl,[rdi]
  inc rsi
  cmp al,bl
  je L3
L2:
  loop L1
  jmp L4
L3:
  inc r12
  jmp L2
L4:
  ret
Find endp
end

因为英特尔处理器之前运行loope和loopne指令时在判定为否时会再进行一次循环,所以出现了匹配成功后r8的值无法确定和冗余代码的问题,现在系统更新后已经解决

ExitProcess proto
Str_find    proto
Str_length  proto
Find        proto
.data
target byte "AAAAAAAAAABCABCDAAAAA",0
source byte "ABCD",0
pos    qword ?
.code
main proc 
  mov rsi,offset target ;放入目的串
  mov rdi,offset source ;放入源串
  call Str_find
  jnz notFound
  mov pos,rax
notFound:
  mov ecx,0
  call ExitProcess
main endp
Str_find proc uses rbx rcx rdx rbp rsi rdi r8 r9 r10 r11 r12
;如果目的串中有与源串相同的部分,rax返回源串首字符在目的串中的位置,零标志位置1。如果没有则rax为0,零标志位为0。
  mov rbp,rsp ;保存基址
  mov rcx,rsi
  call Str_length
  mov r10,rax
  mov r8,0;设置计数器
  mov rdx,rdi;保存源串首字符位置
  mov rcx,rdi
  call Str_length
  mov r11,rax
  call Find
  mov rcx,r12 ;用n作为循环计数器
  test rcx,rcx
  jz L4
  inc rsi;预调rsi
L2: 
  dec rsi;减去L8中找到首字符后不一样的字符后rsi加的1
  push rcx
  mov bl,[rdi]
  mov rcx,r10
L6:;遍历目的字符串寻找与源字符串首字符相同的字符
  mov al,byte ptr [rsi]
  inc rsi
  inc r8;计数器记录找到首字母前遍历字符的个数
  cmp al,bl
  loopne L6
  dec rsi;减去L6中找到目的首字符后多余的加1
  mov rcx,r11
L8:;对比两字符串源字符串首字符后的几个字符
  mov bl,byte ptr [rdi]
  mov al,byte ptr [rsi]
  inc rsi
  inc rdi
  inc r8
  cmp al,bl
  loope L8
  jz L3 
  sub r8,2;减去L8中首尾计数器多加的两次1
  mov rdi,rdx;rdi复位
  pop rcx
  loop L2
  jmp L4
L3:
  inc r11
  sub r8,r11;减去匹配成功后r8多加的源串字符数和L8中减去的1
L5:
  mov rax,r8
  mov rbx,0
  test rbx,rbx;零标志位置1
  jmp L1
L4:
  mov rax,0
  test rsi,rsi;零标志位置0
L1:
  mov rsp,rbp
  ret
Str_find endp
Find proc uses rsi rdi rax rbx;查找一共有多少源串首字母(用n表示)
  mov r12,0
  mov rcx,r10
L1:          
  mov al,[rsi]
  mov bl,[rdi]
  inc rsi
  cmp al,bl
  je L3
L2:
  loop L1
  jmp L4
L3:
  inc r12
  jmp L2
L4:
  ret
Find endp
end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值