This is the start of a series, I hope, of articles building up the fundamentals of how computers work, and how we program them to do all the neat stuff they do.

The first thing to introduce is the concept that underlies the entirety of software engineering: Abstraction

Abstraction

How do we manage to walk? Walking requires a precise control over the muscles in your legs and arms, combined with a complex feedback loop from our senses telling us about uneven ground ahead, or when our left foot has touched the ground so we can begin lifting our right leg. When you stop to think about it it seems an impossible task, and yet we do it without thinking about it every day. How do we manage it?

The answer is that when we were young and learning to walk we had to solve all of those problems – which muscles to move in which sequence to go from crawling to standing up to walking, how to keep our balance and so on. This requires a lot of trial and error, and concentration, to achieve. But once we’ve worked on it and found out the best way to move our legs to get around, that gets filed away in our brains as a ’solved problem’. After that, any time you want to walk, your brain doesn’t have to consciously remember all the individual steps, it just invokes its stored ‘how to walk’ pathways which go off and do it automatically.

Having mastered walking you can build upon the concept to do such advanced things as running, dancing, playing football and so on. You can do these more complex things because your brain is free to concentrate on them rather than focussing on moving the muscles in your legs correctly.

This is the essence of abstraction; solve a basic problem once and you can use it as a building block to solve more complex problems with no additional work. The beauty of it is that once you’ve solved a problem once, you never have to worry about it again.

In computing, as we’ll see, some time ago people had to work out a way to get a computer to a) remember bits of information, and b) perform basic calculations on that information. These are quite complex problems involving very low level electronics. But now, with those problems solved, I as a programmer don’t have to worry about it. I know that if I ask the computer to add two numbers together and store the result it will do it. I don’t need to think about how it does it, which leaves my brain free to think about the problem I’m currently trying to solve.

With that in our minds, we’ll start at the most basic innards of a computer and in subsequent posts build upon those ideas to reach the heights of current computer science.

Transistors

The building blocks of all modern computers are transistors. The best way to think of a transistor is as a controlled gate – imagine a gate-keeper who sits by a gate who has a little light next to him telling him when to open it. When that light lights up he opens the gate and a stream of cattle, or cars, or football supporters stream through. In an electronics context a transistor has three connections; when a current flows to one of the connections (called either the base or gate) it triggers the transistor to allow a (potentially much large) current to flow between the other two connections (called either collector and emitter, or source and drain).  Look at the following circuit diagram:

Operation of a transistor as a switch

Operation of a transistor as a switch (from http://en.wikipedia.org/wiki/Transistor)

The transistor is the lower circle symbol, with a bar and arrow inside. When the switch is pressed a current flows down through the 1k resistor into the base of the transistor (this current is labelled IBE in the diagram). This small current at the base allows a larger current (ICE) to flow between the collector and emitter (and thus through the lamp which then lights up). The advantage of this arrangement is that you really don’t want to have a huge current running through a switch – if your finger happens to touch one of the wires connected to the switch you’ll get a nasty shock! With the transistor you can use only a small amount of current over the switch to activate the transistor but still have the large current you need to make the bulb light up flow when required.

This gets more useful for computers when the idea of a logic gate is introduced:

Logic gates

Logic in this context means calculations involving true and false values. For example

A AND B => C

C is true if both A AND B are true (the => means ‘implies’), otherwise C is false. A, B and C can stand for any yes or no question, so if we had A = ‘Socrates is a man’, B=’All men are liars’, and C=’Socrates is a liar’ then the above becomes (translated into English):

If ‘Socrates is a man’ and ‘all men are liars’ then this imples that ‘Socrates is a liar’

A logic gate is a device which takes one or two yes-or-no inputs and uses them to decide whether to output yes or no as a result. It’s output is determined by a so-called truth-table. Here’s the truth table for the AND-gate, where F = false and T = true:

A B A AND B
F F F
F T F
T F F
T T T

So the output of the AND gate is only true when both of its inputs is true. In every other case its output is false.

There are a handful of other logic gates. For example the OR gate is true when either (or both) of its inputs is true:

A B A OR B
F F F
F T T
T F T
T T T

These gates form the basis of all computation – with them you can add numbers, multiply numbers, decide between different code paths and many more. How this is achieved is a topic for another day – stay tuned!

In the next part of this series I’ll show how transistors can be used to construct logic gates in circuitry, and then how logic gates can be combined to form things such as counters and memory storage. Ask in the comments if anything above is unclear and I’ll try my best to clarify it.

Until next time,

Mark