Re: [PATCH v7 2/5] x86/asm: add volatile, clobbers and zero-length check in inline memcmp

"H. Peter Anvin" <[email protected]>
Newsgroups org.xenproject.lists.xen-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 2026-07-24 16:57, H. Peter Anvin wrote:
> 
> And of course I got the comparison backwards (negative means a < b, thus we
> want a - b not b - a). Here is a fixed version.
> 
> int memcmp(const void *a, const void *b, size_t size)
> {
>         int diff;
> 
>         asm volatile("xor %0,%0 ;"      /* Sets ZF for the size = 0 case */
>                      "repe cmpsb ;"
>                      "jz 1f ;"          /* When size = 0 loading is unsafe */
>                      "movb -1(%1),%b0 ;"
>                      "movzbl -1(%2),%k2 ;"
>                      "sub %k2,%0 ;"
>                      "1:"
>                      : "=&q" (diff), "+D" (a), "+S" (b), "+c" (size)
>                      : : "memory");
>         return diff;
> }
> 
For extra credit, this version is even smaller in 16- and 32-bit mode, but
larger in 64-bit mode (because it depends on the order of the CMPSB operands,
which is the inverse of what the x86-64 ABI expects; swapping the order of "a"
and "b" and adding a cmc instruction improves the x86-64 size, but 64 bits is
not where the really tight code is...)

int memcmp(const void *a, const void *b, size_t size)
{
        int diff;

        asm volatile("xor %0,%0 ;"
                     "repe cmpsb ;"
                     "jz 1f ;"
                     "sbb %0,%0 ;"
                     "or $1,%0 ;"
                     "1:"
                     : "=&r" (diff), "+S" (a), "+D" (b), "+c" (size)
                     : : "memory");
        return diff;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.