memcmp 忽略奇数位置的字符

memcmp ignores characters at odd positions

我正在从 fasm(版本 1.71.51)代码调用 memcmp,我得到了奇怪的结果。

好像memcmp只比较奇数位置的字符。 代码:

format ELF64

section '.text' executable

    public _start

    extrn memcmp
    extrn exit

_start:
    push    rbp     ; Align the stack to 16 bytes

    mov     rdi, str1
    mov     rsi, str2
    mov     rdx, BUFF_LEN
    call    memcmp

    mov     rdi, rax
    call    exit
    pop     rbp


section '.data' writeable

str1                db '1509487271'
BUFF_LEN = $ - str1
str2                db '1509487273'

我是运行宁Ubuntu:

$ uname -a
Linux freedom 4.13.0-43-generic #48~16.04.1-Ubuntu SMP Thu May 17 12:56:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

为了assemble和运行上面的代码,我使用了以下命令:

$ fasm strange_memcmp.asm && ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64 strange_memcmp.o -o strange_memcmp.out && ./strange_memcmp.out 
flat assembler  version 1.71.51  (16384 kilobytes memory)
3 passes, 803 bytes.
$ echo $?
0

我预计 memcmp 将 return 不是 0 的值,因为缓冲区不同。

我尝试更改两个缓冲区。如果我设置:

str1 = '2509487271'
str2 = '1509487273'

我得到一个 return 值 1。

如果我设置:

str1 = '1409487271'
str2 = '1509487273'

我得到一个 return 值 0。 似乎 memcmp 只关心偶数位置的字符:0, 2, 4, ...等

我有一种奇怪的感觉,我错误地调用了memcmp。这可能与 Linux x64 abi 有关,但我无法找出问题所在。任何想法表示赞赏!

编辑:根据 Raymond 的回答,过程中的 return 值用掩码进行了运算。

为了修复上面的代码,我添加了两条指令:

neg     rax
sbb     rax, rax

在调用 memcmp 之后。

您将从 memcmp 返回的 64 位值直接传递给 exit,但是 the value is ANDed with 0xFF before being returned to the parentmemcmp 可能返回一个非零值,如 512,但系统将其截断为 0。