next up previous contents
Next: Nachos Filesystem Up: User-Level Processes Previous: System Calls and Exception

Execution Trace of User-Level Process

Consider the simplest Nachos program, halt.c, which invokes the ``halt'' system call and does nothing else. Its source code is shown in Figure 1

Figure 1: Source for the program halt.c

When compiled, gcc -S generates the assembly language code shown in figure 2 (line numbers and additional comments have been added for clarity). The only instruction that directly relates to invoking the ``halt'' system call is given in line 27. The jal instruction executes a jump that transfers control to the label ``Halt''. Note that there is no label called ``Halt'' in this program. The code for ``Halt'' can be found in the file start.s. Lines 1-21 are assembler directives that don't actually generate any instructions. Lines 22-25 perform the standard procedure call linkage operations that are performed as part of starting execution in a new subroutine (e.g., saving the return address and allocating space on the stack for local variables). Line 26 is a call to a gcc-supplied library routine that Unix needs to execute before your program normally begins execution (it is not needed in Nachos, so a dummy routine is provided that does nothing). Lines 29-33 provide the standard code for returning from a procedure call, effectively undoing the effects of lines 22-25 (e.g., fetch the saved return address and then jump back to it).

Figure 2: Source for the program halt.c

The actual instructions for making system calls are found in start.s. Figure 3 shows the subset of that file that is used by the halt program. Again, lines 1-7 are assembler directives rather than instructions. Line 8 is the first actual instruction, and simply calls the procedure main, e.g., the main program in halt.c. Lines 9-10 are executed whenever the call to main returns, in which case we want to tell Nachos we are done via the ``exit'' system call.

System calls are invoked at runtime by placing a code for the system call in register 2 and then executing the ``syscall'' machine instruction. The ``syscall'' instruction is a trap instruction, meaning that the next instruction to be executed will be the first instruction of the trap handler. In Nachos, this effectively means that execution continues now in the procedure ExceptionHandler. Consider lines 15-18, the steps involved in making an ``exit'' system call. Line 16 places a code for ``exit'' in register r2, and line 17 performs the actual system call. Line 18, the first instruction that will be executed after the system call simply returns to the caller. Note that the Exit system call normally won't return (if coded correctly!), but a return is provided anyway.

Figure 3: Instructions in start.s used by the program in halt.c

The actual steps in converting the halt.c source code into an executable program are shown in Figure 4. Line 1-3 generate object code from the halt.c and start.s source files. Line 5 creates an executable binary. Note that listing start.o before halt.o insures that the code in start.s resides before that of the main program. Finally, line 6 translates the executable into Noff format, making it ready to execute under Nachos.

Figure 4: The output from make when compiling halt.c.

The utility disassemble can be used to show the actual instructions in the halt binary. The result of running disassemble on halt.coff (NOT halt) is given in Figure 5. The instructions are the same as described above, but the code is somewhat harder to understand because the labels have been replaced with addresses.

Figure 5: The disassembled output of the executable for the halt.c program.

next up previous contents
Next: Nachos Filesystem Up: User-Level Processes Previous: System Calls and Exception

Thomas Narten
Mon Feb 3 15:00:27 EST 1997