Pointers

XCSB pointers allow you to refer to the contents of memory by using an explicit address (a number).

Normally when you refer to the contents of memory you do so using a symbolic reference called a variable name.

Pointers allow us to explicitly refer to a specific memory location rather than the compiler choosing one for us. However we still need to be disiplined in the way we use this facility otherwise we could very easily overwrite a memory location that contains some data needed in another part of the program.

When we access the contents of a memory location through a pointer we perform an operation called dereferencing. To access the contents of the location 5 we would write

	*5
This looks like multiply by 5, but the context in which the * is used means it cannot be a multiply. XCSB distinquishes between the multiply and dereference operators by context. When the * is used as binary operator it is taken to mean multiply, when it is used as a unary operator it is taken to mean dereference.

Binary * operator

Unary * operator In general binary operators have values, variables or sub-expressions on both the left and right side. Unary operators only operate on a value, variable or sub-expression immediately to their right.

On the PIC address 5 in the data space is the I/O port PORTA. The following statement sets bit 0 of PORTA

	*5 = *5 | 1
This is equivalent to
	(*5) = (*5) | 1
Although a pointer is a number and we can use a number directly, we normally store pointers in variables.

Any variable that returns an integer can be used to store a pointer since the pointer is a number that corresponds to an address in memory. The derefernce opererator, when applied to a number (whether it is a constant or a variable), is the important component when using a pointer to access memory. However if we explicitly declare a variable as a pointer variable the compiler is given more information about what the pointer variable points to and how to access the data when it is derefernced.

A pointer variable that points to a long variable is declared as:

	long	*PTR

Here the * character before the variable name tells the compiler that the variable is a pointer variable and the long keyword tells the compiler that the pointer is actually pointing to a long variable (kind of backwards but it makes sense once you get the hang of it)

We can declare a pointer variable called PTR, assign it the value 5 then use the the indirect variable *PTR to access PORTA so:

	char	*PTR

	PTR = 5

	*PTR = *PTR | 1
Note that we assign the value 5 to PTR before we actually use PTR as a pointer variable. 5 is the address of PORTA

Normally when we invent variables (including arrays), we do not know what address the compiler assigns to them (unlike PORTA which is fixed in hardware). So we need some mechanism by which we can discover the address the compiler has assigned to a variable (or array) and assign that address to a pointer variable.

The address operator fulfills this requirement. When we apply the address operator to a variable or array or even a pointer variable, the compiler produces code that returns the address of that variable (or array) and not the value of it.

We discover the address of a variable by applying the address operator (which is the & character) to it like so:

e.g.
	char	*PTR
	char	FRED

	PTR = &FRED
This looks like a binary AND, but the context in which the & is used means it cannot be an AND operation.

The following leaves the value 45 in variable FRED

	FRED = 1

	PTR = &FRED

	*PTR = *PTR + 2

	FRED = FRED * 3

	FRED = 5 * *PTR

This is equivalent to:

	FRED = 1

	PTR = &FRED

	(*PTR) = (*PTR) + 2

	FRED = FRED * 3

	FRED = 5 * (*PTR)
Because of the way PIC processors uses seperate RAM and CODE space memory, it is possible for an address that points to CODE to also be valid for RAM. To distinguish between pointers that point to CODE and pointers that point to RAM, XCSB requires that CODE space pointers be declared as pointers to constant data. The following pointer declaration declares a pointer to CODE space memory.
e.g.
	char	* const PTR
The important distinction between it and a declartaion to a RAM pointer is the const keyword between the * and the name of the pointer variable (in this case PTR). NOTE that the pointer variable itself, although pointing to constant data, can still be located in RAM so that it can be changed while the program is running.

A pointer variable (non-changing) that is itself to be stored in the CODE space would be declared are:

e.g.
	const char   * const PTR
However since we would not be able to modify it at run time, we would have to declare it in an initialised manor
e.g.
	const char   * const PTR = BERT
This would yeild a pointer called PTR which would point to BERT in the CODE space. Perhaps more useful would be an array of pointers.
e.g.
	const char   * const PTR = BERT, JACK, PHIL

NOTE: XCSB cannot currently handle pointers to the data EEPROM space