BACKSLASH Gallery Paris
Nov 7, 2019 – Dec 20, 2019
scenography by Daniel Hofstede
0110 1011 1101 0001 1001 Address, 20 bits
Although considered complicated and cumbersome by many programmers, this scheme also has advantages; a small program (less than 64 KB) can be loaded starting at a fixed offset (such as 0000) in its own segment, avoiding the need for relocation, with at most 15 bytes of alignment waste.
Compilers for the 8086 family commonly support two types of pointer, near and far. Near pointers are 16-bit offsets implicitly associated with the program’s code or data segment and so can be used only within parts of a program small enough to fit in one segment. Far pointers are 32-bit segment:offset pairs resolving to 20-bit external addresses. Some compilers also support huge pointers, which are like far pointers except that pointer arithmetic on a huge pointer treats it as a linear 20-bit pointer, while pointer arithmetic on a far pointer wraps around within its 16-bit offset without touching the segment part of the address.
RISC-V handles 32-bit constants and addresses with instructions that set the upper 20 bits of a 32-bit register. Load upper immediate lui loads 20 bits into bits 31 through 12. Then a second instruction such as addi can set the bottom 12 bits. This method is extended to permit position-independent code by adding an instruction, auipc that generates 20 upper address bits by adding an offset to the program counter and storing the result into a base register. This permits a program to generate 32-bit addresses that are relative to the program counter. The base register can often be used as-is with the 12-bit offsets of the loads and stores. If needed, addi can set the lower 12 bits of a register. In 64-bit and 128-bit ISAs,lui and auipc sign-extend the result to get the larger address. Some fast CPUs may interpret combinations of instructions as single fused instructions. lui or auipc may be good candidates to fuse with addi, loads or stores.