GNU内联汇编问题
我对 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看警告消息中的 asm:
显然
#pag:
后面有寄存器或绝对地址是有效的,但对于已经包含像[r2+ 这样的偏移量的更复杂的表达式则无效#66]
。您可能需要改用包含cfg->g_nRcvBufCount
的地址的"r"
参数,而不是"m "
引用它的参数。如果是这种情况,请注意,原始代码一开始就是伪造,并且只是碰巧起作用,因为 gcc 决定替换在 asm 中起作用的简单地址表达式。
Look at the asm in the warning message:
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 ofcfg->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.
来自 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