The Role of the CPU - to Run Programs
In this section, we will get to the whole point of the Processor - to execute programs. We will learn what a program is and an outline of how one is written. We will look then look at the various methodologies and architectures employed by processors to make the process of running a program as quick as possible.
OK... so we know that the CPU has a large number of transistors and these make up circuits, which in turn form registers and other higher-level organisations. So what? Well, the ultimate goal of the CPU is to do tasks asked of it - i.e. to run programs.
So what exactly is a program. At the level of the CPU, a program is simply a series of instructions that the CPU can understand and perform. The CPU understands these instructions in the form of machine language which is no more than streams of binary. However, these days no one writes real programs in machine language. If there are any that still do, then they're a little... erm... eccentric.
The next best thing is to write programs in assembly language, where each machine instruction of the resulting program is explicitly defined by a line of assembly source code. In assembly, these machine instructions are represented by 'near-English' mnemonics. Words like, ADD, INC, MOV, PUSH, POP. A program called an assembler converts these mnemonics into binary machine code.
That said, even assembly code is far too complicated an approach to create programs of the kind we see today. It's like using a tea spoon to dig the Channel Tunnel.
Instead, programmers use 'high-level' programming languages where the code they write much more closely resembles English. These programming languages take away much of the complexity of CPU programming. For example, they hide the need to understand registers their limitations. Once a program is written in such a language, we run this source code through a program called a compiler. Like an assembler, the compiler converts the near-English code into binary machine language that the processor can understand. This is called, not surprisingly, compiling.
Some programming languages are 'higher-level' than others. For example, Visual Basic is a very high-level language and is very easy to write with, because the programmer doesn't need to know anything about how a PC works. However, such languages have their drawbacks: because the language is far-removed from the level of the processor, you have little control over what the program actually does at the machine code level. You just have to trust the compiler to convert your source code into machine code that will perform efficiently.
The result is that a program written in VB (for example) will always slower than an equivalent program written in a lower-level language like C++. However, C++ is much more difficult to write with. The source code is much more difficult to comprehend. The programmer must have a certain amount of knowledge about how data is stored on a computer, and how this data can be accessed. With this in mind, the programmer has much more control over what happens at the level of the CPU. This makes such languages ideal for writing programs where speed, memory usage and efficiency are paramount.
The Pecking Order
Thus is born the pecking order or programmers. C++ programmers often consider themselves above VB programmers, thinking of VB as a toy for infants. Some of this attitude is also present in Java programmers, since it is syntactically so similar to C++ (although the lack of pointers and the presence of the garbage collector does make Java much more simple to code with). Of course, assembly coders consider themselves superior to all.
While I like to think there is some degree of merit to this attitude, one must remember that it is not always essential to know how a PC functions in order to write a good program. BUT, one must know how a PC functions to write a great program.
Different languages use different syntax and have varying levels of complexity. They all contain some variation of commands that look something like this:
int a = 10;
int b = 5;
int c = a + b;
While overly simple (and no real programmer would use three lines for something so trivial), these lines do represent valid commands in both C++ and Java. You don't need to be a rocket scientist to work out that they store the sum of the variables a and b into a third variable, c. When these three lines have been performed, the result is that the value 15 is stored in the integer variable c.
Whatever the language, in the end the result is always the same - a compiler converts the original 'English-like' source code (such as that shown above) into machine instructions that the processor can understand. (Actually, this isn't strictly true as some languages are not compiled into machine code before runtime, but rather are 'interpreted' line by line at runtime - these are called interpreted languages of which BASIC is an example.)
But even these simple instructions involve many steps for the CPU. And many considerations for the compiler. For example, where do the values 10 and 5 come from? Will they be stored in memory, to be pulled into registers when required? Or will they be supplied to the instruction in the form of immediate operands. A programmer need not concern himself with these details. But if you truly wish to understand how a CPU works, then you need to ask yourself these questions and start recognising the complexity of the machine!
Now move on to look at instructions and instruction sets.
|Just Too Good
Last updated: June, 2006 (DJL)