【发布时间】:2021-10-04 17:46:53
【问题描述】:
所以我用我在各个站点收集的知识编写了这段代码,我认为有一种优化的方法可以做到这一点,而无需推送和弹出堆栈内存上的寄存器,但我不知道该怎么做。 这是我的代码
comparing proc
MOV CX, SIZEOF vec2 ;The size of the substring
DEC CX
MOV DX, SIZEOF vec1 ; The size of the String
LEA SI, vec1 ; The String
LEA DI, vec2 ; The substring
FIND_FIRST:
MOV AL, [SI]; storing the ascii value of current character of mainstring
MOV AH, [DI]; storing the ascii value of current character of substring
CMP AL,AH; comparing both character
JE FITTING; if we find it we try to find the whole substring
JNE NEXT
NEXT:
INC SI; We go to the next char
DEC DX; And the size of the string decreased
JE N_FINDED
JMP FIND_FIRST
FITTING:
CLD
PUSH CX ; I push this register because in the instruction REPE CMPSB
PUSH SI ; They change.
PUSH DI
REPE CMPSB
JNE N_FITTING
JE FINDED
N_FITTING:
POP DI
POP SI
POP CX
JMP NEXT ; if the complete substring doesn't fit we go to the next char
FINDED:
POP DI
POP SI
POP CX
MOV AL, 0001H; substring found
JMP RETURN
N_FINDED:
MOV AL, 0000H; substring not found
RETURN:
ret
comparing endp
【问题讨论】:
-
对于它的价值,“find”的仰卧是“found”。
-
在微优化方面,您可以将
cld和push/pop提升到循环之外,只保存/恢复整个功能。此外,在开始慢速rep cmpsb之前扫描匹配的第一个字节会很有意义。 (事实上,在现代 CPU 上,rep cmps和rep scas没有使用快速字符串微码进行优化,只有rep stos和rep movs,因此通常完全避免使用它们;see this example 旧版本的 GCC在-O1处内联rep cmpsb,对于大型strlen 速度较慢,尤其是与SSE2 SIMD 相比。 -
在算法优化方面,对于长子串“needle”,有一些算法可以做得比仅仅将“haystack”的每个字节作为可能的起点更好。一个著名的是博耶-摩尔。 en.wikipedia.org/wiki/…。或者在不真正改变蛮力策略的情况下,使用
cmp [si], ax或其他东西来检查2个匹配字节,并进行重叠的未对齐字比较。您是针对实际 8086 还是针对 16 位模式下的现代 x86 进行优化?还是介于 386 或 Pentium 之间?
标签: string assembly masm strstr