In the previous two units we talked about machine language in general and from this unit onward we are going to talk about the Hack Machine Language. Which is the native code that we are going to use in order to operate the hack computer. Now, I don't want to talk too much about the hack computer itself because we're going to, to spend a whole week, or more than one week talking about the computer. But I do want to give you an overview of the hardware platform on which the machine language is going to operate. As Noam described before these two things, hardware design and machine language design go hand in hand. And, and there's certain duality between them and you have to know one in order to understand the other. So here's an overview of the computer that you are going to build from next week onward. In fact, you've, you've been building this computer all along but next week we're going to actually assemble all these pieces together. And we're going to have a computer which consists of three main elements. We're going to have basically first of all we're going to have a 16-bit computer. And a 16-bit computer, is a machine in which everything consists of chunks of 16 bits. So, if we want to store something, we have to store 16-bits together. If you want to retrieve the piece of data, you have to retrieve16 bits. If you want to move data from one place to another, you move them in chunks of 16 bits. So, this is the atomic unit of information in this in this computer. Now the computer is going to consist of a data memory which is a sequence of 16-bit values. And each of these values is going to be stored in a memory register and these registered are a number for convenience. We can think about them as register zero or register one all the way to as many registers as we have in the data memory. The instruction memory is a separate memory space that is also a sequence of 16 bit values. And the CPU is a device which is capable of manipulating 16 bit values using mostly the ALU which resides inside the CPU. Finally, we are going to have all sorts of buses that enable us to move data from one place to another. So we have a data bus that connects the CPU and the data memory. We have an instruction bus that moves instructions from the instruction memory to the CPU. And we're going to also have some address busses which I didn't put in the picture to avoid clutter. And also we don't need this level of detail for this particular unit. You can think about the buses as highways of 16 lanes moving chunks of 16 bits from one place to another. All right, so how do we control this computer? Well, we have software and the software is in this level of, of, of the machine, the software consists of machine language. Or the programs that we write using machine language. And when we designed this computer and when we designed this machine language, we decided to to create two categories of instructions. Which we call A-instructions and C-instructions and each one of these instructions is specified as a 16 bit number like everything else in this machine. So what is the hack program? A hack program is essentially a sequence of instructions, 16 bit numbers written in the heck [COUGH], I'm sorry written in the hack machine language. What about control? Well, before we talk about control, I have to introduce yet another element in this platform which is called a reset button. So we do have a reset button and here is how I cause this computer to do something useful for me. I write the program, the program is a set of 16 bit numbers. I take these uh,16 bit numbers and somehow put them into the ROM. We'll discuss later, how we actually do it then I press the reset button. And once I do this the program starts running. That's, that's the basic sort of user instructions of how to to cause this computer to do something useful. Now, I have no idea what this, what the computer will do it all depends on the program, you know. But hopefully the computer will start sounding some music or showing a video clip or compute the average of a million numbers or something like this. It all depends on what is written in the program. Now before we go on to talk about the machine language I'd like to say a few words about some more hardware artifacts that we have to be aware of. The hack computer recognizes three registers. First of all, there's the D register which holds a 16 bite value which represents a piece of data. Then there's the A register which holds also a 16 bit value which represents either a data value or an address. We'll talk about this later on. And finally, there is something called the selected memory register which is denoted by the letter M. So it doesn't matter if I have 2 billion memory registers. At any given point of time, only one of them is selected and I can basically ignore all the other registers. They, they're irrelevant for what I currently do, I want to focus only on the currently selected register and I call this register M. You know, the, this is just a convention that we use in the specification of the hack machine language. All right, so now we have all the basic background that we need in order to understand the syntax of the language. So here's the syntax of the A-instruction. Ampersand value or @value where value is either a non-negative decimal constant or a symbol referring to such a constant and we'll discuss these symbols later on. Now, instead of spending too much time about the formal semantics, let's see an example. What does @21 mean? Well if I tell the computer @21 two things happen. First of all, the A register is set to 21 and second of all, RAM of 21 becomes the selected RAM register. So we see that the A register has a very important side effect. Once you set, the A register to particular value like 21. It automatically selects a particular register from the data memory and this register becomes the currently selected register. What I called M in the previous slide, all right? So this is the operation of that's, that's the semantics of the M structure. Here's an example of how we actually use this instruction. Let's say that we want to set, RAM[100] to minus 1. How do I do it? Well, the first thing that you have to do is select the register on which you want to operate and we do it by saying @100. Once we do this, we get the side effect working and then we can say M equals minus 1. Because M now denotes register number 100 in the memory unit. So that's how, how we use the A, A-instruction, we always need it before we operate on the memory. Before we do something to the memory, we have to select a register so we always have to address the memory using an A instruction. And that's by the way, why it's called A, A for addressing. The C instruction is the workhorse of the language. That's where most of the action takes place and the syntax of this instruction consists of three different fields which we call destination, computation and a jump directive. Now, here is how it works. First of all, we compute something and then we can do one of two things. We can either store the result of the computation in some destination or we can use this computation to decide if we want to jump to some other instruction in the program. Now, this is the basic overall semantics of the C-instruction. Now, let's get more into the details of every one of these fields. The computation can be any one of the computations that we see here. So, we see here a set of what is sometimes called pneumonics or symbols that represent some operation. So we can compute the values, 0, 1, minus 1, we can compute the current value of the D register. We can compute D minus 1, D plus A D and A and N here is a 16 bit A D 16 bit or A and so on and so forth. And wherever you see the mnemonic A, we can replace it also mnemonic M. So we can do many different things using the the computation field. What about the destination? Well, we have eight possible destinations, beginning with null which means that we don't want to to store the results of a computation at all. And we can store the result of a computation either in the currently selected ram register or in the de-register or interestingly enough we can store it simultaneously both in M and in D. This is something which is actually quite powerful about the hack machine language. We can simultaneously store the result of computations in more than one container. Now we have eight different possibilities and the, the programmer is free to use any one of them according to what he or she wants to do. Now what about the jump directive? The jump directive takes a little while to get used to and here is how it works. We have eight possible conditions in these conditions always apply, they always compare the result of the computation to zero, okay? And once again instead of belaboring about it, I'm going to to give you some examples in just a few minutes of this will become a much clearer once we see the examples. So, lets say that I want to set the D register to minus 1. Okay, set the D register to minus 1. I look at the language specification and I see that I have minus 1 is one of the value I can compute and D is one of the legible destinations so I can simply say D equals minus 1. The jump directive is optional so I don't have to specify it so case closed. Let's move on to the next example. Let's say that they want to set RAM 300, register number 300 to the value of the D register minus 1. Once again, I look at the language specification and but before I do so, actually, I have to select the register on which I want to operate. You know, whenever I want to access the memory I must use an A instruction to select the register of interest so I say @300. And then I look at the specification and I see that I have D minus 1 as one of the values that the CPU can compute for me. And I have M as one of the legible destinations, so all I have to do is say M equals D minus 1. And that is how I set register number 300 to D minus 1. As you see, I need two instructions to carry out this particular operation. Whenever I do something to the memory I first have to use an A instruction to select the register on which I want to operate. 'Kay the last example deals with a, with a jump. You know, how do I tell the computer to jump to execute a particular instruction? Let's say that the condition I want to use is that if D minus 1 equals 0, jump to execute. You know, the instruction which is located in ROM 56. You know, this is, this is similar to for example a condition that terminates a loop. You know I drew something the loop and each time I check the value of D minus 1. And when it reaches 0, I want to jump to some other instruction. So how do I do it? Well once again whenever I deal with a memory, the first thing that I have to do is use and A-instruction to specify which register I want to operate on. So I say @56 to select the address. 56 and then I look at the language specification. I see that I have D minus 1 as one of the, the possible computations and I also have a J eek which means jump if the value of the computation equals 0. And that's exactly what I want to do, right? I want to jump if the value of D minus 1 equals 0. So I compute D minus 1 and I say J eek. So if the value of D minus 1 equals 0, jump. Instead of equals I could have used the greater than less than not equal and so on. And notice by the way that I also have an unconditional jump. You know, if I simply want to jump to 56 without checking any condition, all I have to say is jump. And in fact, if I want to be more accurate the, the syntax that we have in this language requires that I say 0 semicolon jump. You know, this is just a convention so if I want to do an unconditional on jump, I do 0 semicolon jmp and this will cause an unconditional jump. By the way, everything that I say here is described fully in the book and in the website. So you don't really have to remember any one of the details because you can refer to them later on. So this has been an in overall description of the hack computer language. And in the next unit we're going to be more specific about this language because we're going to describe two different flavors of this language. What we've seen so far was the symbolic flavor of the language but we can also write all these instructions using binary codes. And it's quite interesting to see how these two flavors relate to each other. We'll do this in the next unit.