【问题标题】:SSE2 instruction in C codeC 代码中的 SSE2 指令
【发布时间】:2012-03-17 13:34:33
【问题描述】:

我正在尝试对 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”是什么意思?

【问题讨论】:

  • 这段代码对两个不相交的内联汇编块的使用是无效的;它可能有效,但不能保证,因为编译器以其无限的智慧可能会选择在进入之前对第二个 __asm__ 块的“未声明的输入”(regs %xmm0 / %xmm6)做一些事情。有关如何解决此问题的详细信息,请参阅stackoverflow.com/questions/8891139/…

标签: c gcc assembly sse


【解决方案1】:

你会想看看这个GCC Inline Asssembly HOWTO

百分号数字是指令操作数。

【讨论】:

    【解决方案2】:

    内联汇编器的工作方式类似于宏预处理器。前导百分比正好为 1 的操作数将按照它们在参数列表中出现的顺序替换为输入参数,在这种情况下:

    %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”相反,“m”是内存操作数。约束修饰符“=r”使它成为一个只写操作数,“+r”是一个读写操作数,“r”是一个普通的读操作数。

    在第一个冒号之后是输出操作数,在第二个冒号之后是输入操作数,在可选的第三个冒号之后是被破坏的寄存器。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 2017-08-05
      • 1970-01-01
      相关资源
      最近更新 更多