 In this video, we are going to explain how to translate a switch statement to ABR assembly code. And the first thing we need to know is both the meaning and the syntax of this statement. So this statement can be written with the keyword switch. Then it will be an expression surrounded by parentheses. And then with curly brace, we're going to delimit an area that is going to have the following structure. For every case we want to test, we need to write the keyword case. Then value, let's call it v1, column, and then some arbitrary code. And we can repeat this several times. Let's say, for example, v2, column, another arbitrary code. Let's call this code block v1. This one we call it block v2. And we also have the possibility to specify a default block. Let's call it generically block d, which is executed whenever this expression has neither of all the values that are specified before. Now one additional feature of the switch expression, or the switch statement, is that optionally we can terminate each of these blocks with the statement break. But this is not part of the statement itself, this is totally optional. The effect of this break statement is that if we include it, after evaluating block v1, this break will take us out of this statement and continue the execution in whatever follows in the code. Whereas if we do not insert this break statement after executing block v1, if the expression is evaluated to v1, the code will continue executing all the blocks. So this is basically an statement that is very useful whenever you want to execute different codes or different portions of the code depending on the value of this expression and you segregate them like this. Now what would be the generic structure in an assembly program? Well, let's suppose we had some previous instructions. We need to have some instructions to evaluate the value of the expression. In other words, we need to compute whatever has been specified here in parentheses. So we need to have an arbitrary number of instructions to compute the expression. This is what we know as the evaluation of this expression. Now let's assume for the sake of this discussion that the result of that expression has been stored and registered R18. What we need to do is to start comparing whatever the value is in R18 with the constants specified in the cases. So we can do that directly with the CPI compared with immediate instruction and we compare R18 with value v1 and value v1 is taken directly from here. Now what happens now is we need to execute a conditional jump and this conditional jump will be implemented as follows. If we detect that R18 and v1 are exactly the same value, then we are in the case in which we need to execute this code. So we're going to put precisely a conditional jump that will jump to the location v1. Let's put v1 block if these two operands are identical. If they are different, what we need to do following the interpretation of this statement is to move on and compare now with value v2 to see if we need to execute this block too. And this would be done exactly in a similar way. CPI R18 which is the result of my expression with v2. And we do something similar. And if these two are found to be equal, then I want my program to jump to another label. Let's call it v2 block which is going to be at the beginning of the instructions calculating block v2. Now I could have an arbitrary number of cases which would require each of them these pair of instructions, but eventually if all the comparisons fail and if I have a default block here in my construction, what I would do is basically an unconditional jump to the default block which will write farther down. Okay, now once we have written all the instructions to take care of the comparisons, we need to now insert the different blocks. So if we go back here, the first case we check was r18 with v1. If they are identical, then we need to jump to this v1 block which will be placed right next to the previous instruction, as many instructions as we need to implement whatever functionality we have in block v1. Now here comes the interesting part. If the block finishes with a break, the break will translate exactly into an unconditional jump that takes me outside of the statement, in other words to a label which I'm going to put farther down, which is done. So here we have a case in which one statement inside my switch statement translates directly into one instruction, machine instruction in the AVR assembly code. Okay, once we have done this, we place block v2 in an analogous way. All the instructions go here for block v2 and the unconditional jump to the label done because we have inserted the break statement here. Note that if we do not insert the break statement, then we do not need these two unconditional jumps and we would achieve what the semantics of this block is telling us, which is if the expression value is v1, then you execute block v1 and unless you get a break, then you keep executing all the blocks, which is exactly what it would happen here if we remove the break, which means removing the jump to the dump part. And the only thing remaining is insert here the default case, which it will have its own instructions. We call that block d over here. And finally, the label here, which will be the destination of this jump and this jump. So with this structure, we replicate exactly the operations required to evaluate this switch statement. Let's put up an example to illustrate this translation with an expression that is a bit more complicated. Let's suppose we have the expression x plus y plus z. And we have, for example, two cases, k0. We have code. Let's call it the block 0. We're going to insert a break a statement here. Then case one, we're going to have block one. And we're going to put immediately the default block. But we're going to assume that there is no break a statement at the end of case one. In other words, what it has to happen or the equivalent assembly code we're going to write to the right of this code. It's going to behave such that if the result of this expression is equal to one, then block one and block d need to be executed sequentially. How do we do that? Well, first, as we said here in our template, we need to write down the instructions needed to compute the expression. Let's assume that both all x, y and z are 8-bit integers and they are in memory. And they're in memory in locations labeled with exactly those names. So the instructions that would comprise this block would be first bring to register r18, for example, variable x from memory. Next, we will bring variable y to another register. Let's say, for example, r19. Now we perform the addition of x and y. So we say r at r18, r19, which means that r18 will contain now the addition between x and y. We'll bring the third variable, LDS, again to r19. We can reuse r19 because we don't need it anymore. y doesn't need to be there anymore. And we store the value of z. And we accumulate these to the addition we already have in r18. That's it. So at this point, r18, register18 contains the value of the evaluation of this expression. What do we do next? We start comparing, as we said here, the different values of the different cases. So the first case is k0. So we CPI r180. And we branch if this value is equal to, let's call it block0, a label that will write a little bit further down. If this is not the case, if this comparison fails and therefore we don't execute this branch, then we have to compare for case one. So we just do CPI r181. I still can use r18 because if this branch has not been taken, r18 still holds the value of this expression. And we repeat the same instruction. If these two are equal, then we've detected the case in which we need to branch to block1. If this fails, then we are in the case in which we unconditionally jump to the default. Okay, so we covered this part of the implementation. Now, next, what we need to do is deploy the corresponding blocks for the corresponding cases. So the first case, we decided to call it block0. So we put the label block0 here. And we will insert all the instructions that implement block0. Now, careful here because after block0, we did write the statement break. Therefore, we need to jump unconditionally to the place where we are done with this statement, which we will write a little bit further down. After we've done that and following this template, we are going now to insert the code for case one, which we call it block1 to the label. So we put block1, we put the code here for block1, whatever that is. And now, since we haven't written here the break statement, we are not going to write the jump done instruction. Immediately, what we're going to do is place the default block, blockD, and then the label done. So as we can see, this switch is telling us that if the value of this addition is one, we jump to this block and block1 and blockD need to be executed. And this is precisely what is going to happen in this assembly code. We load expression, we compare its result, this condition is false, therefore it's not going to execute. This condition is true, the jump is going to be taken. We jump over here, we execute block1 and then immediately blockD. And we terminate the execution of the switch statement, which was the correct meaning that we wanted.