Here's the big picture of our VM language. In the previous module, we dealt with arithmetic logical commands and with memory segment commands. And now, we are beginning to deal with branching commands. So branching is actually a relatively easy concept to comprehend. So far, without branching, our program was completely linear. Every command executed after the previous one. But with branching, we can introduce all sorts of non-linear path in the flow of control of the program. So the program can progress linearly, and then all of a sudden, there's a goto. And we continue the program from some other instruction. And the goto's can go forward, they can go backward. If we go both forward and backward, we can implement loops. So this branching gives me a lot of flexibility. So every one of you who use the if statements or while statements has experienced the notion of branching without using the word branching. So at the low level, we have two kinds of branching. We have what you call unconditional branching and conditional branching. So we'll spend a few minutes talking about each one of these flavors of branching, and we'll start with an example. So here's an example of a high level function that computes the multiplication or the product of two given values, x and y. And it computes it using repetitive addition. So we take x, we put it into some container, which we call sum. And then we increment sum with x y times. And in order to count y times, we use yet another variable called n, which starts with one. And you can read the code and understand this, it's rather trivial. I should point out though that this implementation of multiplication is very naive and very inefficient. Later on, we will show a dramatically more efficient implementation of multiply. All right, so this our mult function, and we have this while loop here. And once we compile this high level code into VM code, the VM, I'm sorry, the compiler will generate the code that you see on the right hand side. So you see that what the compiler is doing is it's taking this while loop, and rewrites it using goto commands. And in order to achieve this rewriting, the compiler also has to invent and generate some labels, and insert the labels in the right places. So one label goes where the while was, and another label goes where the while ends. And the compiler has all this knowledge of how to do it. Now once again, as I said in the previous unit, you don't have to worry at this point how the compiler actually achieves this magic. Because we are going to deal with it extensively later on in the course. So all I want to do is focus on the VM code, and see how these goto commands are being used. I don't even have to tell you all this story about the high level function. But I do it because I want you to understand the context of where these weird VM commands come from. They come from compilation. So let's focus on the goto command. We see an example, we have several examples of goto in this code. So I'm just highlighting one of them, and the syntax is trivial, right? You say goto label, and you expect the computer to jump to execute the command just after label in the code. So if you say go to loop, the next command that will be executed is that we see push n would be the next command, because that's the command just after the label loop. All right, moving along, what about conditional branching? Conditional branching is more interesting, because it depends on evaluating the truth value of some condition. So if you go back to the high level code, we see that we had a condition there. The condition was, as long as it is not true that n is greater than y, do this and that, right? So what we have here is the command, if-goto ENDLOOP, that's what the compiler has generated. And notice that whenever we wish to use a conditional goto command, we must first push onto the stack a certain condition or a certain expression that describes a condition. And this expression will have to be evaluated before the conditional goto. Because otherwise, we will not know whether or not the condition is satisfied. So once again, the rules of the game are that you push the expression. And then when the program runs, this expression will end up being evaluated. And a certain truth value will remain on the stack. And then based on this truth value, the if-goto command will know whether or not a jump has to actually materialize. And we see that in this particular example, if you look at the high level code, the condition is n greater than y. And indeed, when you look at the generated code, we see that we have a push n, push y, gt just before the if-goto command. And these three VM commands taken together implement, in the VM language, the same logic as n greater than y. So once the computer will evaluate push n, push y, gt, it will get the truth value that will determine if a conditional jump should actually materialize. All right, so to recap, we have three branching commands, goto, if-goto, and label. Without which, we could not generate all these labels. And the implementation of these command is such that when the VM translator will be asked to implement these commands or to realize them, it will have to generate assembly code that affects the same goto operations in assembly. Now, I assume that you went to the trouble of reviewing assembly language, as we requested in module zero of the course. And if you did that, you should know that the implementation should be extremely simple. Because the assembly language also has goto commands whose flavor and style of execution is almost the same as the goto commands of the VM language. And therefore, the translation in this case of VM branching commands to branching in assembly is a rather simple exercise. And we expect you to do it on your own. All right, so without further adieu, we've dealt with these commands in the previous module. We've dealt with these commands in the current unit. And we are ready to tackle the function commands, which are the real essence of this module. So that's what we'll do starting with the next unit.