The 8086 is a 16-bit processor. One possibility for implementing some form of process isolation is to use the processor's segment registers (CS, DS, SS, ES). These allow a process's stack (SS), heap (DS, ES), and code (CS) reside in specific 64kB areas of a 1MB address space. This works by left shifting the 16-bit segment register by four bits and adding to that the 16-bit stack pointer (SS << 4 + SP
), instruction pointer (CS << 4 + IP
), or data address (e.g. CS << 4 + SI
), to obtain the 20 bits of the physical address.
Thus, through a suitable segment register setup one can isolate a process to at most 64kB, provided the process follows the convention of not altering the segment registers. For the requirements of C programs, where the heap and the stack must be addressable through the same 16-bit pointers, this convention restricts them to 64kB of data and 64kB of code. Although this might sound overly restrictive, remember that early Unix run on a PDP-11 with 64kB of RAM. Consequently, providing a 1MB memory for multiple processes with up to 64kB of code and 64kB of data is more than generous.
Furthermore, by manipulating segment registers and copying memory regions, a supervisor program can dynamically readjust memory regions as processes are created and destroyed in a way that's transparent to running processes. Early versions of Andrew Tannembaum's MINIX operating system relied on some of these ideas.