\documentclass{article}
\usepackage{myMac}
\usepackage{multirow}

\title{{\small Operating Systems V22.0202, Yap\hfill Fall 2007}
	\\[1in]
	Notes on Systems Programming in C }

\begin{document}
\maketitle
\section{Mechanics of Compilation}

The simplest way to compile a C program \ttt{myprog.c}
	is to type:
	
		\ttt{> gcc myprog.c}
		
	Assuming successfull compilation, the output is an executable
	file called \ttt{a.out} (in unix) or \ttt{a.exe} (in cygwin).
	But in this invocation, you are calling more
	than just the compiler!

	\benum
	\item
	First, the compiler invokes a PREPROCESSOR
	to handle lines that begins with a "\#".
	Macro calls are also handled by the preprocessor.
	\item
	The compiler (gcc) translates your preprocessed program
	into assembly language {\em but in symbolic terms}.
	E.g., a store instruction will read "STORE VAR\_A"
	where VAR\_A is a variable name.
	\item
	This output is processed by another program
	called the ASSEMBLER that converts "STORE VAR\_A"
	into a binary word (with VAR\_A resolved into a
	numeric address).
	If you stop the process the this point
	(with the \ttt{-c} option) (see below).
	\item
	Next, gcc calls the LINKER (or link editor) which
	builds the executable program by linking the object file to the
	library routines.
	\eenum
 
   	Suppose you want to prevent the compiler from calling the linker
	and loader.  Then
	you type
	
		\ttt{> gcc myprog.c -c}
		
	(so -c means "just compile").  This will produce
	the output file \ttt{myprog.o}, called an "object file".

	If you want to create an executable from myprog.o,
	you can now call the loader directly:
	
		\ttt{> ld -lc myprog.o}

	This will produce the \ttt{a.out} or \ttt{a.exe} you expected.
	NOTE: that \ttt{ld} must be explicitly given the library \ttt{-lc}.

	Q: Why would you want to do this round-about way to producing
	\ttt{a.exe}?
	A: Your \ttt{myprog.o} file may contain routines that
	can be linked to other programs that wants to use them.
	This saves time on re-compiling (an issue in large projects).
   
   	This brings us to the subject of libraries.
	Every program refer to library routines.  For instance, \ttt{main()}
	is actually the name of a library routine.  The standard C library
	routines are found in a library file named \ttt{libc.a}.
	This library file is usually found in the system include
	directory called \ttt{/usr/lib}.
	The file \ttt{libc.a} is basically a list of
	a bunch of object files (\ttt{*.o})!

	CONVENTION:
	All library files are named \ttt{libXXX.a}
	where \ttt{XXX} is any identifier.
	To ask the compiler to search the library \ttt{libXXX.a},
	you give it the option \ttt{-lXXX}.
	Thus, if \ttt{XXX=c}, we use the option \ttt{-lc} as
	in our illustration.

	Suppose your program uses a mathematical library routine like "sqrt".
	This is in another library called \ttt{libm.a}.  In this case, you MUST
	tell gcc to search the \ttt{libm.a}.  You should now invoke
		
		\ttt{gcc myprog.c -lc -lm}

	If you have several libraries to search,
	give each one as a separate \ttt{-lXXX} option.  
	Below, we provide more notes on 
	Runtime libraries and Shared libraries.

   	QUIZ: what is odd about this command line:
	\ttt{> gcc myprog.c -lm -c}.

\section{Run-Time Organization of C Programs}

The compiled code is loaded into memory in three
segments (code, data and stack):

\ignore{% do good!
\begin{center} \begin{tabular}{l | l | l}
	\cline{2-2} & \\
	& 	& \\
	&  Code Segment & read-only, function blocks \\
	& 	& \\
	\cline{2-2} & \\
	&  Data Segment & \\
	& 	&  Static allocations from global variables\\
	& 	& \\
	\cline{2-2} & \\
	& 	& \\
	&  Stack Segment & push down stack grows upward\\
	& 	& \\
	\cline{2-2} & 
\end{tabular} \end{center}
}

\bigskip\hrule\bigskip
\myfignew{process-image}{Process Image}{proc-image}{.6}
\hrule\bigskip

As illustrated in \refFig{proc-image}, these
segments are laid out in a specific order:
(starting from lowest address \ttt{0000} to highest \ttt{FFFF})
(1) code segment, (2) the data segment, 
(3) a gap of free space, and finally
(4) the stack segment.

Because the gap is flexible, we can arrange the top of the stack in
the stack segment to coincide with
the highest address (\ttt{FFFF} in the figure).
Then as the stack grows during runtime,
it grows into the free space found
it the gap.  

The data segments are subdivided into initialized
and uninitialized data sections, and a third section
for heap allocation.  The initialized and uninitialized
data sections have fixed size.  Like the stack,
the heap can grow during run-time.  So it is arranged
to be adjacent to the gap of free space.

During runtime, we get an error when the gap between the heap and stack
is reduced to nothing.  We either have a ``stack overflow''
or an error while attempting to obtain space from the heap.

\section{System Calls}

In Unix and C, there is no difference between
a system call and an ordinary function call!

%Consider the following system call to display system information:
\begin{verbatim}
/***************************************************
 * io.c: minimal cat version (from Kernighan and Pike) 
 * This program will echo whatever you type.
 * To terminate, type control-D
 ***************************************************/

#define SIZE 512	// arbitrary

int main() {
	char buf[SIZE];
	int n;

	while ((n = read(0, buf, sizeof buf)) > 0)
		write( 1, buf, n);
	return(0);
}
\end{verbatim}

The function \ttt{read(...)} is actually a system call.

\myTail
