2013: Advent Computing: Writing for a computer

by on December 6, 2013

A number can represent some sort of “instruction” to a computer, and what instruction a given number means is determined by that computer’s “machine language”. The number sequence “27, 48, 19” might mean “store the number 48 in the bit of memory at address 19”, while “82, 161, 8, 24” might mean “compare the numbers at the bits of memory at addresses 161 and 8, and if they’re equal, start running instructions in the bit of memory starting at address 24”. Simple, right?

Unsurprisingly, when computer programmers sit down and write programs, they don’t just type in numbers. They could, but it would be incredibly difficult and error-prone. Some programmers do use something called “assembly language”, though. I’ve used it a couple of times myself for very small parts of a program, and I know of some reasonably large programs written entirely in assembly language. Assembly language lets you type simple mnemonics that correspond to the numbers in the machine language, which can then be run through an “assembler” which will convert those mnemonics to the actual machine language.

The assembler will also do useful things like checking each individual instruction has the correct number of “operands” or “arguments” – the things that tell the computer what to operate on. In the “27, 48, 19” example above, that might be written as “STORE 48 19” in an assembly language, and the assembler would warn you if you had too many or two few numbers after the instruction.

Assembly language has a whole bunch of problems, however. Firstly, you’re effectively writing programs using a more readable version of your computer’s machine language. Which is great if your program is only going to run on that specific type of machine, but not so useful if you might ever want to run on a different machine. Swapping between AMD and Intel processors (the two most common processors in home PCs) can cause problems, and there are even considerable variations within Intel and AMD’s own lines. They have similar, but certainly not identical, machine languages.

Another problem is that, while assembly language is certainly easier to read than simple lists of numbers, it’s still not exactly readable. Which makes it hard to understand as you’re writing it, and hard to understand when you come back to read it another day, after someone found a bug and you need to fix it.

As a result, assembly language is more often used for “disassembly”, where you have a program and want to dig inside it, at the level the computer sees, to try to find a problem. Because each assembly mnemonic corresponds directly with a number from the machine language, a disassembler can tell you exactly what instructions a program is running at a given point, which can help in finding some really nasty bugs.

For writing programs, we tend to use “compiled” languages, or alternatively “scripted” languages. Those are for tomorrow.

Leave a Reply