A little memory access trouble with assembler
Nefastor
Posts: 14
Hi guys,
I'm having a little frustration about accessing the main RAM from a cog.
Fixing this would be a lot easier if I had some kind of debugger, but we ain't there yet.
Basically, here's what I want to do :
- As cog 0 starts running spin, it declares an array variable such as :
long ARRAY[noparse][[/noparse]30]
- In the code, cog 0 launches code on cog 1 that will read and write into ARRAY[noparse]/noparse, therefore cog 1 is started with the address of the array as its parameter.
I'm a C guy, so initially I thought ARRAY would be the pointer to array ARRAY[noparse]/noparse. When the code didn't work, I tried passing @ARRAY and also @ARRAY[noparse][[/noparse]0], but nothing changed. Or at least that's what it looks like since I don't have a debugger to check what's really happening.
I would like to know exactly what happens when I declare an array of longs in Spin : my assumption is that the array starts at element 0 and the next elements are located at contiguous addresses (+4, +8, +12...). Can you confirm that ?
Also, can you confirm which expressions return the array's start address ? (ARRAY, @ARRAY, @ARRAY[noparse][[/noparse]0]...) ? Is there a page in the manual that I should read more carefully ?
- In cog 1, the software is in assembler, so the address I'm passing it ends up in cog 1's PAR register. I'm using a very conservative approach to transfering the data : I initialize a register with the value of PAR and add 4 to it to access the next element of the array, and I use that register as the address register in wrlong and rdlong. I'm not even trying self-modifying code for now.
I think the problem most likely comes from my assembler code and the way I declare my registers :
After the last instruction, I do this :
LABEL long $initial_value
repeatedly. I have found this to work just fine : in any instruction I can use the LABEL to specify my register and I haven't noticed any odd behaviour.
However I'm not too sure about how to get the ADDRESS of the register. Again, as far as I can tell, I can simply use #LABEL.
But all examples of code I've read on the forum use ":LABEL" instead of "LABEL". I think I have misunderstood the purpose of the colon before a label : where is it explained in the manual ?
Right now I use a colon before a label if it's a label to which I intend to jump, and I don't use one when I want the label to represent a register, but from what code I see on the forum this doesn't seem to matter.
As you can see I'm a bit lost with this stuff. Help me please
Jean
I'm having a little frustration about accessing the main RAM from a cog.
Fixing this would be a lot easier if I had some kind of debugger, but we ain't there yet.
Basically, here's what I want to do :
- As cog 0 starts running spin, it declares an array variable such as :
long ARRAY[noparse][[/noparse]30]
- In the code, cog 0 launches code on cog 1 that will read and write into ARRAY[noparse]/noparse, therefore cog 1 is started with the address of the array as its parameter.
I'm a C guy, so initially I thought ARRAY would be the pointer to array ARRAY[noparse]/noparse. When the code didn't work, I tried passing @ARRAY and also @ARRAY[noparse][[/noparse]0], but nothing changed. Or at least that's what it looks like since I don't have a debugger to check what's really happening.
I would like to know exactly what happens when I declare an array of longs in Spin : my assumption is that the array starts at element 0 and the next elements are located at contiguous addresses (+4, +8, +12...). Can you confirm that ?
Also, can you confirm which expressions return the array's start address ? (ARRAY, @ARRAY, @ARRAY[noparse][[/noparse]0]...) ? Is there a page in the manual that I should read more carefully ?
- In cog 1, the software is in assembler, so the address I'm passing it ends up in cog 1's PAR register. I'm using a very conservative approach to transfering the data : I initialize a register with the value of PAR and add 4 to it to access the next element of the array, and I use that register as the address register in wrlong and rdlong. I'm not even trying self-modifying code for now.
I think the problem most likely comes from my assembler code and the way I declare my registers :
After the last instruction, I do this :
LABEL long $initial_value
repeatedly. I have found this to work just fine : in any instruction I can use the LABEL to specify my register and I haven't noticed any odd behaviour.
However I'm not too sure about how to get the ADDRESS of the register. Again, as far as I can tell, I can simply use #LABEL.
But all examples of code I've read on the forum use ":LABEL" instead of "LABEL". I think I have misunderstood the purpose of the colon before a label : where is it explained in the manual ?
Right now I use a colon before a label if it's a label to which I intend to jump, and I don't use one when I want the label to represent a register, but from what code I see on the forum this doesn't seem to matter.
As you can see I'm a bit lost with this stuff. Help me please
Jean
Comments
If I do something like this in assembler :
REG1 long 0
REG2 long 0
REG3 long 0
...
Can I always be 100% sure that REG1, REG2... will be located in cog RAM at contiguous memory locations so I can safely access them using pointers ?
Thanks
Jean
2) What you declare in a single DAT section will be in the order you declare it. Nothing is moved.
I wrote my code using the rules you just described (not surprising, of course). But it doesn't work, so I'll have to keep looking for the problem. I've narrowed it down to a sequence of 15 instruction that does a sequential read from main memory followed by a sequential write, between a lockset / lockclr pair.
Can you confirm that when I write :
mov A,#B
Where A and B are two registers, I actually place the address of B into A ? That's the most likely cause for my problem (i.e. I assume I get a pointer when in fact I get a value or garbage).
Damn it would REALLY help to have a nice debugger... if I had time I'd port gbd, it shouldn't be too hard to write a stub since :
a/ there's no stack pointer to worry about
b/ you can easily control the Z and C flags
c/ it's easy to modify the code in memory to set breakpoints.
The tough problem would be debugging across multiple cogs.
I'm on a tight time constraint right now, but if I ever have time I'll definitely do something.
Anyway, can you tell me if the colon in labels has any specific meaning at all ?
Thanks,
Jean
mov A,#B
if B happens to be register 17, then A will contain 17, not the contents of register 17.
labels with a : in front are local. Their scope lies only between two global labels. That way you can reuse names like :loop for dumb little local loops in several different contexts.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Do you mean a label ? (label == symbol for an address)
Jean
I used the word address because it might indeed be a label which might be a symbol for an address. On the other hand, it might be an expression of some kind which is evaluated by the compiler (and might not really be an address). Sorry if I added to the confusion.
No harm done, after all we can always come back to the forum and sort it all out
Besides, you've confirmed what I was thinking originally. I still haven't found the cause of my problem, but when I do (and assuming it's interesting) I think I'll post in the "traps and tricks" thread.
Ultimately, I want to write code for circular FIFO's that would allow flexible and simple communication between cogs. It'd be nice to have some sort of mechanism for this kind of peer-to-peer transfers, though I can see how that would be tough to implement in hardware (I've worked on multi-core processors at TI)
Jean
That is the problem I'm up against now: Buffers + multiple cogs.
I know that I'm probably not going to be asking this question correctly, but you seem to have strange powers of divination... This is another way of thinking generally about the question that started this thread. So. I'm going to give it a shot... and if I am wrong... this would be a good time to find out[noparse]:)[/noparse]
Would it be reasonably correct to say that for any "symbolic label" identified as a variable... a particular assembly instructions might accept that label and operate on it as a "register(memory location) address" associated with that label... while another assembly instruction might operate on the actual contents stored at the memory address associated with that same label? So, what a particular label usage "means" is defined by the context of the instruction?
In other languages... there is a clear syntax for addresses vs. contents held at addresses... in Propeller assembly ... the syntax is defined by the operation?
Thanks,
Rich
In assembly like for the Propeller (there are exceptions in some other assemblers), labels either represent explicit constant values (CON stuff) or addresses. That's it. The actual instructions use that address to fetch or store a value or use the address as a literal constant (#x). The jump instructions copy the source value into the program counter (a special internal register). That's why jumps usually use the literal constant form of their source operand. The instruction determines how the destination and source values are used. As a destination, it's always used as an address. As a source, the instruction determines whether it's used as an address to fetch a value or the value itself (#x).
In C, there is not a clear syntax for addresses vs. contents held at addresses, particularly where type checking is not used and addresses are passed as parameters to subroutines. There's no way to tell what the parameter value represents. It's a major source of errors in C programs at run-time. That's why most compilers now require typing as a default setting, but C doesn't require it.
A word of warning, the ":hptr········ mov······ :hptr, par····················· 'use this loc as ptr to hub mem" is a bit of trickery that can only be used in a "run once and die" routine, if you have a permanent cog running multiple aquisitions, you would need to have a seperate variable to use for the hub pointer.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 4/24/2007 5:41:18 PM GMT
Rich