GNU内联汇编问题

发布于 2024-10-04 23:06:23 字数 1581 浏览 7 评论 0原文

我对 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”变量的“页”以及后面的原子表达式的数量(在本例中为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 版本(内联汇编)也会有所帮助。 GNU 内联汇编器的文档解释了“=m”关键字的作用也很有用。

预先感谢,

尤利安

I did some refactoring at c167 platform specific code and I stumbled upon an inline assembly problem.

Previous code:

  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"
  );

[

Basically this code does an atomic decrement of "g_nRcvBufCount" variable

"extp" instruction takes the "page" of the "g_nRcvBufCount" variable and the number of atomic expressions that follow (3 in this case)

]

Current - not compiling code:

  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"
  );

where cfg is a pointer to a structure containing the "g_nRcvBufCount" variable.

struct {
  ...
  unsigned short g_nRcvBufCount;
  ...
}cfg;

The errors received in compilation are:

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

Any hints about how to make this work are welcome. Also an x86 version (of inline assembly) on how to access variables defined in a C/C++ structure would be helpful. Documentation of the GNU inline assembler explaining what "=m" keyword does is also useful.

Thanks in advance,

Iulian

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨落画卷 2024-10-11 23:06:23

查看警告消息中的 asm:

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

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

如果是这种情况,请注意,原始代码一开始就是伪造,并且只是碰巧起作用,因为 gcc 决定替换在 asm 中起作用的简单地址表达式。

Look at the asm in the warning message:

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

Apparently the #pag: thing is valid with a register or absolute address after it, but not with a more complex expression already containing an offset like [r2+#66]. You might need to switch to using a "r" argument containing the address of cfg->g_nRcvBufCount instead of a "m" argument referencing it.

If this is the case, note that the original code was bogus to begin with, and only happened to work because gcc decided to substitute a simple address expression that worked in the asm.

≈。彩虹 2024-10-11 23:06:23

来自 ibiblio

"m" :允许使用内存操作数,具有机器通常支持的任何类型的地址。

关于“错误” - 这些是“唯一”警告 - 尝试使用此程序集创建一个小的 .c 文件并反汇编它并查看 objdump 如何输出它。它可能会告诉您如何编辑代码以避免出现这些警告

from ibiblio

"m" : A memory operand is allowed, with any kind of address that the machine supports in general.

about "errors" - these are "only" warnings - try to make a small .c file with this assembly and disassemble it and look how objdump outputs it. it might give you clue on how edit your code to not have these warnings

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文