Areas of memory
Often running C programs are considered to have several segments or sections, distinct areas of memory.
- Text: For program code
- Data: For global and static variables
- Data (more specialized): For initialized variables
- BSS: For uninitialized variables — Required to be 0 in ANSI-C
- Stack: For local variables
- Heap: For dynamically allocated memory
Some compilers/architectures may place const variables in read-only segments. In many compilers/architectures each shared or dynamic-link library has its own segments for text and data. This allows several running programs to share common library routines.
Example C program using all areas
uint32_t Aglobal[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
const uint32_t Aconst[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
uint32_t Abss[10] ;
void subr(void) {
uint32_t ASlocal[10] ;
return ;
}
int main(int argc, char** argv) {
uint32_t AMlocal[10] ;
uint32_t *Amalloc ;
Amalloc = (uint32_t *)malloc(10*sizeof(uint32_t)) ;
subr() ;
return (EXIT_SUCCESS);
}
Some address for those variables
| Variable | 64-bit linux | 16-bit PIC |
|---|---|---|
Aglobal | 0000000000600B00 | 0850 |
Aconst | 00000000004007A0 | 9072 |
Abss | 0000000000600B60 | 0878 |
Amalloc | 0000000000897010 | 09AE |
AMlocal | 00007FFF09C89C80 | 09F2 |
ASlocal | 00007FFF09C89C30 | 0A24 |
main | 0000000000400541 | 1204 |
subr | 0000000000400514 | 11EA |
printf | 00000000004003F8 | 0459 |
Pointers
Examples of functions using pointers
void swap(int *p, int *q) {
int t = *p ;
*p = *q ;
*q = t ;
}
void sort(int *mn, int *mx) {
if (*mn > *mx) {
swap(&mn, &mx) ;
}
}
char *firstLetter(char *msg) {
while (*msg && !isalpha(*msg)) {
++msg ;
}
return msg ;
}
char *firstLetter(char *msg) {
while (*msg && !isalpha(*msg++)) ;
return msg ;
}
Examples of implementing pointers on the PIC
MOV x,W2 ;; W2 <- x
MOV #x,W3 ;; W3 <- &x
MOV [W3],W2 ;; W2 <- *W3
MOV W5,[W3] ;; *W5 <- W5
MOV [W6],[W7] ;; *W7 <- *W6
MOV [W8++],[++W9] ;; *++W9 <- *W8++
Arrays and pointers in C
In C, an array declaration defines a constant pointer
to a sequence of data values. For example:
int A[] = {2, 3, 5} ;
is really the same type as:
int * const A = {2, 3, 5} ;
Incidently, this is not the same as:
const int A[] = {2, 3, 5} ;
or
const int * A = {2, 3, 5} ;
Finally, all you Java programmers should be warned that the following,
while encouraged in Java, is forbidden in C:
int[] A = {2, 3, 5} ;
Pointer arithmetic in C
If p is the address of an integer in C, then
p+i is the address of the i’th
integer stored in memory after the place p points to.
This interpretation means that p[i] can be
considered an abbrevation for *(p+i).
Two equivalent C loops
for (i=0; i<1000; ++i) {
A[i] = B[i] ;
}
int *pA = &A[0] ;
int *pB = &B[0] ;
for (i=0; i<1000; ++i) {
*pA++ = *pB++ ;
}
Examples of implementing arrays on the PIC
Assume that c is an array of 8-bit characters.
Each character will require one byte.
MOV.B W2,x+5 ;; c[5] <- W2
MOV.B x+5,W2 ;; W2 <- c[5]
MOV.B W2,[W4+5] ;; W4[5] <- W2
MOV.B [W4+5],W2 ;; W2 <- W4[5]
MOV.B [W4+W5],W2 ;; W2 <- W4[W5]
Now, assume that x is an array of 16-bit integers.
Each integer will require two bytes.
MOV W2,x+10 ;; x[5] <- W2
MOV x+10,W2 ;; W2 <- x[5]
MOV W2,[W4+10] ;; W4[5] <- W2
MOV [W4+10],W2 ;; W2 <- W4[5]
ADD W5,W5,W0 ;;
MOV [W4+W0],W2 ;; W2 <- W4[W5]
Getting the right address
The following two lines of PIC code will increase the value stored
in W7 by one and the value stored in
W8 by two.
MOV.B [++W7],W0
MOV [++W8],W0
Faster loops
The PIC instruction set has a REPEAT instruction
that is designed to make loops a bit more succinct.
Here is an implementation of
the C for shown above that copied the first
1000 elements of B into A.
MOV #A,W5
MOV #B,W6
REPEAT #999
MOV [W6++],[W5++]
A brief look at structure
C has a non-heterogenous data structure called the struct,
resembling a method-less class in Java, where several fields
are stored within a collection.
struct point3D {
int x ;
int y ;
int z ;
}
struct point3D P ;
P.x = 5 ;
P.y = P.x + 1 ;
P.z = 7 ;
When implemented the fields are stored at fixed offsets from the beginning of the structure.
MOV P+2,W5 ;; W5 <- P.y
MOV W5,P+4 ;; P.z <- W5
Trying out an example
int V[500] ;
int H[100] ;
int i ;
for (i=0; i<100; ++i) {
H[i] = 0 ;
}
for (i=0; i<500; ++i) {
++H[V[i]] ;
}