LONG vs RES
Title:LONG vs RES
Author:72.185.234.76
Published:Sun, 31 May 2009 20:35:30 GMT

How is RES different from LONG?

This is very difficult to explain, but understanding this is one of those Eureka moments that make you into a real Propeller assembly programmer.

external image 86d72083ff.jpgAs PropTool is compiling a spin program, with embedded assembler, it is keeping track of two important pointers.
  1. The Hub RAM pointer. This is the address in Hub RAM that the current code or data is going to be placed. It starts at zero, and keeps getting incremented as spin code is compiled or assembler is assembled. It measures memory as bytes.
  2. The Cog RAM pointer. This is set by the ORG directive, and is then incremented as assembler instructions and LONG, WORD and BYTE statements are assembled. It represents the eventual Cog address where code and data will live once it have been copied into a cog by a COGNEW or COGINIT. It measures memory as longs.

LONG defines an item of data. It increments the Cog RAM pointer by 1 and the Hub RAM pointer by 4.
RES reserves what will eventually be a space in Cog RAM with undefined content. It just increments the Cog RAM pointer by 1. It leaves the Hub RAM pointer alone.
That is the difference.

Why?

When you have a long that has initialised data, then it must occupy a long in Hub RAM to start with, and then it is copied with the rest of the code to a Cog to be executed. If it doesn't need to be initialised, you could just store any old value (say zero) in the long in Hub RAM and have that copied. But this unnecessarily wastes a long in Hub RAM that isn't needed. RES is a statement that allows you to mark out space with labels at the end of Cog RAM, without that space having to be taken up in Hub RAM.

"I don't get it. Just tell me what I need to do"


Another explanation

Here's what Propeller Tricks and Traps has to say on this issue:
Be sure to place RES statements at the end of any ORG segment that uses them. The following example does it wrong:
                //MOV     Time,CTR
                ADD     Time,Offset
                ...
 
Time            RES     1
Offset          LONG    230
Other_value     LONG    123
 
                ORG
Another_cog     ...//
In this example, Offset will get clobbered when CTR is copied to Time, and 123 will get added to it instead of 230. Why? Because when the assembler encounters a RES, it reserves space in cog memory, but not in hub memory where the program is stored. Consequently, 230 will occupy Time’s address in hub memory, and 123 will occupy Offset’s. Do this instead:
                //MOV     Time,CTR
                ADD     Time,Offset
                ...
 
Offset          LONG    230
Other_value     LONG    123
Time            RES     1
 
                ORG
Another_cog     ...//
In this example, whatever’s assembled at Another_cog will get loaded into Time when the first cog loads. But we don’t care, since Time will get written over anyway.