Page 1 of 1
Accessing C struct members from Assembly?
Posted: Fri Nov 16, 2018 1:28 pm
by gauauu
I'm curious if cc65/ca65 has a method for accessing C struct members by name from assembly. I looked through the docs and didn't find anything.
Here's an example of what I mean:
Code: Select all
struct Foo {
char x;
char y;
char z;
}
struct Foo myFoo;
Now later in assembly, I want to access myFoo.y without knowing the position of y in Foo. If I know that it's the 2nd member, it's easy to do:
But is there any notation for accessing it by name y? I know there are also structs in ca65, but I don't know any way to make a struct available to both C and assembly without building my own preprocessor to generate the code for one or the other.
(I know I can completely rework things, using structs of arrays instead of an array of structs, etc. I know there's many reasons not to do what I'm doing in 6502. I'm not asking about those here. I'm just curious if there's a way to let assembly know about the ordering of members so that if I add a member w in Foo, before x, my assembly code won't need to be updated.)
Re: Accessing C struct members from Assembly?
Posted: Fri Nov 16, 2018 1:50 pm
by dougeff
You could define some constants to make the code clearer.
x = 0
y = 1
z = 2
So
lda _myFoo+1
becomes
lda _myFoo+y
*x, y, z are not good variable names
Re: Accessing C struct members from Assembly?
Posted: Fri Nov 16, 2018 2:18 pm
by gauauu
dougeff wrote:You could define some constants to make the code clearer.
x = 0
y = 1
z = 2
So
lda _myFoo+1
becomes
lda _myFoo+y
Yeah, that's what I've done in the past. It still requires me modifying all the constants if I insert a member w. Worst comes to worst, I can write a pre-processor that generates all those constants for me, but I'd hate to do that if cc65 already provides a mechanism to do this.
*x, y, z are not be good variable names
Absolutely, they're just placeholders to illustrate the problem. Like Foo.
Re: Accessing C struct members from Assembly?
Posted: Fri Nov 16, 2018 7:30 pm
by Banshaku
There is no automated way, unfortunately (except for maybe the hack above but I don't know if there is any drawback to do so
).
What I do is I have a file that contains the definition, again, for the asm side and I keep them in sync when updated. If you don't have many structure to share it may not be a big issue. An example of what I used:
C side:
Code: Select all
typedef struct {
const unsigned char* frameCount;
const unsigned char* const *frameList;
} animInfo_t;
typedef struct {
unsigned char index; // index of the frame to be shown
unsigned char count; // current count for next frame
unsigned char maxCount; // how long is the frame
const unsigned char* current; // the current frame to be shown
} frameInfo_t;
// player's specific information
typedef struct {
int x; // location inside stage. May need negative, not sure yet.
int y; // vertical location, now 16 bits for checking bound outside screen
unsigned char direction; // which direction facing, left or right
unsigned char priority; // if shown priority is front or background
unsigned char outOfBound; // if went out of bound in a direction (up/down/left/right) based on the limit of the map
unsigned char state; // state of actor (for player, this means animState)
unsigned char subState; // state that modify current state (ex: using weapon while doing somethings)
unsigned char previousState; // previous states
unsigned char health; // tentative: value for health
unsigned char invicibleTimer; // flag & counter for invincible state (> 0, in that state)
unsigned char weapon; // which weapon was selected
frameInfo_t frame;
animInfo_t anim;
} player_t;
Asm side (started to convert recently, maybe issue in it)
Code: Select all
;
; Info regarding animation for the currently selected anim
;
.struct FrameInfo
index .byte
count .byte
maxCount .byte
current .word
.endstruct
;
; animation info
;
.struct AnimInfo
frameCount .word
frameList .word
.endstruct
;
; Player information definition
;
.struct Player
posX .word
posY .word
direction .byte
priority .byte
outOfBound .byte
state .byte
subState .byte
previousState .byte
health .byte
invicibleTimer .byte
weapon .byte
frame .tag FrameInfo
anim .tag AnimInfo
.endstruct
Something like that.
Then in asm you just use the struct, like expected:
Re: Accessing C struct members from Assembly?
Posted: Fri Nov 16, 2018 8:34 pm
by gauauu
Yeah, the C has more type information than what would be in the assembly (signed vs unsigned, whether it's an int vs a pointer), so my intention was to go that direction.
Re: Accessing C struct members from Assembly?
Posted: Fri Nov 16, 2018 8:36 pm
by gauauu
Either way, thanks for the suggestions. I appreciate the input.