我在c167平台特定的代码上进行了一些重构,但偶然发现了内联汇编问题。

先前的代码:

  asm volatile ( "
            extp   #pag:%0, #3
            mov    r4, pof:%0   @ R4 = g_nRcvBufCount
            sub    r4, #1       @ R4 = R4 - 1
            mov    pof:%0, r4   @ g_nRcvBufCount = R4"
        : "=m" (g_nRcvBufCount)
        :
        : "r4"
  );

[

基本上,这段代码对“g_nRcvBufCount”变量进行原子递减

“extp”指令获取“g_nRcvBufCount”变量的“page”以及其后的原子表达式数(在这种情况下为3)

]

当前-未编译代码:
  asm volatile ( "
            extp   #pag:%0, #3
            mov    r4, pof:%0   @ R4 = cfg->g_nRcvBufCount
            sub    r4, #1       @ R4 = R4 - 1
            mov    pof:%0, r4   @ cfg->g_nRcvBufCount = R4"
        : "=m" (cfg->g_nRcvBufCount)
        :
        : "r4"
  );

其中cfg是指向包含“g_nRcvBufCount”变量的结构的指针。
struct {
  ...
  unsigned short g_nRcvBufCount;
  ...
}cfg;

编译中收到的错误是:
test.c:1124:Warning:Missing operand value assumed absolute 0.
test.c:1124:extp #pag:[r2+#66],#3: trailing chars after expression
test.c:1125:Warning:Missing operand value assumed absolute 0.
test.c:1125:mov r4,pof:[r2+#66]: trailing chars after expression
test.c:1127:Warning:Missing operand value assumed absolute 0.
test.c:1127:mov pof:[r2+#66],r4: trailing chars after expression

欢迎提供有关如何进行此工作的任何提示。同样,有关如何访问C / C++结构中定义的变量的(内联汇编的)x86版本也将有所帮助。解释“= m”关键字的作用的GNU内联汇编器文档也很有用。

提前致谢,

尤利安人

最佳答案

查看警告消息中的asm:

extp #pag:[r2+#66],#3

显然#pag:东西对它后面的寄存器或绝对地址有效,但不适用于已经包含[r2+#66]这样的偏移量的更复杂的表达式。您可能需要切换到使用包含"r"地址的cfg->g_nRcvBufCount参数,而不是引用它的"m"参数。

如果是这种情况,请注意,原始代码起初是伪造的,只是偶然发生了,因为gcc决定替换在asm中起作用的简单地址表达式。

关于c++ - GNU内联汇编问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4303860/

10-10 21:23