【问题标题】:Assembly - compiler will not see my inline changes?汇编 - 编译器不会看到我的内联更改?
【发布时间】:2015-04-22 14:11:39
【问题描述】:

上下文:

Linux 64.

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 $8,%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    $10, %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 $8,%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 行?

它应该在一个单词中移动很长。但它已经由我完成,并且花费了我一个多余的时钟。

有什么解决方法吗?

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

谢谢

【问题讨论】:

    标签: linux assembly x86-64 cpu-registers att


    【解决方案1】:

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

    像往常一样,您不需要内联 asm 进行轮换,而且如果您曾经在内联 asm 中使用 mov,那么您可能做错了。

    【讨论】:

    • 谢谢(再次:-))小丑。我用 movl 更正了 mov。实际上我这样做节省了 1 个 cpu 周期!什么都不是,只是一个开始。但我的问题仍然存在。我能做些什么来解决它?
    • 我从 int16_t 更改为 int32_t 并且问题消失了。现在我的内联 asm 快了 2 个 cpu 周期 :) waw.. champagne..
    • 但是我想给你 +1 小丑:因为你就像我在装配领域的守护者,总是为我指明正确的方向。
    【解决方案2】:

    好的,

    所以解决方法是设置 int32_t 而不是 int16_t。

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

    这太荒谬了。

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

    【讨论】:

      猜你喜欢
      • 2013-07-23
      • 2013-11-28
      • 2019-05-11
      • 2023-03-08
      • 2012-10-20
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多