So in the last two weeks, we've built an ALU and memory hierarchy. And basically, we're at the stage, we can just combine them and build a computer. But we're going to postpone that to next week. And this week, we're going to actually look at the computer that we want to build from a user's point of view. Study what can we do with the computer that we're going to be, what exactly the specification of the computer that we're going to build. And then only after we've looked into it, played with it, we're actually going to build it next week. So why do we need to do that? Well, basically because a computer is a complicated thing. It can do lots of things. When you think about it, this is really amazing. Most machines that we have in the world do one thing. Your washing machine only washes clothes, it cannot cook spaghetti. On the other hand, the computer, and for that mean, a smart phone is a computer, can do lots of different things. They can do word processing. You can play games on it. You can talk with other people. It can show you videos. There are huge, enormous amount of eh, stuff that the same computer does. So how is it possible that we can do all these different things with a single hardware, with a single machine? The basic idea here is that of a universality. The origins of this idea were theoretical models that considered by Alan Turing eh, in the early 19th and 20th century. He tried to formalize the notion of a computing machine, and defined a theoretical model, a Turing machine, that actually tries to capture the essence of what can be computed. And then he noted this amazing phenomenon. Although there are many different computing machines, many different Turing machines in his model, there was a single one of them that could actually act like all of them given the correct program. Could simulate all of them and that is called the Universal Turing Machine. That was the first time we have this amazing idea of one machine acting as a huge amount of all machines, in fact, it can act as anything at any computing machine. The same idea actually turn, was turned into practice by von Neumann, who actually built the first serious architecture of a general computing machine. Where he had noticed that, where the centerpiece of his architecture was the fact that we have a program computer. We can put the program software inside the hardware and then it can act in, in a way that is according to the software that we put there. Different programs create different different operations, different functionalities. And in this way, we actually had the real computer for the first time that could form, could perform many different functions, many, run many different programs. And that secret is still with us to, today, to date. And we don't even notice how remarkable it is, that our single machine can do all these many different things. So, let's look at, slightly more carefully, how does this actually work? So, we have our computer, computer. And inside the computer, we know we're going to have some central processing unit, we're going to have some memory. Its going to read some input, produce some output. But inside that memory is going to be a program that is going to com, tell the computer what to, what to do. While the hardware is fixed, that program, the software can change, and as a program, the software changes, the computer will do different things. So, let's see how does the hardware, the single hardware, static hardware perform many things according to the program. Well, the program had a sequence of instructions. Each one of them is going to be coded in binary. And our hardware is simply go instruction by instruction, and, and execute it. Now, different sets of instructions, different sequences of instructions will thus cause our co, our hardware to produce completely different things. And when we take the whole sequence, the whole program, the whole sequence of instructions together, we get the functionality of the program. Which can be completely dependent on what the, was written there on the program itself. So now let's look at the different elements that we will need to look at more carefully, which we will do in the next unit. Eh, that together cause the hardware to do what the program wants it to do. The first thing is, how are we going to specify the instructions? Our program is going to be, is going to be composed of, of a sequence of instructions. What exactly does the instruction tell the computer to do? That's one element. The other element is, how do we know which instruction to perform at any given stage and time? Suppose we are now in instruction 74, it makes sense that the next instruction we will do is 75. But sometimes, we will need to change the order maybe to do some kind of loops or to do things conditionally. That's the second kind of element that we need to be able, so, that software needs to be able to control the operation of the hardware. The third element which is really important, is if we're going to have to tell the hardware what to operate on. Even if the hardware knows it needs now to add two numbers. We have to tell it, the software has to tell the hardware, how exactly, where exactly will it get these two values that it's going to, that it needs to add and where should it put the result. So these are the three basic elements, if you wish, that every machine language every way that the hardware allows the software to tell it what to do needs to specify. And we'll talk a little bit about possibilities and what kind of options are there for each one of these three possibilities later. Now, the point is once we have this machine language, this is what the hardware allows the software to perform. Now, this machine language specification is really a programming language but it's a terrible programming language. It's really convenient for the hardware. It allows specifying anything you want to do to the hardware. But it's really not convenient for human beings. So, in reality, human beings never program or almost never program exactly in machine language, but they rather program in what's called the high level programming language. A language that was designed for humans to be able to easily write what they want to do. And then there are automatic programs called compilers, which translate that into the machine language, into the software, which actually tells the hardware what to do when it runs it. And thus, usually, we do not worry too much about the machine language because we, as human programmers, don't actually use it. However, from the computer's point of view, this is really what runs. Always only machine language programs run and any other programs that runs was really translated in some way, to this machine language formalism. Which is what exactly tells the hardware what to do. Even though, normally, people do not write in machine language. In this course, where we are actually dealing with the hardware that runs the machine and with the software that immediate, directly operates above it. And because we're really learning about this machine language in order to understand how to build a computer, we're going to have to deal directly with the machine language. And there are some other situations where people deal directly with machine language, for example, if they really want to have highly optimized code for very specific tasks. In this case in this case, as in, in our course, we will need to pay a little, we need, we'll need to make a working with a machine language slightly easier. And there are two things that are normally done when working with machine language which make things easier. The first thing is, instructions in machine language are always sequences of bits, that's how where we keep all information in a computer. This is terrible because it's very difficult to, to, to program, to look at the instruction 0100010 and see what it's supposed to mean. But in reality, there is some way this instruction codes something in a computer, and usually, it codes something that we can understand. For example, it could be that the first part of this sequence of bits really codes ADD. Addition. In that case, when we talk about this kind of instructions, it will be more convenient to talk about the mnemonic form of this instruction and simply say add instead of 01110. Or whatever the code is. Similarly, parts of the instruction may code specific things. For example, perhaps the second part of the instruction codes as a register that we want to use, whatever that means for now. In this case, again, we can write R2, which makes sense to humans, somehow implying the second register. Rather then the sequence of bits which really codes this too, in some way, depending on the machine language. So, instead of talking about this sequence of bits, which makes no sense to humans, we're going to have to say, we're going to think that what's really written there is the command, add R3 to R2. And then, we're going to specify exactly what that means to our computer. And, this is exactly equivalent to talking about the early, earlier sequence of this. It will just make things easier for us. Now, there are two ways to interpret it. The simplest way, and this is the way I prefer looking at it the beginning of this stage. Is simply that the synthetic form, the nice, nice form, does not exist anywhere just the way that we're talking about the real bits that exist in a computer. That's the first thing. So when I say add, I really mean 01110 or whatever the machine language specifies. The second interpretation goes one step further and looks at the following thing. While sometimes we do want to code in machine language,. And why not allow the user human to actually specify writing in this syntactic form in this, what's called assembly language form, and then we can translate it to the bits very easily. This is what an, a program called an assembler does. And you will actually need to build this assembler in the sixth week. So, that's the second interpretation that we will have. Where we actually, there is a program that allows you to write this machine language not directly as bits but in a slightly nicer assembly language format. While we are at it making things a littler bit easier to actually write programs and machine language for the rare cases that we need to do that, including this course. Then eh, there is another thing that we get for free and which is called symbols. A lot of times in a machine language program, we will try, need to access memory locations. For example, there could be a command that tells, add one to memory location 129. Now, the point is for the programmer writing that, it's not really important that we actually talk about machine location and memory location 129. What you really have in mind, our programmer is, that we are going to keep some kind of index in that machine location, in that memory location. So eh, for the programmer, this could have been instead that he kept that the program lo, at memory location 250 or any other pro, memory location. The important point was that every time that I'm talking that I use this value, I go to the same memory location. In this situation, we might as well translate, allow the user to write some kind of symbolic symbol, some kind of name for that memory location. Let's say, call it index. And automatically lets our assembler that already is providing us with some eh, convenience, allows assembler to actually translate that word index into some kind, some free memory location, for example, 129. Again, this will allow us to write programs in easier ways to humans, it look easier to way to humans without changing everything within, in reality. Whenever you see index, that really just means some, for some memory location, which is fixed every, and is used the same memory location whenever we talk about index. So, this finishes the overview about the idea of machine languages. And, what we're going to do in the next unit, is actually talk a little bit, a bit about specifics of machine languages. What kind of things do we have in them? What kind of elements are they composed of? And once we have that, basically background, that perspective on what kind of machine languages what, what kind of things we do in machine languages. Then we'll actually start talking about the machine language of the computer that you'll build in this course, the HACK computer