1

我正在尝试比较 2 个字符串以查看它们在汇编中是否相等。区分大小写。它们是从 cpp 包装器传入的。这是我到目前为止所拥有的:

我将一个字符串存储在 esi 中,另一个存储在 edi 中:

LOOP:
    mov al, [esi + edx*4]
    mov bl, [edi + edx*4]
    sub al, bl
    INC edx
    je LOOP
    jmp END_LOOP  ; if it's not equal, do some stuff at the end

END_LOOP:

我究竟做错了什么?它如何知道我何时位于 char 数组的末尾?

4

2 回答 2

4

由于这些字符串是 C++ 字符串,而且我猜它们是由chars 而不是宽字符组成的,所以每个字符的大小都是一个字节,所以你不应该将索引寄存器乘以edx4。此外,你不能edx紧接之前递增您的je指示,因为只有跳转是 edx 已被撞到零。

最后,字符串以 0 字节结尾。因此,您正在寻找albl为零以知道何时停止循环。

您可以按照以下几行修改您的代码:

    xor edx, edx         ; make sure edx is 0 to start with
LOOP:
    mov al, [esi + edx]
    mov bl, [edi + edx]
    inc edx              ; prepare for next char
    cmp al, bl           ; compare two current characters
    jne DIFFERENT        ; not equal, get out, you are DONE!
    cmp al, 0            ; equal so far, are you at the end?
    je SAME              ; got to end of both strings, you're good, get out
    jmp LOOP             ; okay well they agree so far, go to next char
DIFFERENT:
    ; Do what you need to do for the strings being different
    ;
    ;
    jmp DONE
SAME:
    ; Do what you need to do for the strings being the same
    ;
    ;
DONE:

但是我建议只在 x86 中搜索字符串比较。有一个cmps指令。如果您愿意,您甚至可以安排调用该strncmp函数。有几种方法可以解决这个问题。

于 2012-07-26T06:44:51.173 回答
2

嗯...为什么是“edx * 4”?看起来你只会比较每四个字符。“sub”设置标志与“cmp”相同。不同之处在于“sub”覆盖了 al,而“cmp”只是设置了标志,而将两个寄存器都放在一边。任何一个都应该适合你。

然后你“inc edx”。这会再次设置标志,并且您想使用标志来查看字符串是否相等!“inc”是一种“有趣”的指令,因为它设置了大多数标志,但不考虑进位标志。这对你没有帮助。“inc”需要完成,但不是在 cmp/sub 和条件跳转之间!

除非我弄错了,否则 C 将“字符串”定义为以零结尾的 char 数组,因此假设您的字符串以零结尾可能是安全的。另一种方法是将长度作为另一个参数传递。

Ray 刚刚发布了一些很好的代码,应该可以解决你的问题,所以我会停下来......

最好的,弗兰克

于 2012-07-26T07:18:40.740 回答