让我们说我们有一串给定的字符
DataString DB 'AGIJKSZ', 0FFH ;
找到让我们说J
的最有效的程序是什么?
按时间效应,我的意思是最少的时钟滴答。
它是带有这些指令集的x86处理器:
MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, EM64T, VT-x, AES, AVX, AVX2, FMA3, TSX
我们假设字符串和搜索字符都可以更改,但只能通过编辑代码,我们总是在寻找单个字符。字符串是ASCII。字符串结尾标有FF
答案应该只是将EAX
设置为找到1
/找不到0
。
这是我能想到的
FindChar_1 PROC
MOV ESI, OFFSET DataString ;
SI
MOV AH, 'J' ;
Check_End:
CMP BYTE PTR [ESI], 0FFH ;
JE Not_Find ;
CMP AH, [ESI] ;
'DataString'
JE Got_Equal ;
ADD ESI, 1 ;
JMP Check_End ;
Got_Equal:
MOV DL, [ESI] ;
JMP Done
Not_Find:
MOV EAX,0 ;
RET ;
Done:
MOV EAX,1 ;
RET ;
FindChar_1 ENDP
编辑:
现在我意识到我应该提到的其他东西。我使用masm32所以我可以使用的指令仅限于非常基本的指令。
答案 0 :(得分:-1)
当您需要快速代码时,请避免内存访问,跳转和复杂指令。我会扫描字符串两次:一次找到结束标记,然后找到搜索到的字符:
FindChar_2 PROC
MOV ESI, OFFSET DataString
XOR EAX,EAX
XOR ECX,ECX
XOR EDX,EDX
NOT EAX ; Let AL=EndOfString marker.
NOT ECX ; Let ECX=Max.integer.
MOV EDI,ESI
CLD
REPNE SCASB ; ECX -= String size (-9 in this example).
NOT ECX ; ECX= String size (8).
MOV AL,'J' ; The searched needle.
MOV EDI,ESI ; Restore the haystack pointer.
REPNE SCASB ; The actual search.
; It returns CF if not found, because the needle is below 0FFH.
CMC ; Invert the logic.
MOV EAX,EDX ; Return false.
ADC EAX,EDX ; Return true if found.
RET
FindChar_2 ENDP