hi,
I had some strange bugs, which at the end showed up as overlapping variables:
FRAM_VARS UDATA
FRAM_REG RES 1
_FRAM_REG
FRAM_ERROR RES 1
_FRAM_ERROR
gives me this:
FRAM_REG 0x000088 data extern /home/this/mios/trunk/modules/fram/fram.asm
_FRAM_REG 0x00008a data extern /home/this/mios/trunk/modules/fram/fram.asm
FRAM_ERROR 0x000089 data extern /home/this/mios/trunk/modules/fram/fram.asm
_FRAM_ERROR 0x00008c data extern /home/this/mios/trunk/modules/fram/fram.asm
and this one
FRAM_VARS UDATA
_FRAM_REG
FRAM_REG RES 1
_FRAM_ERROR
FRAM_ERROR RES 1
will be that
_FRAM_REG 0x000088 data extern /home/this/mios/trunk/modules/fram/fram.asm
FRAM_REG 0x000088 data extern /home/this/mios/trunk/modules/fram/fram.asm
_FRAM_ERROR 0x00008a data extern /home/this/mios/trunk/modules/fram/fram.asm
FRAM_ERROR 0x000089 data extern /home/this/mios/trunk/modules/fram/fram.asm
can somebody explain me shortly what the **** is going on here? labels in data space seem to behave quite differently. the reason why I even got suspicious, was that the error-code seemed to match the address LSB! :
_address 0x00008a data extern _output/main__mios-gpasm-tmp.asm
I will use separate UDATA sections for each C/ASM variable instead now, but I wonder anyway what is going on here. no warnings or so at all… my intension was (obviously) to have the ASM/C variable at the same address, and I also had the idea that it shouldn’t be shared with other variables 
I found a solution that works:
FRAM_REG_ UDATA
_FRAM_REG
FRAM_REG RES 1
FRAM_ERROR_ UDATA
_FRAM_ERROR
FRAM_ERROR RES 1
now the addresses look better to me.. :
_FRAM_REG 0x00008a data extern /home/this/mios/trunk/modules/fram/fram.asm
FRAM_REG 0x00008a data extern /home/this/mios/trunk/modules/fram/fram.asm
_FRAM_ERROR 0x00008b data extern /home/this/mios/trunk/modules/fram/fram.asm
FRAM_ERROR 0x00008b data extern /home/this/mios/trunk/modules/fram/fram.asm
_address 0x000088 data extern _output/main__mios-gpasm-tmp.asm
What is the label before ‘udata’ even for? It seems that I can’t use it in my code as a memory address. Are there other(better) ways to define two labels on the same memory address, like I can do in codespace?
I will use separate UDATA sections for each C/ASM variable instead now, but I wonder anyway what is going on here. no warnings or so at all…
That’s probably overkill. I don’t think you got any errors because it just did what you told it to do, and it’s not strictly an error (sometimes you might want it that way, like a union)
I think that what is happening here is that the res directive persists for following lines. I guess that makes it a bit less typing, because you can do:
FRAM_VARS UDATA
_FRAM_REG RES 1
_FRAM_THING
_FRAM_FOO
_FRAM_BAR
And you only have to use RES, one time. If you wanted to have two vars in ASM code share the same memory address, then there are ways of forcing a specified address, but you shouldn’t need to do that for your purposes…
my intension was (obviously) to have the ASM/C variable at the same address, and I also had the idea that it shouldn’t be shared with other variables 
No need to worry about it sharing the address with other vars, it will only do that with the automatic temporary registers. When you link the C code and ASM together, it’ll match them up to ensure they get the same address - this way, you only define the variable once in ASM land (with the prefix underscore) and once in C, and it will match them up…
global _FRAM_REG
global _FRAM_ERROR
...
FRAM_VARS UDATA
_FRAM_REG RES 1
_FRAM_ERROR RES 1
unsigned char FRAM_REG;
unsigned char FRAM_ERROR;
When you link, they will become the same. Check out mod_skel_var to see how it’s done. Note the difference between mod_skel_int, where the global directive is not used, so no label is generated for the linker to use.
Your new code may work, but it’s not really the best thing… you’re just tricking it into reserving 0 bytes for the variable. Try the ‘global’ directive and C declaration mixup, it’ll do what you want 
The label before ‘udata’ can be used for banksels.
PS: You ask interesting questions! 
I think that what is happening here is that the res directive persists for following lines. I guess that makes it a bit less typing, because you can do:
I’am not quite sure about that… when you look at the first example I provided in the first post, you can see a quite strange behaviour. And besides, a field that I defined globally in C only, will have the same address as one of my ASM fileds. So it seems that with the label without RES directive, the assembler will give the label an address, but not really reserve the memory location. That’s why it will be used again:
FRAM_VARS UDATA
FRAM_REG RES 1 ;0x000088
_FRAM_REG ;0x00008a
FRAM_ERROR RES 1 ;0x000089
_FRAM_ERROR ;0x00008c
_address 0x00008a data extern _output/main__mios-gpasm-tmp.asm
‘address’ is I field that I defined globally on application level then. As you can see it has the same address as FRAM_REG. So the assembler seems to increment the memory address pointer (in the module), but it will not reserve the address, the linker uses the same address in the application (main.o) again. Maybe a label in a UDATA section without any directive equals a shared field. This would make sense.
anyway, the only thing I wanted is not to have the ugly _ vars in the ASM code.. Maybe I have to be a bit less aestheticly fanatic and have a working software instead 
by the way.. my ‘solution’ for having two labels at the same memory address is not confirmed to work as intended. I have strange behaviours in my app since I changed it this way (LCD not switching to second line, wrong increments etc.).
I’ll study the gputils manual again, and do some more test. You may say that this is loss of time, but when I once touched this issue, I want to know what’s going on! 
I will post any results here.
so, here are the results of my UDATA/RES research. I tested different solutions and the effect they have. I added the resulting addresses as comment to the labels (@stryd: this is also the proof that labels without RES are NOT the same as with RES 0):
FRAM_VARS UDATA
FRAM_REG ; 0x000088
_FRAM_REG RES 1 ;0x000088
FRAM_ERROR ;0x00008a
_FRAM_ERROR RES 1; 0x000089
this is not really the intended result. don’t do this
FRAM_VARS_1 UDATA
FRAM_REG ;0x00008a
_FRAM_REG RES 1 ;0x00008a
FRAM_VARS_2 UDATA
FRAM_ERROR ;0x00008b
_FRAM_ERROR RES 1;0x00008b
the addresses look good and are unique, but it has some strange effect on the codespace. For example the display will not switch to the second line, the constant 0x40 in codespace seems to get fucked up. Don’t do this either!
FRAM_VARS UDATA
_FRAM_REG RES 0 ;0x000088
FRAM_REG RES 1 ;0x000088
_FRAM_ERROR RES 0 ;0x000089
FRAM_ERROR RES 1 ;0x000089
this seems to be the proper way to define two labels at the same memory position. The addesses are correct, unique and the program behaves like it should. and to end the story: <label 1> RES 0 has always to be *before* <label 1> RES X ! else the RES-0-Label will obtain an address, but no meory will be reserved for it:
FRAM_VARS UDATA
FRAM_REG RES 1;0x000088
_FRAM_REG RES 0;0x000089
FRAM_ERROR RES 10x000089
_FRAM_ERROR RES 00x00008a
so the valid way to have identical variable names in C/ASM is:
vars_x UDATA
_var1 RES 0
var 1 RES 1
_var2 RES 0
var2 RES 1
now I’am satisfied with this 
The label before ‘udata’ can be used for banksels.
I see. A UDATA section will always entirely reside in one bank. Also good to know!
EDIT: http://www.midibox.org/dokuwiki/doku.php?id=home:software:picasm
You may say that this is loss of time, but when I once touched this issue, I want to know what’s going on! 
Never! me too! Thanks for doing the research for us all 