The 'C' programming language was designed and developed
by Brian Kernighan, and Dennis Ritchie at The Bell Research
Labs. 'C' is a Language specificallycreated in order
to allow the programmer access to almost all of the
machine'sinternals - registers, I/O slots and absolute
addresses. However, at the same time,'C' allows for
as much data hiding and programme text modularisation
as is needed to allow very complex multi-programmer
projects to be constructed in an organised and timely
fashion. During the early 1960s computer Operating Systems
started to become very much more complex with the introduction
of multi-terminal and multi-process capabilities. Prior
to this time Operating Systems had been carefully and
laboriously crafted using assembler codes, and many
programming teams realised that in order to have a working
o/s in anything like a reasonable time this was now
longer economically feasible. This then was the motivation
to produce the 'C' Language, which was first implemented
in assembler on a Digital Equipment Corporation PDP-7.
Of course once a simple assembler version was working
it was possible to rewrite the compiler in 'C' itself.
This was done in short order and therefore as
soon as the PDP-11 was introduced by DEC it was only
necessary to change the code generator section of the
compiler and the new machine had a compiler in just
a few weeks. 'C' was then used to implement the UNIX
o/s. This means, that a complete UNIX can be transported,
or to use the simple jargon of today; 'ported to a new
machine in literally just a few months by a small team
of competent programmers. Enough of the past. Lets see
the various actions, or compilation phases through which
the `C' compilation system has to go in order that your
file of `C' program text can be converted working program.
Assuming that you are able to work an editor and can
enter a script and create
a file. Please enter the following tiny program.
#ident "@(#) Hello World - my first program"
#include <stdio.h>
char *format = "%s",
*hello = "Hello World...\n";
main()
{
printf ( format, hello );
}
Now save it in a file called hello.c. Lower case is
allowed - encouraged, no
less - under the UNIX operating system.
Now type:
cc -o hello hello.c
The computer will apparently pause for a few moments
and then the
Shell, or Command Line Interpreter prompt will re-appear.
Now type:
hello
Lo and behold the computer will print
Hello World...
Let's just look at what the computer did during the
little pause.
The first action is to activate a preliminary process
called the pre-processor.
In the case of hello.c all it does is to replace the
line
#include <stdio.h>
with the file stdio.h from the include files library.
The file stdio.h provides us with a convenient way of
telling the compiler that all the i/o functions exist.
There are a few other little things in stdio.h but they
need not concern us at this stage.
In order to see what the pre-processor actually outputs,
you might like to
issue the command:
cc -P hello.c
The 'cc' command will activate the 'C' compilation
system and the -P option will stop the compilation process
after the pre-processing stage, and another file will
have appeared in your directory. Have a look, find hello.i
and use the editor in view mode to have a look at it.
So issue the command:
view hello.i
You will see that a number of lines of text have been
added at the front of the hello.c program. What's all
this stuff? Well, have a look in the file called /usr/include/stdio.h
again using the view command.
view /usr/include/stdio.h
Look familiar?
Now the next stage of getting from your program text
to an executing program is the compilation of your text
into an assembler code program. After all that is what
a compiler is for - to turn a high level language script
into a program.
Lets see what happens by issuing the command
cc -S hello.c
Once again there is another file in your directory
- this time with a .s
suffix.
Lets have a look at it in the same way as the .i file
view hello.s
You will doubtless notice a few recognizable symbols
and what appears to be a pile of gibberish. The gibberish
is in fact the nmemonics for the machine instructions
which are going to make the computer do what you have
programmed it to do.
Now this assembler code has to be turned into machine
instructions.
To do this issue the command.
cc -g -c hello.s
Now, yet again there is another file in your directory
- this time the suffix is ".o". This file
is called the object file. It contains the machine instructions
corresponding exactly to the nmemonic codes in the .s
file. If you wish you can look at these machine codes
using one of the commands available to examine object
files.
dis -L -t .data hello.o >hello.dis
The output from these commands won't be very meaningful
to you at this stage, the purpose of asking you to use
them is merely to register in your mind the fact that
an object file is created as a result of the assembly
process.
The next stage in the compilation process is called
by a variety of names -
"loading", "linking", "link
editing". What happens is that the machine instructions
in the object file ( .o ) are joined to many more instructions
selected from an enormous collection of functions in
a library. This phase of the compilation process is
invoked by the command:-
cc -o hello hello.o
Now, at last, you have a program to execute! So make
it do it's thing by putting the name of the executable
file as a response to the Shell or Command Line Interpreter
prompt.
hello
Presto, the output from your program appears on the
screen.
Hello World...
You are now allowed to rejoice and have a nice warm
fuzzy to hold!
You have successfully entered a `C' program, compiled
it, linked it, and
finally, executed it!
Having gone through all the various stages of editing,
pre-processing, compiling, assembling, linking, and
finally executing, by hand as it were, you can now rest
assured that all the stages are automated by the 'cc'
command, and you can forget how to invoke them! Just
remember that the computer has to do them in order for
you to have a program to execute.
The single command you use to activate the C Compiler
is:
cc -o hello hello.c
The word after the -o option is the name of the executable
file, if you don't provide a name here the compiler
dreams up the name "a.out". The source file
MUST have the .c extension otherwise the compiler complains
and stops working.
Notes:
The command names used in the above text are those
of standard UNIX,
Your particular system may well use a different name
for the 'C' compiler.
bcc - for Borland 'C'.
gcc - GNU 'C', which is standard on the Linux operating
system.
lc - Lattice 'C', available on IBM and clone P.C.s as
well as the Amiga.
Check in the Documentation which came with your compiler.
The same notions apply to the text editor.
Differences between 'C' and other languages.
In the years since 'C' was developed it has changed
remarkable little. This fact is a bouquet to the authors,
who had the vision and understanding to create a language
which has endured so well. The strengths and weaknesses
should be pointed out here.
The big plus is that it is possible to do everything
( well at least 99.9% ) in
'C' while other languages compel you to write a procedure,
subroutine or
function in assembler code.
'C' has very good facilities for creating tables of
constant data within the
source file.
'C' doesn't do very much to protect you from yourself.
This means that the resulting code executes faster than
most other high level languages, but a much greater
degree of both care and understanding is demanded from
the programmer.
'C' is not a closely typed language, although the newer
compilers are offering
type checking as part of the language itself as opposed
to having to use a
separate program for mechanised debugging.
'C' is a small language with very few intrinsic operations.
All the heavy work is done by explicit library function
calls.
'C' allows you to directly and conveniently access
most of the internals of the machine ( the memory, input
output slots, and CPU registers ) from the language
without having to resort to assembler code.
'C' compilers have an optimisation phase which can
be invoked if desired. The output code can be optimised
for either speed or memory usage. The code will be just
as good as that produced by an assembly code programmer
of normal skill - real guru programmers can do only
slightly better.
Lesson # 1, #
2, # 3, #
4, # 5, #
6, # 7, #
8
|