Nachos processes are formed by creating an address space, allocating physical memory for the address space, loading the contents of the executable into physical memory, initializing registers and address translation tables, and then invoking machine::Run() to start execution. Run() simply ``turns on'' the simulated MIPS machine, having it enter an infinite loop that executes instructions one at a time).
Stock Nachos assumes that only a single user program exists at a given time. Thus, when an address space is created, Nachos assumes that no one else is using physical memory and simply zeros out all of physical memory (e.g., the mainMemory character array). Nachos then reads the binary into physical memory starting at location mainMemory and initializes the translation tables to do a one-to-one mapping between virtual and physical addresses (e.g., so that any virtual address N maps directly into the physical address N). Initialization of registers consists of zeroing them all out, setting PCReg and NextPCReg to 0 and 4 respectively, and setting the stackpointer to the largest virtual address of the process (the stack grows downward towards the heap and text). Nachos assumes that execution of user-programs begins at the first instruction in the text segment (e.g., virtual address 0).
When support for multiple user processes has been added, two other Nachos routines are necessary for process switching. Whenever the current processes is suspended (e.g., preempted or put to sleep), the scheduler invokes the routine AddrSpace::SaveUserState(), in order to properly save address-space related state that the low-level thread switching routines do not know about. This becomes necessary when using virtual memory; when switching from one process to another, a new set of address translation tables needs to be loaded. The Nachos scheduler calls SaveUserState() whenever it is about to preempt one thread and switch to another. Likewise, before switching to a new thread, the Nachos scheduler invokes AddrSpace::RestoreUserState. RestoreUserState() insures that the proper address translation tables are loaded before execution resumes.