CSCI 255 — Chapter 6 miscellany

The PowerPoint

Calling functions

Accessing variables

How do functions access variables?

Variables in registers

The first few arguments to a function are stored in $a0 to $a4. The return value is stored in $v0 (along with $v1 for 64-bit returns).

With the exception of arrays and structures, most local variables of the functions can be stored in the ten caller saved temporary registers, $t0 to $t9.

Variables on the stack

The automatic (local) variables of C that can’t be fit into registered, will be stored on the stack. At compilation time, automatic variables are allocated registers or space within a function’s stack frame. Variables on the stack will be addressed at a fixed offsets from either the stack or frame pointer.

These means that a variable that is allocated at address X bytes from the stack pointer, will be loaded with an instruction similar to the following:
      lw    $tv,X($sp)

All local arrays of a function must be stored on the stack. Suppose, the base of an array starts X bytes from the stack pointer. In that case, the address of the array can be loaded into register with an instruction similar to the following:
      addi  $ta,$sp,X
Think about it.

Variables in the data area

Global variables are stored in the data area of the program’s memory. In general, the address of a global variable cannot be determined at compile time. In this case, the object code contains relocation information that specifies the name and type of global variables and the locations of instructions that reference global variables.

On the PIC32, the location of global variables can be determined when the object modules are joined together to form the executable at link time. Let’s say that an assembly program writes the following statement:
      lw    $tv,X
where X is an integer.

Now suppose the linker has determined that X will be stored at memory location 0xA0BEEF44. Then the lw will be implemented as a two instruction sequence:
      lui   $tv,0xA0BE
      lw    $tv,0xEF44($tv)

If you wish to load the address of X, that is, to implement
      la    $tv,X
Then the following two instruction sequence is used:
      lui   $tv,0xA0BE
      ori   $tv,$tv,0xEF44

An optimization

To save an instruction, the compiler and linker will conspire to allocate small data items in the ”small“ region, also known as .sdata and .sbss, no more than 64 KB in size.

At run time (also known as execution time), the global pointer $gp is initialized to an address near the middle of the small data region. At link time each variable stored in the small data area is associated with an offset from the global pointer. Now small global data can be addressed with a fixed offset from a the global pointer very similar to how automatic variables are addressed at fixed offsets from the stack or frame pointer.

In case of dynamic libraries

The Global Offset Table (GOT) is often used with dynamic libraries because the address of a global will not be known until load time. In these situations, a unique Global Offset Table, containing the address of each global variable is associated with each function and populated when the program is loaded in memory. The GOT is effectively a collection of pointers to a function’s global variables.