 If we want to fully understand CPUs, we'd have to get into a lot about circuitry and electricity and even material science to understand how they are created. But as programmers, all we really need to know to program a CPU is what's called its programming model. The programming model is the abstraction presented to programmers that elides over all of the details of circuitry and voltages and so forth. Those sorts of things which we really just don't need to know to program the CPU. So, first off, from the programmer's perspective, what a CPU does is it executes instructions. And the sort of instruction a CPU understands, of course, is some sequence of bits. In short, the CPU is hardwired such that when a certain sequence of bits is read by the processor, it interprets that as a particular instruction and acts upon it accordingly. So, CPU instructions are sometimes called binary instructions or sometimes machine instructions. And so, the code which is read and executed by the CPU is often called machine code. Now, of course, any particular CPU design is hardwired to understand one particular set of instructions. There are a few things, though, which any CPU needs to be able to do. So, first off, any CPU needs one or more instructions for copying bytes. Mainly, instructions for copying bytes from one address in memory to another address in memory. Secondly, we need some instructions for doing basic arithmetic. So, say, you need an instruction that says something like, take these bytes of memory and these other bytes of memory, treat them both as representing numbers and add them together and store the result at this location. Thirdly, any CPU should be able to do what's called bit logic. A not instruction, for instance, takes an input byte and simply flips all the bits. And then we have additional logic operations including and, or, and exclusive or. All you need to know about them at this point is that they are what you use when you want to manipulate the individual bits of bytes. Lastly, any CPU needs to have what are called jump instructions. When the CPU executes code, it retrieves its instructions from memory. And each time after reading and executing an instruction, the CPU then reads and executes the next instruction in memory, the one that immediately follows it. So you can think of a CPU executing code as starting at some particular address and just working its way sequentially through memory. However, if the CPU were to always execute instructions in a strict sequence through memory, then our programmers would never branch. They'd always do each time they run exactly the same thing. So to branch, we need jump instructions. A jump instruction simply tells the CPU to jump to some particular location in memory and start executing there. And very importantly, we need jump instructions which are conditional, meaning that first the CPU tests for some condition, and if that condition is true, then to jump to the specified address. Otherwise, don't do the jump and just continue execution as normal by executing the instruction which follows immediately in memory. Now, you may be wondering what kind of condition would these conditional jumps involve. Well, usually it's something very simple like, say, looking at a byte of memory and if all of the bits are zero, then do the jump, otherwise don't. Inside a CPU itself, there are some very small storage locations called registers. Registers serve basically two purposes. First, there are what are called status registers, and then what are called general purpose registers. The status registers contain little pieces of data that concern the operation of the CPU itself. For example, some CPUs operate in different modes, and so such a CPU will typically have a register where it stores some bits that designate what mode the CPU is in. For example, when a CPU is executing instructions, it needs to keep track of the address of where it should get its next instruction. The register which holds this address is usually called the program counter, and in fact, when you execute a jump instruction, what you are doing is modifying the program counter, thereby causing the CPU to change where it's going to get its next instruction. The general purpose registers in contrast are so named because the intention is that the programmer should be able to store whatever they want in these registers for whatever purpose. In most processors, though, the general purpose registers serve the central role because the operations which we perform, copying bytes, basic arithmetic and bit logic, they can only be performed in many processors on data in the general purpose registers, not stuff that's in memory. So say many CPUs don't have any instruction which will copy directly one byte of memory to another byte of memory, instead what they have are copy instructions which will copy bytes in memory to a register and then a separate instruction which copies from a register to memory. So in such a processor, when you want to copy data in memory, you first have to copy each byte into a register and then in a separate instruction copy it out to memory. And similarly in many processors, there's no arithmetic instruction which will add stuff that's in memory to other stuff in memory. We have to first copy whatever we want to add into registers and then add the contents of the two registers together. So you may be wondering how many registers we're usually talking about and how big are they. Well most registers are just a handful of bytes, usually some small power of two like say 4 bytes, 8 bytes or 16 bytes. On an Intel 64 bit processor for instance, most of the general purpose registers are 64 bits in size, 8 bytes. As for how many registers, well the Intel processors for example have a few dozen general purpose registers, some other chips have upwards of a few hundred and then the sort of CPU you might find in a really cheap device like say a toaster at best maybe has four registers. So when we write machine code, very often the big part of the game is in dealing with the fact that we have only a limited handful of registers. And so we have to be very careful about when we copy stuff into the registers from memory, we first have to often store stuff in the registers out in memory first so we can get back to it later. So a CPU's programming model primarily consists of its instruction set, what precisely are the instructions which that CPU supports and what are its registers, what are they named, what purpose do they serve and so forth. And the design of these two things, the registers and the set of instructions are really very much intertwined and together they are often known as an ISA, an instruction set architecture. When you have some machine code and you're wondering does it run on this processor, the question you are asking is what is the ISA of that processor. If you have two processors made by different manufacturers but they both support the same ISA, then they both can run the same code, the same machine code. So for example the PC platform is built around Intel's x86 instruction set architecture and for a long time up to about the mid 90s the only x86 processors you could buy were directly from Intel itself but then AMD came along and started producing processors which supported x86 and so they can run the same code. So x86 is one very dominant ISA today, there's also the ARM ISA MIPS and the not so prevalent anymore Motorola 68K, those are some other examples. But understand that instruction set architectures tend to develop and grow over time so the x86 ISA for instance hasn't remained still as Intel releases new processors, their newer processors support all of the instructions of their older ones and they have all the same registers except they might support more instructions, more new instructions and they might have more new registers. So x86 is really an umbrella term that covers all of the ISAs starting from Intel's processors in the 70s all the way up to their processors today and specifically when Intel released the 386 processor they designated that upgrade of the x86 ISA, they designated that I832 and then finally when they released a 64 bit processor in the mid 2000s they called that ISA x8664. But again these upgrades just add new instructions and new registers so all the old code will still run on a modern processor. If you get a new Intel 64 bit processor today it will still run I832 code because it still supports all the instructions and registers that I832 expects.