And now for something completely different. We're going to fulfill the last part of the promise that we made at the beginning of this course, that we wanted to demystify for you what goes on inside the machine. So to begin, we're going to describe an imaginary machine that's very similar to the computer that you use every day. To begin we'll start with a basic overview of the properties of the machine. Now this is an imaginary machine that we created for this course. It's very similar to ancient computers, that's a picture of a PDP-8 machine from the 1970s. But also, surprisingly, it's also quite similar to today's smartphone processors and countless other devices that have been designed and built over the past 50 years. In fact, it's really rather incredible that from a birds eye view, the design of these machines is all virtually the same. And you'll see that as we get into this topic. So why do we want to study the machine like this? Well, our main thing is to prepare to learn about computer architecture. We're going to be talking about how your computer's processor works, and we're going to try to develop an understanding of that. Now, what are the basic components of your computer's processor and how do they interact? To look at these things, we need to learn about machine-language programming, the lower level language that your computer uses to get its job done. And you'll learn about how Java programs relate to your computer. The relationship between the code that we've being writing and the actual code that your machine runs. It really is the key to understanding references in Java, which is one of the most important concepts in Java programing. There's also just the intellectual challenge of attacking a new programing regime. Actually machine-language programming is fun, and many of you will get to experience that. And it's still the case that it's necessary in some modern applications to go down to the low level for performance. And still today people working in multimedia or computer games or embedded devices in scientific computing are writing machine-language programs in order to get good performance. But our main idea is through these next four lectures, we want you to learn the fundamental abstractions that have informed processor design for decades and are likely to for decades to come. All right, so to get started we need to work with the idea that everything in our TOY machine, and in your real machine, is encoded as sequence of bits. So we need a language to communicate with the machine really. And the reason that everything is encoded in bits is that in the physical world, it's easy to represent two states, on or off. And we'll see that directly when we start working with this machine. Usually bits are organized in contiguous sequences. In our machine, it's 16 bit sequences. In your machine, maybe it's 64, but the idea's the same. So the idea is the information is encoded as bits, but we represent them in the machine, or we interact with the machine using switches and lights. And the switches are either up or down, on or off, the light either lit or not lit, on or off. And so we're representing the information with these physical artifacts that we use to communicate with the machine. We tell the machine what we want by turning a switch on or off. The machine tells us what it has by turning on the light or not. Now, communicating in binary is definitely inefficient, so we always use a more convenient notation. And we're going to use a hexadecimal notation to communicate with the machine. And that's just a base 16 number. Takes a tiny bit of study, but it's really very simple to convert to and from hexadecimal notation and binary notation. What we do is, in a base 16 number, we have to have 16 different digits rather than the 10 digits that are familiar from decimal notation. And we call those last five digits, we just use A, B, C, D, E, and F. So to convert a binary number less than 16 to hexadecimal, I'll just use this table. And the first few are familiar from converting a binary to decimal, but then the next ones we represent 10 with A, 11 with B, 12 with C, 13 with the D, 14 with E, and 15 with F. In very short time, you'll get used to this table. And you can do the math, but the fact is that if you have a binary number, say this 16-bit sequence, we can convert that one to and from hex just by doing one digit at a time. So we look at the first 4 bits, those are 0 0 0 1. We look it up in the table, it's a 1. Then we do the next 4 bits, that's 1 0 0 0. Look it up in the table, that's 8. The next 4, 1 1 1 0, that's E. And the last are 7. And conversely, if we have that hex number 18E7, we know that each one of those hex digits corresponds to 4 bits, we just look up in the table and find the bits. But absolutely everybody knows this table after just a short amount of time working with the hexadecimal notation. That's the way we're going to communicate with the machine. You wouldn't want to be trying to remember a long binary number, but it's not so hard to remember a hex number that represents the same number of binary digits. And there's much more detail about hex and binary on the book site and in the book, if you want to study in more detail. Okay, so what is the TOY machine made up of, what's inside? So we're going to talk next about the basic components of the machine. It's got a memory, it can remember things and work with them. That's were the data and the code is held, and we'll be looking at that in detail. It's got something called registers. Those are kind of like your variables in Java programs, and you'll understand better after we look at the circuit that implements the machine why we need registers, but they're there. Then there's the arithmetic and logic unit. That's the calculator that actually does things like add numbers or compute the bits and so forth. And then there's two special components called the program counter and the instruction register that are obstructions that make everything go. Let's look at these in detail. So for memory, what that does is holds all the data and all the instructions that we're going to work with in our programs. You're of course aware that your computer's got a memory. You pay more for more memory and so forth. For TOY we have just 256 words of memory and 16 bits in each word. We're going to talk about a machine that's quite a bit smaller than your computer, but the basic principles are easy to extend to get to the size of your computer. And we'll talk about that a little bit later. What we want to have is a machine that is powerful enough to really actually do many, many other things that you've already done with Java programs. But also simple enough that we're going to be able to look at the design of a complete circuit for that machine. So TOY's just got 256 different words. It's got 16 bits in each word, and the memory is connected to registers. Generally, we take stuff out of memory, put it in registers, operate in the arithmetic logic unit with the registers, and then put it back in memory. And we'll look at that in detail. Now what we need to do is address the words. So each word's got a name, and we just use hexadecimal for the addresses. So we number them from 0 0 to FF. FF is the hex number 255. The hex number 100 is 16 squared, or 256, 1 less than that is FF, is 255. And again, when we think about binary arithmetic, it's pretty easy to learn about hex arithmetic. And anyway, this is a quite simple layout of the memory. The first column has all the words whose addresses start with the 0 hex digit. There's 16 columns, so one for each hex digit, next one is 1, next one is 2, and so forth. And all you have to do is bear in mind that it's not decimal, it's hexadecimal. So that after 9 is A, after A is B, and so forth, and after 0, F is 1 0. So we number the words from 00 to FF. And really we're going to think in hexadecimal for the next four lectures for sure, and just use array notation. So to refer to the contents of memory, we say M of 2A. So the M means memory and 2A is the address 2A, and what word's in there, it's C O 2 4. Again, C 0 2 4, that's 4 hex digits, 4 bits for digit, that's 16 bits. Every memory word, we can specify which word it is with 8 bits, there's 255 of them, 2 hex digits. Now we can specify the contents with 4 hex digits or 16 bits. That's the memory. And it's important to remember that a table of 256 words, which we can fit in just a page really, only we are going to show 4 out of the 16, one quarter of the memory right here. But if you know all 256 words, you know the contents of memory. Now your memory might contain a billion 64-bit words, so there's a lot more to it, but usually you're only using a small part of the time anyway. Okay, the next thing is the arithmetic logic unit, that's TOY's computational engine. And the way to think about arithmetic logic unit, or ALU, is that it's a calculator, it's not a computer. It's the hardware that implements the operations that we perform on data, like adding things and doing an and, and so forth. In a couple of lectures, we're going to look at precisely how it does that, and what kind of circuit we can build that actually implements the operations. But for now, it's not any different than an abacus or a slide ruler or a calculator, that's the way to think of the ALU. It's the thing that calculates. Takes two numbers as input, performs some operation on them and gives the result as output. That's the ALU, an important part of the computer, but just one part. Then there's the registers. Registers are 16 words, they're like the memory, but there's only 16 of them, so we can number them from 0 to F. And we'll use the names R0 through RF for the registers. And they're words, so they're 16 bits, so we need 4 hex digits to specify each register. And again, you think of those as like variables. There's this scratch space that we use for calculations and for moving things in and out memory. And very soon you'll see how the registers relate to the memory, and to the ALU, they're connected to both. By convention in TOY we make register 0 always 0, and that's just to simplify code, and we are going to do plenty of TOY code in the next couple of lectures. And we also often keep 0001 in register 1, although that's not an absolute convention. And all of these things are just illustrating the types of things that are found in real computers. And we are going to be very specific about them, because we need to be very specific in order to write code, and also to build a circuit that implements this kind of thing. So you might think, well, what do we need, really, registers for? Well, we'll talk about it a little more later, but the basic reason is that there's too many different memory names or addresses to be able to always be specifying things in memory. When you have a huge memory, you need a lot of bits to specify a word in memory, and that's wasteful often. Why not just always connect the memory locations just to one another, what do you need the registers for anyway? And again, in this case, there's just too many different connections. And you'll have a better feeling for this after you've seen the circuit, but I just want to just briefly indicate why we need something like registers. And all computers have registers. So again, it's important to remember, the table of 16 words completely specifies the content of the registers. Okay, so there's the memory, and the registers, and the ALU. The last two things are the program counter and the instruction register. As we're going to see next, the way that TOY operates is by executing a sequence of abstructions. The critical abstractions that make this happen are the program counter, which we call the PC, and that's the memory address of the next instruction to be executed. And the instruction register, which is the actual instruction being executed. So these abstractions, we think about them when we're writing TOY programs, and we actually physically realize them when we build a circuit to implement the TOY machine. And the basic idea of the machine is very simple, it's based on a fetch, increment, execute, cycle. So what happens is, fetch gets an instruction from memory into the instruction register. Which instruction, the one that's referenced by the PC. And then increment most often just increments the PC by one to reference the next instruction in the memory. And then execute does whatever the instruction specifies. It might be moving data to or from memory, it might be changing the PC, or it might be performing calculations as specified by the particular instruction in the instruction register. And we'll see detailed examples of this in just a moment. But the basic idea is, that all the machine needs to do is fetch, increment, execute, fetch, increment, execute. Specifically what it does is encode it in the instructions. And again, all computers operate in this way. Finally that's, really, that's it, that's what the machine is. And the fundamental concept that you want to be sure that you get at this point, is that the contents of the memory, the registers and the PC, for one thing is they provide a record of what a program has done. If the program changed things, then it's going to be reflected in the state of these things, some memory word will have the sum of two numbers or whatever else. But the other more important thing is that it completely determines what the machine will do next. The machine is deterministic. What's going to happen next is the instruction is going to be fetched from where the PC points to, PC's going to increment, the instruction's going to be executed, and so forth. The state of the machine completely determines what it'll do, that's a deterministic machine. The IR and the ALU are there, they hold kind of intermediate states of computation. So we don't worry about them in terms of the state of the machine. So now what we're going to look next is what kind of of data we hold inside the memory, and what kind of instructions or operations we perform on that data.