inline assembler instructions with offsets

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

inline assembler instructions with offsets

Jump to solution
1,359 Views
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

Labels (1)
Tags (1)
0 Kudos
1 Solution
640 Views
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

 

 

View solution in original post

0 Kudos
3 Replies
640 Views
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.

 

640 Views
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 Kudos
641 Views
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 Kudos