In pics all constants are stored in rom as the only sensible way to use them is with a movlw # or addlw # etc. Using define or const will still produce the same code. Strings stored as constants are compiled to retlw tables or if you are using asm then the DT "Hello World!" will be stored as a series of retlw instructions.
In pics all constants are stored in rom as the only sensible way to use them is with a movlw # or addlw # etc. Using define or const will still produce the same code. Strings stored as constants are compiled to retlw tables or if you are using asm then the DT "Hello World!" will be stored as a series of retlw instructions.
On 16-bit PICs, the linker has a provision for a RAM data section which is then getting initalized from ROM at startup, so the same thing is stored twice. I suspect that C compiler could be using this mechanism.
They have a direct mechanism which allows parts of the program memory to be mapped into the data space, but since the program memory is usually bigger it cannot be mapped all at once. I guess that is why direct access may not be implemented in C.
I use Assembler and I create a constant section at the beginning of the program memory which I use for constants that don't change. I then map it into the data memory space and I never change this mapping. As a result, it is accessible from anywhere as if it was in the data memory, but read-only. The only drawback is that you need to use an ugly #psvoffset prefix for all such variables, but this could be avoided with better Assembler compiler.
Sorry, I should have made it clear above that I was referring to 16 series (8 bit) pics. I would assume that 16 bit compilers keep constants in ROM and use the same mechanism as yourself for efficiency. However, would it be more efficient to use an immediate addressing mode (like movlw) to move a constant into a register?
Sorry, I should have made it clear above that I was referring to 16 series (8 bit) pics. I would assume that 16 bit compilers keep constants in ROM and use the same mechanism as yourself for efficiency. However, would it be more efficient to use an immediate addressing mode (like movlw) to move a constant into a register?
On 16-bit PICs, instructions reading from the mapped memory take about 3 times longer than instructions dealing with regular memory. However, you do not really read constants from the memory very often, so I don't think it's a big deal.
The organization of their program memory is very funny. Even though every instruction uses 3 bytes, these 3 bytes are spaced by 2 in the program memory space. That is first 3-byte instruction is at address 0x200, second 3-byte instruction is at address 0x202, next one is at address 0x204 etc. When you buy a chip with 64K of memory you get 64K/3 = 22016 instructions with the last address being 0x5800.
When the program memory is mapped into the data space, only 2 of the 3 instruction bytes are visible, while the 3-rd byte is hidden. When you put your constants into program memory, the data go into the two visible bytes and the third byte is set to 0. When the hidden byte is zero, the instruction becomes "NOP", so you can safely execute through the data located in the program memory without doing much harm.
Mapping is very useful. For example, you may have a routine which prints text on LCD. You can pass a pointer to a regular data memory location (e.g. decimal number) or you can pass a pointer to a piece of program memory mapped to data memory (e.g. constatnt text). It won't make any difference except that the mapped memory cannot be written.
In pics all constants are stored in rom as the only sensible way to use them is with a movlw # or addlw # etc. Using define or const will still produce the same code.
That makes sense, except for handling pointers. You can have a pointer to a const but you can't use FSR and INDF to reference program memory. If the compiler was smart enough and/or the code simple enough it might be possible to replace any pointer based code with literals but I'm not sure that is always going to work.