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
Solved! Go to Solution.
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
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.
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.
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