在C中使用Assembler而不使用占位符

时间:2014-05-08 17:19:32

标签: c assembly inline-assembly gas

我被分配了一项理论上不太难的任务。应使用汇编程序代码(asm)更改C变量。我已经完成了它并且它可以工作,但是赋值的第二部分是在不使用占位符(%)的情况下执行相同的操作。

我在这里不知所措,经过一些研究,我仍然没有找到解决方案。如何在不使用占位符来获取变量的情况下访问或操作汇编代码中的C变量?

以下是带占位符的代码:

    volatile uint8_t number = 1;
    volatile uint8_t *number_pointer = &number;

    asm volatile(
        "ld r20, %a0" "\n\t"
        "lsl r20" "\n\t"
        "st %a0, r20" "\n\t"
        "breq resetten" "\n\t"
        "ret" "\n\t"

        "resetten:" "\n\t"
        "ldi r20, 1" "\n\t"
        "st %a0, r20"
          : "+e" (number_pointer)
    );

简而言之:如何在不使用%的情况下访问和更改“number_pointer”? (代码加倍“数字”直到它为128,然后再从1开始。)

1 个答案:

答案 0 :(得分:1)

评论戴维斯的建议(如果我有足够的声誉,我会发表评论):使用"记忆"暗示在破坏的领域,如asm(" nop" :::"记忆");

这告诉gcc asm语句修改内存并且需要重新加载变量等。

例如,使用

static int foo;
int bar()
{
  foo = 1;
  __asm__("":::"memory");
  return foo;
}

我们得到了

转储功能栏的汇编程序代码:

   0x0000000000000000 <+0>:         movl   $0x1,0x0(%rip)        # 0xa <bar+10>
   0x000000000000000a <+10>:        mov    0x0(%rip),%eax        # 0x10 <bar+16>
   0x0000000000000010 <+16>:        retq   

如果没有&#34; memory&#34;,则缺少重载的变量值。