GNU Inline assembly problem
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) 开发者_C百科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
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.
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
精彩评论