View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
asm syntax for int16 variables |
Posted: Tue Feb 20, 2007 8:56 am |
|
|
Hi,
I can not manage to access a struct using inline asm
Code: | struct
{
long deadline;
} bank1;
INFSNZ &bank1.deadline,F
INCFSZ &bank1.deadline+1,F
|
Using the *(char*) cast proposed by other threads results in compile time error (Expression must evaluate to a constant).
Thank you. |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 20, 2007 10:36 am |
|
|
What compiler version?.
You don't actually 'need' the '&' for the first line, but either as posted, or using:
Code: |
#asm
INFSNZ bank1.deadline,F
INCFSZ &bank1.deadline+1,F
#endasm
|
It compiles fine under 3.249, and accesses the right bytes.
Best Wishes |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Feb 20, 2007 11:25 am |
|
|
Sorry, it is version 4. Version 3 works fine using the posted code.
On version 4, &var+1 is 2 bytes after var, so the char cast is needed and I can't find the correct syntax for it. |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 20, 2007 1:36 pm |
|
|
OK.
V4, has switched to correct C syntax, so incrementing a pointer, moves you forward by the size of the addressed object. This will cause problems accessing latter bytes in anything larger than an int, when using assembler using this normal 'trick'.
Use 3.249, and report it to CCS.
Alternatively, declare a union, rather than a structure, and have a second component, talking to the bytes, and access this in the assembler.
Best Wishes |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Fri Mar 02, 2007 9:14 am |
|
|
This works ... but it's annoying havong to change all my code .... and for all i know it will break with the next compiler version.
I have not found a way of dealing with int32
Code: |
typedef union {
int16 w;
int8 b[2];
} iint16;
#define HI(x) (((iint16)x).b[1])
....
#ASM
movf coil_count,w //Low byte
movf ((iint16)coil_count).b[1],w // High byte
movf HI(coil_count),w // High byte
|
Bill |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Fri Mar 02, 2007 10:58 am |
|
|
.... and this also works
Code: |
#define ByteOf(addr,n) (&((int8)addr)+n)
......
movwf ByteOf(acount,2) //w -> acount+2
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 02, 2007 11:08 am |
|
|
Now that is neat, and interesting. Totally 'silly', that a syntax that doesn't work inside the assembler, works OK, if it is in a #define.
It appears that the core 'fault', is that the 'cast' doesn't work inside the assembler.
A lovely bodge.
Best Wishes |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 02, 2007 11:25 am |
|
|
I don't know why the word 'spam' appeared in my answer. It appears that something in the filtering on the board, decided the text I had typed, should be replaced by the word 'spam'. I suspect the word I chose, was one that is used in some spam posts. Anyway try 'tidy' instead.
Best Wishes |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Mon Mar 05, 2007 10:34 am |
|
|
It does work without the #define ... its just easier to use with |
|
|
Ttelmah Guest
|
|
Posted: Mon Mar 05, 2007 10:46 am |
|
|
Yes. What doesn't work inside the assembler, is casting the pointer. You cast the 'value', then generate the pointer. Casting the pointer works outside the assembler.
Best Wishes |
|
|
thomasb
Joined: 12 Mar 2005 Posts: 7
|
|
Posted: Tue Mar 27, 2007 5:04 pm |
|
|
Quote: | .... and this also works
Code:
#define ByteOf(addr,n) (&((int8)addr)+n)
movwf ByteOf(acount,2) //w -> acount+2
|
Thanks, it works great! I was scratching my head trying to figure out how to do this. Thank goodness you shared the secrete. |
|
|
|