c - 在不使用占位符的情况下在 C 中使用汇编器

标签 c assembly inline-assembly gnu-assembler

我被分配了一项理论上不太难的任务。应使用汇编程序代码 (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 开始。)

最佳答案

要评论 David 的建议(如果我有足够的声誉,我会把它作为评论发布):在被破坏的字段中使用“内存”提示,如 asm("nop"::::"memory");

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

例如,用

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

我们得到

函数 bar 的汇编代码转储:

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

而没有“内存”,变量值的重新加载就丢失了。

关于c - 在不使用占位符的情况下在 C 中使用汇编器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23548488/

相关文章:

java - ASM 方法访问者可以与接口(interface)一起使用吗?

c - 如何在 gcc asm 中添加一个计数器?

assembly - 使用 gas (-fPIC) 生成位置无关代码

c++ - 错误 : operand out of range (64 is not between 0 and 31)

c - 如何在 MS Visual Studio 中使用 SSE 内在函数?

c - C 中变量被覆盖

c - 使用 fgets 从文件中读取

python - Migrate extension to python3,丰富对比

c - 将CPU寄存器保存到GCC中的变量中

c - 按值传递结构的值不会改变