我在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”关键字也很有用。
提前致谢,
尤利安
答案 0 :(得分:2)
在警告信息中查看asm:
extp #pag:[r2+#66],#3
显然,#pag:
之后的寄存器或绝对地址是有效的,但是对于已经包含[r2+#66]
之类的偏移的更复杂的表达式则没有。您可能需要切换到使用包含地址 "r"
的{{1}}参数,而不是引用它的cfg->g_nRcvBufCount
参数。
如果是这种情况,请注意原始代码是 bogus 开始,并且只是因为gcc决定替换在asm中工作的简单地址表达式才有效。
答案 1 :(得分:1)
来自ibiblio
“m”:允许使用内存操作数,以及机器通常支持的任何类型的地址。
关于“错误” - 这些是“仅”警告 - 尝试用这个程序集制作一个小的.c文件并反汇编它,看看objdump如何输出它。它可能会告诉您如何编辑代码以获得这些警告