and 0s).
The goal of every programming language is to make programming simpler and easier. Unfortunately, because no one can define exactly what simpler and easier really mean, computer scientists keep creating new and improved programming languages that promise to make programming simpler and easier, at least until someone else invents another new and improved programming language.To understand how assembly language works, you must first understand how processors store and manipulate data. The processor is the “brain” of the computer that does all the work. By itself, the processor is fairly useless.
Think of Einstein's brain floating in a jar of formaldehyde. It may be one of the smartest brains in the world, but if it can’t communicate with the outside world, it’s completely useless as anything other than a very unusual paperweight. Like Einstein’s brain in a jar, your computer’s processor is useful only if it can communicate with the outside world. The processor communicates with the other parts of the computer through a series of wires called a bus.
When a processor needs to work with data, it retrieves it from another part of the computer (such as the hard disk or memory) and temporarily stores that data in a storage area called a register, as shown in Figure 1-1.
FIGURE 1-1: A processor uses its registers to temporarily store data.
The processor then edits the data in its registers and sends the changed data back to another part of the computer, such as the memory or hard disk.
So, computer programming progressed from physically rearranging wires and switches (with ENIAC), to flipping switches using 1s and 0s (with machine language), to telling the computer which data to store in which registers and how to manipulate that data (with assembly language).
A typical assembly language command might look like this:
mov al, 061h
This command tells the processor to move (mov
) the hexadecimal number 061h
into the specific register named al
. Other assembly language commands might tell the processor to add (add
) or subtract (sub
) a value from the number stored in a specific register.
When you use assembly language, you have to tell the processor what data to store in which registers, how to manipulate the data in the registers, and when to remove data out of the registers.
Sound tedious? It is. Although assembly language is far easier to understand and write than machine language, it's still too complicated to use for creating really big computer programs, like word processors or video games.
In the old days, most programs were written in assembly language, but as programs grew larger and more complicated, assembly language proved too cumbersome to write, edit, and modify.
The biggest problem with assembly language is that you need to manipulate the processor’s registers just to do the simplest tasks. If you wanted to add two numbers together, you’d have to tell the processor to store a number in a register, add a second number to the number in the register, and then yank the result out of the register.
Forcing people to know how to manipulate the processor’s registers before they can program a computer is like forcing people to know how their carburetor works before they can drive a car. Ideally, you don’t want to tell the processor how to manipulate data in its registers; you just want the processor to add two numbers without worrying about specific registers. So, to make computer programming even easier, computer scientists have hidden the technical details of manipulating registers by creating high-level languages.
Every processor understands only its own particular assembly language. So an Intel processor won’t understand the assembly language of an Advanced RISC Machine (ARM) processor and vice versa. However, some companies make processors that work identically to other processors. For example, a company called Advanced Micro Devices (AMD) makes processors that work just like Intel processors, so an assembly language program written for an Intel processor also works on an AMD processor.
Hiding the details of a computer with a high-level language
The whole purpose of high-level languages is to make programming more intuitive. So, rather than tell the computer to store the number 2
in register al
, add the number 3
to the number stored in register al
, and then yank out the result from register al
, high-level languages let you tell the computer what to do and not worry about how the computer does it. So, a typical high-level language command might look like this:
Total = 2 + 3
As you can see, high-level languages are much easier to read and understand, even if you know nothing about programming. Where assembly language forces you to tell the processor what to do and how to do it, high-level languages just let you tell the processor what to do.
Early popular high-level languages include Fortran (formerly FORTRAN, short for FORmula TRANslator), BASIC (short for Beginner's All-purpose Symbolic Instruction Code), COBOL (short for COmmon Business Oriented Language), and Pascal (named after the French philosopher Blaise Pascal).
Besides making programming more intuitive, high-level languages also make programming easier because a single high-level language command can do the work of a dozen (or more) assembly language commands.
A thousand lines of assembly language commands might do nothing more than multiply two numbers together. A thousand lines of high-level language commands might create a video game, a music player, or a stock market analysis program. By using high-level languages, programmers can spend more time being productive and less time worrying about the technical details of the computer.
Combining the best of both worlds with the C programming language
High-level languages isolate you from the technical details of programming, but by isolating you from these details, high-level languages also limit what you can do. So, as a compromise between assembly language (which can manipulate the processor) and high-level languages (which isolate you from the details of manipulating the processor), computer scientists created an intermediate language dubbed C.
The idea behind the C programming language is to give programmers the ability to manipulate the processor directly like assembly language, but also give them the chance to ignore these technical details, if they want, like a high-level language.
As a result, a C program doesn’t look as cryptic as assembly language, but it also isn’t as easy to read as a high-level language, as the following C program demonstrates:
#include <stdio.h>int main(void){ printf("Hello World!\n"); exit(0);}
Just by looking at this C program, you can probably figure out that it prints
Hello World!
on the screen. However, you may see a bunch of cryptic curly brackets, back slashes, and other odd symbols and characters that may make no sense whatsoever. Don’t worry. Just notice how confusing C programs can look while at the same time being somewhat understandable.