Compilers

The best way to get your program logic running on a real computer is to use a high-level language, designed to help you think your way through your project, and create a program. Unfortunately, no computer can use that program directly. Instead, we need to use a tool to translate that file holding your program into a form that the machine you intend to use can understand.

That tool is tied tightly to the language you are using, and the actual machine you want to use. Even the same chip in a different operating system needs a different compiler. Change either and you need a different tool. Fortunately, the same compiler can often be found on different machines, so this is not a big problem.

Machine Language

The machine itself only understands a pile of binary data we call zeros and ones. (Actually, the machine sees these as voltages, typically zero volts and five volts, but that is a topic fr a computer engineer!).

To further complicate thins, computers can only do a limited set of very basic things, like this:

  • move this data item from one place to another
  • add two data items to get a result
  • compare two data items to see which is bigger
  • and so on

To make matters worse, every machine has a different set of codes for those things it can do. What a mess!

This is not a nice place to build a complex program, so humans have moved on to those high-level languages.

Assembly Languages

The first stop in getting away from zeros and ones was actually not much of a step. Humans created simple codes for those simple instructions the machine understands. They called this language assembly language, and it looks like this:

  • MOV R8, [mydata]
  • ADD R8, 10
  • CMP R8, 100

Ugly when you first see it, but WAY easier to figure out than the raw binary stuff the computer can actually run!

High Level Languages

A high level language lets yo focus on the work you want the machine to do:

int mydata = 90;

if( mydata + 10) > 100) mydata = 100;

Those three lines of assembly would actually be part of what it would take to process this line oc C++ code.

Humans are much happier now, especially programming humans!

Translating your Code

We need a tool that can read your program, written in some programming language, into those simple instructions the computer understands, so it can run your program.

Translating is a critical step, and the best tool for doing this is called a compiler. Not all languages are compiled, but programs written in all programming languages must be processed by some tool before they can be loaded into a computer and run.

In this set of notes, we will explore that translation process. The language I am using here is C++, since most compilers are written in this high-level language so the resulting tool will be fast. Oddly enough, the C++ compiler we use is actually written in C++. That brings up an interesting question:

  • how did the first c++ compiler get written?

The answer is tat it was written in another language first (like C, an older language that is actually part of modern C++). Once that compiler ran, they re-wrote it into C++ and fed it to itself! (Sounds dangerous). When the smoke cleared, they had a nice C++ compiler, written in C++! Cool

I have worked with many compilers for over 50 years now, and used to teach compiler design back in my Air Force days, when I taught at the Air Force’s graduate school.

In the notes in this section, we will look at how toy define a programming language in the first place, How you read a program written in that language and figure out what it wants us to do, then how we convert that pile of information into something the computer can actually run.

These notes are actually something I show to students in my computer architecture class, and they are part of building a processing tool called an assembler for a machine they design in software.

Here are the current notes available: