【问题标题】:Set register using a variable inline assembly使用变量内联汇编设置寄存器
【发布时间】:2014-11-10 06:26:52
【问题描述】:

我的要求是使用带有内联汇编的变量来设置 EDI 寄存器。我写了下面的sn-p,但是编译失败了。

uint32_t value = 0;
__asm__ __volatile__("mov %1,%%edi \n\t"
                      : "=D"
                      : "ir"  (value)
                      :
                      );

我得到的错误是

cyg_functions.cpp(544):错误:预期为“(” :“ir”(值) ^

cyg_functions.cpp(544):内部错误:空指针 : "ir" (值)

编辑

我想我不清楚问题规范。假设我的要求如下。

  • 有两个 int 变量 val 和 result。
  • 我需要
    1. 将变量 val 的值设置为 %%edi 破坏已经存在的任何内容
    2. 将 %%edi 值乘以 2
    3. 将 %%edi 值设置回结果变量

如何用内联汇编来说明这一点?虽然这不完全是我对此的要求答案(特别是第一步)会解决我的问题。我需要中间体专门在 EDI 寄存器中。

【问题讨论】:

  • 虽然您可以使用“=D”作为约束,但有效的语法需要变量名。请参阅gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html 的文档另外,由于您使用的是“=D”,因此在调用 addl 时 EDI 的内容将是未定义的(IOW,它将使用它之前所做的任何事情发生的任何值) .
  • 我会给你更好的语法,但老实说,你的要求在这里没有意义。编译器可以踩踏您在 EDI 中输入的任何值作为下一条语句,因此您没有完成任何事情。
  • 我进行了编辑。希望现在有意义。我尝试解析文档。但我仍然不确定正确的方法。
  • edi需要乘以2的时候为什么要加1呢?在 gcc 中,您无需内联汇编即可做到这一点register int edi asm("edi"); int value = edi*2; edi = value;
  • 是的,这是一个错误。但我仍然要求将值从变量移动到 edi。

标签: c gcc inline-assembly


【解决方案1】:

我已经阅读了您的 cmets,但这里的要求对我来说仍然没有意义。但是,有意义不是必需的。就是这样:

int main(int argc, char *argv[])
{
   int res;
   int value = argc;

   asm ("shl $1, %[res]" /* Take the value in res (aka EDI) and shift
                            it left by 1. */
      : [res] "=D" (res) /* On exit from the asm, the register EDI 
                            will contain the value for "res".  The
                            existing value of res will be overwritten. */
      : "0" (value));    /* Take the contents of "value" and put it
                            in the same place as parameter #0. */

   return res;
}

如果你从下往上阅读,这可能更容易理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2021-03-21
    • 2018-01-04
    • 1970-01-01
    • 2014-04-16
    相关资源
    最近更新 更多