inline assembler instructions with offsets

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

inline assembler instructions with offsets

跳至解决方案
2,167 次查看
slarti
Contributor I

Hi all,

this seemingly simple inline instruction won't compile:

 

char c;char d;void foobar(void){  __asm   movb c , d : 1 ; // access byte behind d}

 

It generates an error C12089: ',' expected before next element

 

Version with '+' or reversed order yield the same result. It seems that the assembler can't generate the necessary offset calculation to produce the desired access.  The reason I want to have this is a C array which I want to access with indices which carry an offset:

 

#define OFS -4char x[8];char get(char c) // c ranges from 4 .. 11{    return x[OFS + c];}

 

 

 

Of course on can always do the offset calculation at runtime, at the cost of extra bytes and cycles:

 

#define OFS -4char x[8];char get(char c) // c ranges from 4 .. 11{    c += OFS;    return x[c];}

 

 

But this negates the whole purpose of using inline assembly IMO.

 

Is there a solution to this?

 

regards,

Mark

标签 (1)
标记 (1)
0 项奖励
回复
1 解答
1,448 次查看
CompilerGuru
NXP Employee
NXP Employee

One way to code this is to compute the size as an enum with the ANSI offsetof in C code and then in the hli code to read the enum.

This way all the C operations and syntax can be used.

 

E.g.

 

#include <stddef.h>struct A { int field1; int field2;};enum { offset_field1 = offsetof(struct A, field1), offset_field2 = offsetof(struct A, field2)};void fun(void){ __asm LDD  #offset_field2 - offset_field1; }

 

Daniel

 

 

在原帖中查看解决方案

0 项奖励
回复
3 回复数
1,448 次查看
kef
Specialist I

Please don't forget to mention target name at least. Codewarrior version also would be nice know. I guess we are talking about CW for HC12.

 

It seems inline assembler treats "d" variable as d register. If you rename d to something else, for example dd, your code starts compiling and emits warning C10030 Offset out of Object.

 

1,448 次查看
slarti
Contributor I

kef wrote:

Please don't forget to mention target name at least. Codewarrior version also would be nice know. I guess we are talking about CW for HC12.

 

It seems inline assembler treats "d" variable as d register. If you rename d to something else, for example dd, your code starts compiling and emits warning C10030 Offset out of Object.

 


 

Ouch! Completely missed the D register name clash. The problem stays somewhat the same, at least for positive offsets. Funny enough, with negative offsets the  code compiles ok. All in all, the inline assembler seems to be severely restricted for no good reason anyway:

struct foo{  char c;  long ignore;  char c2;};struct foo bar;void foobar(void){  __asm addb #bar.c2 - bar.c;  __asm addb #(bar.c2 - bar.c);  __asm addb @bar.c2 - @bar.c;  __asm addb (@bar.c2 - @bar.c);  __asm addb #(@bar.c2 - @bar.c);}

 

None of the above statements compiles ok. Is there a way to move around in a struct via offset arithmetic (at compile time)?

 

regards,

Mark

 

PS: the target is an S12X and the suite is a CW 4.6 - OTOH I suppose the problems will not be confined to one certain version as it doesn't look like a bug but rather a restriction.

0 项奖励
回复
1,449 次查看
CompilerGuru
NXP Employee
NXP Employee

One way to code this is to compute the size as an enum with the ANSI offsetof in C code and then in the hli code to read the enum.

This way all the C operations and syntax can be used.

 

E.g.

 

#include <stddef.h>struct A { int field1; int field2;};enum { offset_field1 = offsetof(struct A, field1), offset_field2 = offsetof(struct A, field2)};void fun(void){ __asm LDD  #offset_field2 - offset_field1; }

 

Daniel

 

 

0 项奖励
回复