汇编 - 编译器看不到我的内联更改?

Assembly - compiler will not see my inline changes?

上下文:

Linux64.

GCC 4.8.2(带 -O3 -march=native)

我左手下的x86_64 abi,​​在第21页打开。

C代码:

int main (int argc, char ** argv) {

    int16_t h = atoi(argv[1]) ;
    int16_t p;

  __asm__ ("mov %2, %0\n\t"
    "rol ,%1\n\t"          
     : "=r" (p)    /* output operands */
     : "0"(p),"g"(h)/* input operands */
     :"cc");        /* clobbered operands */

  printf("%d %d\n", h, p);
  return 0;

}

汇编代码(问题所在的行):

    ...
    movl    , %edx
    movq    8(%rsi), %rdi
    xorl    %esi, %esi
    call    strtol
    xorl    %edx, %edx
    movl    $.LC0, %edi
#APP
# 1627 "test2ptr.c" 1
    movl %ax, %dx          <- set in %dx
    rol ,%dx

# 0 "" 2
#NO_APP
    movswl  %ax, %esi
    movswl  %dx, %edx <- Then this line should not appear
    xorl    %eax, %eax
    call    printf
    xorl    %eax, %eax
    ...

如果我评论它,结果很好。

但我不能依赖于修改源代码(无法维护:每次更改源代码中的某些内容时,都必须回到那个位置以确保它仍在工作..不行)。

问题:

为什么要保留行 movswl %dx, %edx

总之要搬长。但这已经被我完成了,让我浪费了一个多余的时钟。

有什么解决方法吗?

这只是我没有设置的选项吗?

谢谢

由于您指定了 16 位类型,但 printf 需要 32 位整数,因此您的结果需要进行符号扩展,这正是该代码所做的。不过,如果您为 printf 使用了正确的格式,两个版本应该会产生相同的输出。

像往常一样,你不需要内联 asm 来进行轮换,而且如果你在内联 asm 中使用 mov 很可能你做错了。

好的,

因此解决方法是设置 int32_t 而不是 int16_t。

现在代码...快了 2 cpu 个周期。

这太荒谬了。

但我现在非常喜欢组装:)