我从 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

为了组装和运行上面的代码,我使用以下命令:
$ 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 将返回一个不是 0 的值,因为缓冲区不同。

我尝试更改两个缓冲区。如果我设置:
str1 = '2509487271'
str2 = '1509487273'

我获得了 1 的返回值。

如果我设置:
str1 = '1409487271'
str2 = '1509487273'

我得到的返回值为 0。
似乎 memcmp 只关心偶数位置的字符:0、2、4 等。

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

编辑:根据 Raymond 的回答,过程的返回值带有掩码。

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

在调用 memcmp 之后。

最佳答案

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

关于assembly - memcmp 忽略奇数位置的字符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50889769/

10-11 16:38