C代码中的SSE2指令

时间:2012-02-28 03:06:20

标签: c gcc assembly sse

我正在尝试对c代码进行逆向工程,但这部分程序我真的不明白。我知道这是SSE扩展的一部分。但是,有些东西与我在x86指令中习惯的不同。

static int sad16_sse2(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
{
    int ret;
    __asm__ volatile(
        "pxor %%xmm6, %%xmm6            \n\t"
        ASMALIGN(4)
        "1:                             \n\t"
        "movdqu (%1), %%xmm0            \n\t"
        "movdqu (%1, %3), %%xmm1        \n\t"
        "psadbw (%2), %%xmm0            \n\t"
        "psadbw (%2, %3), %%xmm1        \n\t"
        "paddw %%xmm0, %%xmm6           \n\t"
        "paddw %%xmm1, %%xmm6           \n\t"
        "lea (%1,%3,2), %1              \n\t"
        "lea (%2,%3,2), %2              \n\t"
        "sub $2, %0                     \n\t"
        " jg 1b                         \n\t"
        : "+r" (h), "+r" (blk1), "+r" (blk2)
        : "r" ((x86_reg)stride)
    );
    __asm__ volatile(
        "movhlps %%xmm6, %%xmm0         \n\t"
        "paddw   %%xmm0, %%xmm6         \n\t"
        "movd    %%xmm6, %0             \n\t"
        : "=r"(ret)
    );
    return ret;
}

%1,%2和%3是什么?什么(%1,%2,%3)是什么意思? “+ r”,“ - r”,“= r”是什么意思?

2 个答案:

答案 0 :(得分:2)

您需要查看此GCC Inline Asssembly HOWTO

百分号是指令操作数。

答案 1 :(得分:0)

内联汇编程序的工作方式与宏预处理程序类似。只有一个前导百分比的操作数被输入参数替换为参数列表中出现的顺序,在这种情况下:

%0    h                output, register, r/w
%1    blk1             output, register, r/w
%2    blk2             output, register, r/w
%3    (x86_reg)stride  input, register, read only

参数是正常的C表达式。它们可以通过“约束”进一步指定,在这种情况下,“r”表示该值应该在寄存器中,与作为存储器操作数的“m”相对。约束修饰符“= r”使其成为只写操作数,“+ r”是读写操作数,“r”和正常读操作数。

在第一次冒号之后,输出操作数出现,在第二次输入操作数之后,在可选的第三次之后出现修饰寄存器。

因此,指令序列计算blk1blk2的每个字节的绝对差值之和。这发生在16字节块中,因此如果stride为16,则块是连续的,否则存在漏洞。每条指令出现两次,因为完成了一些最小的循环展开,h参数是要处理的32字节块的数量。第二个asm块似乎没用,因为psadbw指令仅在目标寄存器的低16位汇总。 (你省略了一些代码吗?)