This N°9 Posted January 20, 2009 Report Share Posted January 20, 2009 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 :D Quote Link to comment Share on other sites More sharing options...
This N°9 Posted January 20, 2009 Author Report Share Posted January 20, 2009 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? Quote Link to comment Share on other sites More sharing options...
stryd_one Posted January 20, 2009 Report Share Posted January 20, 2009 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 :D 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. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted January 20, 2009 Report Share Posted January 20, 2009 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! :D Quote Link to comment Share on other sites More sharing options...
This N°9 Posted January 20, 2009 Author Report Share Posted January 20, 2009 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. Quote Link to comment Share on other sites More sharing options...
This N°9 Posted January 21, 2009 Author Report Share Posted January 21, 2009 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 00x00008aso the valid way to have identical variable names in C/ASM is:vars_x UDATA_var1 RES 0var 1 RES 1_var2 RES 0var2 RES 1now I'am satisfied with this :D Quote Link to comment Share on other sites More sharing options...
This N°9 Posted January 21, 2009 Author Report Share Posted January 21, 2009 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 Quote Link to comment Share on other sites More sharing options...
stryd_one Posted January 21, 2009 Report Share Posted January 21, 2009 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 :) Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.