 Let's give you, we're going to explain an example of ABR assembly program. So as we said before, an assembly program should start always first defining its data. So let's assume we start our section defining four integers. Let's use the labels N1 dot by 10, N2 dot by 20. Remember that these initialize one byte to 10 and 20 respectively, the third number N3 dot by 30 and N4 dot by 40. And let's assume that my program wants to add all these numbers and the result wants to be store, will be store in an extra byte that we declare like this, space one, zero. One byte with value zero. Now the way these things are laid out in memory, remember that this definition would be identical to using something like this dot by 10 comma 20 comma 30 comma 40. That would be exactly the same. Then remember that after the data section, we can define another section with the dot section dot text directive in which we do dot global. Main to declare the main label as global. And then with main column, we start the definition of the code which typically finishes with the instruction red to say that we return and the directive dot N. Now what kind of operations are we going to do here? Again, the program has to add these four numbers and place result here. One first operation we would do is to load with instruction LDS in R24, register 24, the number and N1. And we can do exactly with this instruction. Now remember, this label over here, what it's telling us is that we are loading in R24 the content in memory which corresponds to label N1. Another way of looking at it, this directive actually translates into memory in something like this. This is position N1, N2, N3, N4 and result. And we have the values 10, 20, 30 and 40 here and a zero here waiting for the result to be stored. Now this instruction would take the value pointed to by N1 number 10 and load it into R24. We can do the same LDS, suppose R17 with N2. And then we can add R24, R17. Now what have we achieved here? After this instruction what we have is the R24 contains the value N1 plus N2. However, we can use these labels in a different way. So this instruction would be equivalent to perform the following. Suppose that I first load the immediate in R26, L08 and N1 next to this LDI, R27, HI8 and N1. What have I done here? These two instructions load into the register R27 followed by R26 which by the way it's also called X. In register X now I have the address of the label N1. Now what am I going to do with this? Well, I want to achieve exactly the same as this instruction which means I need to bring from memory having the address in register X. I want to bring from memory the number 10 and load it into register R24. The way to do that is with instruction all the LD, I bring it to R24. And then, this is the important part, I can use this syntax X plus. So what I'm doing here is I'm going to memory with an address which is part stored in the register X. I'm going to memory where this location is pointing to which is of course N1. I'm getting the value 10, I'm storing it in R24 but and this is the important part, the register X is incremented. Which means that X which started with the address pointing to this number after this instruction, number 10 will end up in R24 and the address will point to the next position. So as you can see what I'm getting at is that the microprocessor allows me to first load the address in one register which is the concatenation of R27 and R26 which we know we call X. And in the same instruction it allows me to go to memory to whatever that address is pointing to, get the value and at the same time increase the value I want. So as you can imagine these three instructions over here achieve exactly the same as this one that loads N1 in R24. Now you'll be asking yourself, why are you doing this in three instructions if you can do it with one? Well, this is just to show different ways of accessing data. The other trick that I'm interested in showing is that now I have a very interesting situation. Register X contains the address of the following number to add. So I could do something like this, LD R17 comma X plus. And this would achieve exactly the same as this instruction here. So you see what I did is now R17 gets the value 20. Why? Because X was left increased by the previous instruction and therefore is pointing to the next number. Not only that, the following after executing this instruction X it's going to point now to this value here. So I could keep working on the expression doing the following now LD R17 X plus. And now what I'm doing here is that R17 now has the value of N3 or 30. And I can add it again add R24 R17. So in this case R24 has N1 plus N2 plus N3. And the other interesting thing is that X got incremented again. Therefore now its address or its value is the address of the following number to add. So I can repeat this instruction LD R17 X plus. And yet again add R24 R17. And therefore R24 now has N1 plus N2 plus N3 plus N4. So again I could have executed instead of these instructions. This one and this one instructions similar to these two. Right? Because I put the labels N3 and N4. But this alternative way of doing it is to show that the microprocessor allows me to use a register of 16 bits of course. Because the addresses in AVR architecture are 16 bits. It allows me to use that register and increment it in one position. Which is very useful when I need to access data that are stored in consecutive positions in memory. There is only a couple of things left for me to do. We said that we wanted the result to be stored here. So one way I can do that is ST X R24. Why? Because after accessing this element in this instruction. The value of the address in X is now left pointing to the result. Because I defined them in consecutive positions. So in here what I'm doing is result equal to N1 plus N2 plus N3 plus N4. Now there is only one thing left for me to do. I've used three registers. Sorry four registers. R26, R27, R24 and R17. These are the four registers I've used. If you check the rules that we need to observe in terms of register. You realize that these three registers can be used freely. However R17 needs to be saved and restored. Therefore our problem is not correct yet. We need to first execute before this sequence of instructions. Push R17 to save its value. Because we are overriding it here. And before we finish we do the opposite or the symmetric operation. Pop R17. And as you can see what we have done is not only preserve the value of R17. But also the stack at points A and B. The stack is exactly the same. I arrive with certain stack here. I put a temporary value, remove the temporary value. I'm ready now to terminate the program with exactly the same stack. Now let's summarize six points that are very important in this program. First I can access N1 directly with destruction LDS. Remember LDS, R24 and 1. But I can also access N1 indirectly through its address loaded in X. And that was instruction LD. Then you give a register in X. And I can add this which is called a post increment. Which by the way is optional. You can use it or not. But if you plan to access the following data in memory, it's very convenient because it leaves the register already modified and pointing to the next data. We can again store data directly with instruction STS. So we could have done something like STS result R24. And this instruction would replace this one over here. It would be exactly equivalent. However, since we already had register X, that has been used to access this position. And then it was post incremented. Register X at this point was already pointing there. Therefore, we can also store indirectly. And this is instruction STX R24. Finally, the other two options or the other two aspects that we observe here is that we saved and restore R17. Very important because it's one of the registers that we need to observe that rule. And the end is that start and finish the program with the same. And what I mean is in positions A that is here and here. And this concludes the example of the assembly program.