CS140 Lecture notes -- Intro

  • Jim Plank
  • Directory: ~plank/cs140/Spring-1999/notes/Intro
  • Lecture notes: http://www.cs.utk.edu/~plank/plank/classes/cs140/Spring-1999/notes/Intro
    This lecture is a review of compilation, C, and a little computer organization.

    Basic computer organization

    From the outside, a computer looks something like:

    The most notable things are the screen, keyboard, mouse, etc. However, from an architectural point of view, your computer looks like this:

    The Central Processing Unit (CPU) does all the work -- the way it does this is by loading an instruction from memory into its instruction register, and then performing that instruction. It does this once per clock cycle. Instructions fall into a few categories:

    The Operating System is the program that oversees all activity of the computer. I won't go into detail on how it works, but it manages all the parts of the computer, such as what program is running, what is in memory, and what the peripherals are doing. Any activity to/from the peripherals or the network goes through the operating system.

    So what is a program? It is a file that gets loaded into memory. It has instructions and data. The instructions get loaded into the instruction register and direct the CPU. The data goes to/from registers.

    When you write a program in C, it must be compiled into the kind of file that can be loaded into memory. I will call these files executables, or sometimes ``a.out'' files. You can't read these because they are zeros and ones that only have meaning to the CPU. Just let it be known that they have instructions and data that will be loaded into memory by the operating system, and will then drive the CPU as depicted above.


    Compiling C programs

    In CS102, you learned how to compile a C program into an a.out file. For example, in this directory (/blugreen/homes/plank/cs140/Spring-1999/notes/Intro), there is the C program hw.c:
    UNIX> cat hw.c
    #include < stdio.h >
    
    main()
    {
      printf("Hello world!\n");
    }
    UNIX>
    
    In CS102 you learned a simple way of compiling this program:
    UNIX> gcc hw.c
    
    This creates a file called a.out, which you can execute:
    UNIX> ls a.out
    a.out*
    UNIX> a.out
    Hello world!
    UNIX> 
    
    When you typed a.out, the operating system loaded the contents of the file a.out into memory, and then the CPU started to execute the instructions of a.out. What this did was instruct the operating system to print ``Hello world!'' to the screen. Fortunately, the programming language C makes this pretty straightforward.

    Now, you don't have to always compile in this simple way. You can use the -o option to gcc to name the executable file something besides a.out. For example, here we'll name it hw:

    UNIX> gcc -o hw hw.c
    UNIX> ls hw
    hw*
    UNIX> hw
    Hello world!
    UNIX> 
    

    Compiling Multiple C Programs into One Executable

    You don't have to have all of your C program in one file. For example, if your file contains multiple procedures, you can spread them over multiple files. For example, look at the files callprintme.c and printme.c. The first one defines a main() procedure that calls the procedure printme() three times. In printme.c, the procedure printme() is defined to print ``Hi, I'm Jim.'' Thus, if we compile these two files together, we should get an executable that prints ``Hi, I'm Jim'' three times.

    The simple way to do this is to make a simple call to gcc with the C files, and make the a.out file:

    UNIX> gcc callprintme.c printme.c
    UNIX> a.out
    Hi, I'm Jim
    Hi, I'm Jim
    Hi, I'm Jim
    UNIX> 
    
    However, doing this kind of compilation for bigger programs ends up taking a long time. To solve this problem, gcc can be used to turn C files into object files. These have the .o extension. Like the a.out files, the object files are unreadable by humans, but they are written in such a way that gcc can make executables from them very quickly. To make an object file from a C file, use the -c option to gcc:
    UNIX> gcc -c callprintme.c
    UNIX> ls call*
    callprintme.c   callprintme.o
    UNIX> gcc -c printme.c
    UNIX> ls printme*
    printme.c   printme.o
    UNIX> 
    
    To make an executable from object files, simply call gcc on them just like you would .c files. If one of the object files defines the main() procedure, and all procedures that you use are defined in the object files, then it will create an executable for you. This is called linking:
    UNIX> gcc -o printme callprintme.o printme.o
    UNIX> printme
    Hi, I'm Jim
    Hi, I'm Jim
    Hi, I'm Jim
    UNIX> 
    
    If you try to make an executable and you don't include enough object files, then gcc will give you an error saying that a procedure is ``undefined.'' For example, suppose I try to link callprintme.o without printme.o. This means that the printme() procedure is undefined, and gcc will flag this as an error:
    UNIX> gcc -o printme callprintme.o
    Undefined                       first referenced
     symbol                             in file
    printme                             callprintme.o
    ld: fatal: Symbol referencing errors. No output written to printme
    UNIX> 
    
    Get used to compiling C files into object files and then linking the object files into executables. You'll be doing this a lot.

    File permissions

    In Unix, you can specify who can see your files. For example, if I do a ``long listing'' of the files in this directory, the first column of information tells me who can see my files:
    UNIX> ls -l
    -rw-r--r--   1 plank         153 Aug 25 10:57 1to10.c
    -rw-r--r--   1 plank         235 Aug 25 10:57 1ton.c
    -rw-r--r--   1 plank         252 Aug 25 10:57 1ton2.c
    -rw-r--r--   1 plank         277 Aug 25 10:57 1tonrepeat.c
    -rwxr-xr-x   1 plank        5120 Aug 25 10:57 a.out
    -rw-r--r--   1 plank        4628 Aug 25 10:57 arch.gif
    -rw-r--r--   1 plank          70 Aug 25 10:57 callprintme.c
    -rwxr-xr-x   1 plank        4888 Aug 25 10:57 hw
    -rw-r--r--   1 plank          59 Aug 25 10:57 hw.c
    -rw-r--r--   1 plank       12007 Jan 19 08:25 index.html
    -rw-r--r--   1 plank         223 Aug 25 10:57 printalpha.c
    -rw-r--r--   1 plank          62 Aug 25 10:57 printme.c
    -rw-r--r--   1 plank         258 Aug 25 10:57 read10.c
    -rw-r--r--   1 plank         415 Aug 25 10:57 read10b.c
    -rw-r--r--   1 plank        1291 Aug 25 10:57 srm.gif
    -rw-r--r--   1 plank         252 Aug 25 10:57 sumcl.c
    -rw-r--r--   1 plank         315 Aug 25 10:57 sumcld.c
    -rw-r--r--   1 plank         267 Aug 25 10:57 twowords.c
    UNIX>
    
    The first four characters in the listing tell me whether I can read/write/execute my files. For example, the -rwx in a.out tell me that I can read, write and execute a.out. Similarly, I can read and write callprintme.c, but not execute it. This is because it is not in the proper format for the operating system to load into memory (in order to get it into the proper format, I have to compile it into an executable).

    The last three characters in that first column tell me what others can do with this file. For example, the r-x in a.out tell me that others can read and execute, but not write the a.out file. Similarly, others can read, but neither write nor execute callprintme.c.

    You can change the protections on your files with the chmod command. Learn how to use it (ask your TA's if you don't know). You should not let anyone read your lab files. If they can, then they can plagiarize, and that has happened many times in previous classes. If someone plagiarizes from you, you will get a zero because could have prevented it. You have been warned.