开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜