Microchip Technology XC8 Standard Compiler (Workstation) SW006021-1 SW006021-1 User Manual

Product codes
SW006021-1
Page of 518
C Language Features
 2012 Microchip Technology Inc.
DS52053B-page 155
5.4.5.2.1
Pointers to Both Memory Spaces
When a pointer is assigned the address of one or more objects that have been allo-
cated memory in the data space, and also assigned the address of one or more const 
objects, the pointer will fall into one of the mixed target space pointers listed in 
Section 5.4.5.2 “Data Pointers”, and the address will be encoded so that the target 
memory space can be determined at runtime. The encoding of these pointer types are 
as follows.
For the Baseline/Mid-range 16-bit mixed target space pointer, the MSb of the address 
(i.e., bit number 15) indicates the memory space that the address references. If this bit 
is set, it indicates that the address is of something in program memory; clear indicates 
an object in the data memory. The remainder of this address represents the full address 
in the indicated memory space.
For the PIC18 16-bit mixed target space pointer, any address above the highest data 
space address is that of an object in the program space memory; otherwise, the 
address is of a data space memory object.
For the PIC18 24-bit mixed target space pointer, bit number 21 indicates the memory 
space that the address references. If this bit is set, it indicates that the address is of an 
object residing in data memory; if it is clear, it indicates an object in the program mem-
ory. The remainder of this address represents the full address in the indicated memory 
space. Note that for efficiency reasons, the meaning of the memory space bit is the 
opposite to that for baseline and mid-range devices.
To extend the mid-range device example given in Section 5.4.5.2 “Data Pointers”
the code is now developed further. The function getValue() is now called with the 
address of an object that resides in the program memory, as shown.
int i, j;  // allocated to bank 0 in this example
int x;     // allocated to bank 2 in this example
const int type = 0x3456;
int getValue(const int * ip) {
    return *ip;
}
void main(void) {
    j = getValue(&i);
    // ... code that uses j
    j = getValue(&x);
    // ... code that uses j
    j = getValue(&type);
    // ... code that uses j
}
Again, the targets to the pointer, ip, are determined, and now the pointer is made of 
the class that can access both data and program memory. The generated code to 
dereference the pointer will be such that it can determine the required memory space 
from the address, and access either space accordingly. Again, this takes place without 
any change in the definition of the pointer.
If assembly code references a C pointer, the compiler will force that pointer to become 
a 16-bit mixed target space pointer, in the case of baseline or mid-range programs, or 
a 24-bit mixed target space pointer, for PIC18 programs. These pointer types have 
unrestricted access to all memory areas and will operate correctly, even if assignments 
(of a correctly formatted address) are made to the pointer in the assembly code.