A METHOD FOR PIC ASSEMBLY CODE INTEGRATION AND REUSE - Part 2 First of all I'd like to publicly thank again for all the positive words many of you had towards my first message. In my last posting I ended by giving an example of a case in which you may overlap variables. We had the following structure as an example: TEXT_DISPLAY | | --------------- ------------------ | | | | FILLING_A_TEXT_BUFFER------------- READING_A_TEXT_BUFFER | | | | | ------------- ------------ | | | | | KEYBOARD_INTERFACE SERIAL_INTERFACE EEPROM_SUPPORT I said that you shouldn't ovelap the variables belonging to "FILLING_A_TEXT_BUFFER" with those from "KEYBOARD_INTERFACE" because both components might be active at the same time. By "active" I mean that the component is performing a service for a client. For example, if in this structure the program flow is in the "KEYBOARD_INTERFACE" that component will be active and "FILLING_A_TEXT_ BUFFER" too because it's waiting for "KEYBOARD..." to perform the service it requested (no other component could have requested a service from "KEYBOARD..." with this structure). The rule is to overlap variables that belong to components that are never active at the same time, with some exceptions to which I'll soon refer. To check for the validity of this assertion lets make an analogy with an Algol-like-high-level-language (one that makes use of a data stack) running on a language-oriented-machine (one that HAS a data stack!). If a routine is active it has a stack frame belonging to it where it keeps its local variables. When this routine calls a server its frame is kept on the stack and the server's frame is placed on top. So when the program flow is in the server both routines are active, as in the example, and the memory for their local variables is not overlaped. What happens when the server ends its job, the flow returns to the original routine and it calls another server? The first server's stack frame is wiped out and the newer server's is put on top of the original routine's. So you may have some memory space being shared by both servers. But there was no problem about it because both routines were not active at the same time, and if one never calls the other, and never calls another routine that calls the other, and never calls another routine that calls another routine... etc. that calls the other, then you can assure that you will *never* need separate memory locations for these routines' variables. Our example shows this behaviour for {"KEYBOARD...", "SERIAL..." and "EEPROM..."} and for {"FILLING..." and "READING..."}. But there is no need to inspect the client-server structure of a given system to apply the method, I'm explaining this only to introduce its logic but its application is much simpler. I'll again begin with an example and generalize later on my next posting. Lets say each component has the following quantity of local variables: "KEYBOARD_INTERFACE": 5 "SERIAL_INTERFACE": 3 "EEPROM_SUPPORT": 3 "FILLING_A_TEXT_BUFFER": 7 "READING_A_TEXT_BUFFER": 4 "TEXT_DISPLAY": 3 I'll start from the bottom of the structure. Where will I put the variables belonging to the first three components? I already said I could overlap them. Recall the method to which I refered on my last posting that assigned consecutive addresses to variables and could be implemented with "CBLOCK"s. I said that it was OK as long as you did not run out of registers, because it did not overlap any. So lets add this feature to that method. But first lets agree on something, when you use consecutive addresses it's the same to build from the bottom to the top incrementing the addresses or to do it from top to bottom decrementing them. This time I'll choose the second option, but for no particular reason. So, if the maximum register address is 127, the variables belonging to "KEYBOARD..." will occupy positions 123 to 127. And the other two will also begin in 127 as I have no problem in ovelapping them! "SERIAL..." will use 125 to 127 and "EEPROM..." too. Now the responsibility of not overlapping that allocated space is passed to the components on top. This makes sense if you think that the definition of a component includes information of its servers but not of its clients. Where can I put "FILLING..."'s variables? They shouldn't overlap the first three allocated spaces, so they could start at 122 being the next free position that meets this condition. The variables will go from 116 to 122. "READING..."'s variables must not overlap only "EEPROM..."'s, so they can start at 124, occupying from 121 to 124. "TEXT..."'s variables shouldn't overlap any of the others' so they may start at 115 and run down to 113. The general rule then is (if you're using a "decremental model" as in this case): allocate beggining from the least of the routine's servers' allocated positions minus one. This is a job for a macro. I'll continue later, but I guess you can see much of the point already. I also owe you the explanation of the exceptions for this scheme. Once again, I'll appreciate any opinions. Regards! Andres aajordj@aleph.fi.uba.ar