Calling a Constant
pjv
Posts: 1,903
Hi All;
I need to have identical assembly code in several cogs, and of course the compilerI cannot have multiple assembler DAT blocks each having identical symbol names. So to rectify that I place several identical binary blobs in the editor, and use CONstants to define the various symbol names and their cog addresses. So far so good.
Then I have various pieces of assembler for each cog that must access it's binary blob at specific label locations as defined by the CONstants. That all works fine except for the CALL instruction which causes the compiler to throw an "expected a DAT symbol" error. I presume that is because the compiler can't find the call's _RET symbol in the binary blob eventhough it is listed in the CONstants.
It would be real nice if the assembler could be forced to use CONstants as arguments..... BST will also not do what I want, it recognizes and lists the symbol, but assigns a zero for it's value.
Does anyone know of a way to trick the compiler around this problem ? (I wish not to unfold the identical binary blobs and personalize the labels of each one)
Thanks for looking.
Cheers,
Peter (pjv)
I need to have identical assembly code in several cogs, and of course the compilerI cannot have multiple assembler DAT blocks each having identical symbol names. So to rectify that I place several identical binary blobs in the editor, and use CONstants to define the various symbol names and their cog addresses. So far so good.
Then I have various pieces of assembler for each cog that must access it's binary blob at specific label locations as defined by the CONstants. That all works fine except for the CALL instruction which causes the compiler to throw an "expected a DAT symbol" error. I presume that is because the compiler can't find the call's _RET symbol in the binary blob eventhough it is listed in the CONstants.
It would be real nice if the assembler could be forced to use CONstants as arguments..... BST will also not do what I want, it recognizes and lists the symbol, but assigns a zero for it's value.
Does anyone know of a way to trick the compiler around this problem ? (I wish not to unfold the identical binary blobs and personalize the labels of each one)
Thanks for looking.
Cheers,
Peter (pjv)
Comments
Is this because each PASM instance has it's own HUB workspace? If so, I believe, you could assign HUB addresses when the cog starts.
You will need a constant for the RET position in the binary blob and then replace the call with:
Andy
If there is some configuration different to each instance why not pass than in via a par parameter block?
@Mike: The code is proprietary at this point so I can't post. To answer your question, for each cog, the binary blobs are identical, but the other assembler codes are different. So to load a blob followed by it's specific code requires a new org 0 for each instance, and each cognew instruction must reference each blob/specific section separately, hence their names must be different.
@Andy: What you describe is precisely what I am doing, and that works fine, but it is a little cryptic, so I was hoping to somehow use the CALL/RET psuedocodes to make things clearer..... Sounds like a non-starter.
@Heater: Same answer as Mike. The differences are assembly code programs.
Looks like I'll have to stick with the less obvious approach. Thanks again guys,
Cheers,
Peter (pjv)
-Phil
I'm having a bit of a hard time to explain this properly... that probably means I don't fully understand it myself, although with the JMPRET method it does work properly, it just looks messy
Each cog must have the universal binary blob, immediately followed by its specific assembler code. In order to load the various cogs from spin they each must have a unique starting address (set to org 0 as you suggest) which will then load the consecutive 512 (less SFRS) longs into the respective cog. This implies multiple copies of the identical binary blobs, yet they can all be accessed via a pre-determined list of CONstant addresses. And all this works just fine.
The only trouble is with the compiler error when I use a CALL/RET instruction into the blob. It will work if I intersperse the blob with lables at salient points, but then again the labels mut be unique for each blob, and that becomes even messier than the JMPRET approach. So I guess I have my answer.
Thanks for reading.
Cheers,
Peter (pjv)
Since you stated that you want ed the blob located at the beginning of the cog, you don't save any hub space doing it this way, but you can address the blob data by their common names in each cog. Now, if you were to read the blob into the end of the cog, instead of the beginning, you would save hub space.
-Phil
Thank you. I have not yet decided for sure if I want my blob (actually it is my Spin-friendly multi-tasking scheduler) to reside at the beginning or at the end of the cog there are pluses and minuses to each approach.
I will need to try what you are suggesting, but I suspect that in the application code following the blob, the compiler will not let me do a CALL into the blob.
Example: call #data1
But all other instructions referencing data1 etc. ARE permitted.
Cheers,
Peter (pjv)
I'm afraid my code includes a bug. The statement,
will work only if the blob is fully located within the first 512 bytes of hub space, which is unlikely. As a consequence, you would have to store the value in par into another variable and use it at the source of the rdlong without the #. In that case two separate address increments are necessary in the transfer loop.
-Phil
The current blob (simple version scheduler) will just fit as it is 80 longs plus a dozen or so local variables. A next, more capable version will likely just be too large.
I'm wondering if by chance you have tested this with a CALL instruction into the blob ? Everything else you describe is already familiar to me. It just this silly CALL issue. I can't test it until after tomorrow.
Thanks for your interest.
Cheers,
Peter (pjv)
Note that I've fixed the rdlong ... #0-0 error and also am overwriting the jmp startx at the beginning of each cog.
This is untested code, BTW, except for verifying compilation.
-Phil
I can see that I'm still failing to describe my issue properly..... or perhaps I'm too much of bonehead !
The binary blob I have is just a DAT section of lines of hex bytes, as in byte $xx, $yy, $zz, etc for about 300 elements. Then in a CON section I have all the salient addresses defined in hex. So, there are no labels in the hex DAT section. I was hoping to CALL a routine in the blob via it's address in the CON section. This works for (I believe) all instructions, but not for a CALL.
Cheers,
Peter (pjv)
-Phil
If you mean calling some code at some address given by a constant that's something we can think about.
The problem here is that a CALL needs to save its return address somewhere. Most processors save return addresses on the stack, the propeller however stores it into the location of the return instruction of the subroutine being called. That is why you have: Here the return address is stored into the RET instruction at someFunction_ret
Clearly if you are calling into a "binary blob" of code it is not possible to use a CALL instruction as it does not have any "..._ret" label at which to store a return address. That is to say the assembler cannot deal with: (Which I believe is what you mean by "calling a constant".
You would need to use JMPRET. With JMPRET you specify the lable of the function to JMP to and the lable of the place where the function can find its return address.
Here the JMPRET stores the return address at retAddr and the jumps to the function. When the function is done it jumps via the return address back to the calling code.
In this case you can use constants: Problem of course now is that the binary blob and the caller have to agree on a location of retAddr (99) which will have to be fixed some how.
N.B. My PASM syntax may not be quite right here I have not hacked on this for a while.
Does this sound like what you are trying to do?
If so why do you need a binary "blob of" code with the resultant anonymous addresses fixed up by constant definitions?
I'm truly sorry for all the confusion... this thread has turned into a bit of a mess.
Heater has the right idea. I have code as a list of BYTEs in a DAT block. I have CONstants defined as address labels for some locations in the code (my binary blob). Several of those CONstants are named as CALL/RET pairs such as PAUSE and PAUSE_RET, or SUSPEND and SUSPEND_RET. Then further down, outside of the binary blob I wish to make calls to and returns from those PAUSE/PAUSE_RET etc. labels. And THAT'S the part that will not compile, and is the basis of my query. Only a CALL instruction into the blob using the CON defined labels will not compile, all others seem to be OK.
My reason for enclosing the blob as anonymous hex in a DAT block is that it is a small scheduler intended for use by others, and should not be messed with because it is quite convoluted. So, as stated earlier, instead of CALLs to those blob locations, JMPRETs will work, its just more confusing for other users I think.
Sorry again folks, I had not intended to abuse the forum or the respondents this way.
Cheers,
Peter (pjv)
IIRC, orgs don't work that way, since the address pointer changes after the org. This might work, however:
-Phil
Dave and Phil, this is precisely the "trick" I was hoping for. It works perfectly.
Many thanks to all contributors ! Oh how I love this forum and this chip. Yet another case of making it do what was not intended. Marvelous.
Cheers,
Peter (pjv)
I had not picked up sufficiently on your suggestion..... so far I have not (needed to) use the res directive.
But what you offer will probably work, I will try it..... Your suggestions are always well thought out, and deserve serious consideration.
Thank you.
Peter (pjv)
As expected, your suggestion works perfectly.
Both, Dave's as well as yours produce identical results, as per:
All is well, and it does considerably visually clean up my applications that CALL into the binary blob.
Thanks again all.
Cheers,
Peter (pjv)