没有见过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