 In this video, we're going to explain the concept of the stack in a microprocessor or a microcontroller. The stack is basically the combination of two things. First, an area in memory. We're going to assume for the sake of this example that this memory addresses cells of one byte. So we have certain space in memory. These are the cells where we store the data. The combination of this space in memory with a register that we are going to call the stack pointer. Now this register, obviously, it's going to contain an address that points to a cell in memory, which we call the top of the stack. And typically we abbreviate this register and we call it SP. Now the mechanism here is very simple and it works as a regular stack. I have memory in which I can store data and I have a register with an address that points to the top of the stack. The two operations that are allowing this construction are putting things on top of the stack or removing things, in this case data, from the top of the stack. So the two instructions are push some data and pushing some data in terms of the elements of this construction. What it requires is first we have to write data above the top and then what we have to do is step number two is update the top. So another way of looking at it, this operation, basically what it means is that if we have the memory here and if this is the stack and we assume that we have the top here and therefore a register stack pointer is pointing here, after we execute the push data operation what happens is the data gets stored in the position above the top and then this register is modified and points to the previous position in memory. So this is the result of the push data operation. Analogously, the other operation that is allowed is pop data. As you can imagine, the two steps similar to what happens here that occur when we perform the operation is first we read the data on top of the stack and then we update, in other words again, this is our memory, this is the status of the stack, this is the top and this is our register stack pointer. After performing the pop data, what we do is we read this data, put it somewhere else and then we correct this register now to point to the position right below. So this is no longer the top, this is the new top. So as you can see in this operation what is actually happening is a memory write, let's call it mem write, and register update, whereas in the pop what we have is occurring a mem read operation and of course the register. Now what is this used for? The main purpose of the data is, let's just write it up here, to store temporary results. Now let's get two examples. We're going to assume, example number one, that we want to save temporarily some values and we're going to assume that these values are in the registers of the microcontroller. So let's imagine this scenario, I have this program here, this is my program, these are my instructions and what I would like to do is save some values before the microprocessor executes this program and restore them at the end. Let's assume that the values that I want to save are in registers R1 and R2. So the way to do that with the stack would be to push both registers R1 and R2 onto the stack, then go ahead and execute this program. We need to assume that this program is going to leave the stack at exactly the same state as it is found here and then at the end we simply restore and we say pop R2, pop R1 and with these four operations what we achieve is after executing this code block both values in R1 and R2 are preserved because I annotate them temporarily on the stack. Then this program may freely manipulate whatever values are in R1 and R2 because I had a copy on the stack and then I restore this copy to the original values. So I basically preserve the values that were there before. Another a bit more sophisticated use of the stack is when calling or invoking functions or sub-routines. This is typically what happens in a program. I have a few instructions executing and then I typically call another function, let's just say F1 which is somewhere else, suppose this is F1 which starts executing and at some point I end up calling another function which is called F2, suppose it's here, F2 executes a few instructions, I could have different calls nested one inside of the other which is typically what occurs in programs but then at the end I return from this function and we all know that what happens is that we need to return to this position here which is the instruction immediately following the call. We finish then the execution of this function and when we return, same thing happens, we return to exactly this position over here and this program continues executing. So this is one of the most powerful uses of the stack which is the following. When this first program calls function one, it has to remember the address to return from F1, let's just call it address return one which would be this position over here. How do I remember this address to return because I might have more than one as a matter of fact while I'm executing F1 and I call F2, I need to remember the address to return two because then when I execute the return instruction what happens is I go back exactly to the address indicated by this value and when I finish and execute this return instruction I need to return back to this position. So this can be very easily implemented with the stack. So what happens when I do this first call is we push in the stack, suppose this is the stack and I have initially the top pointing here with my stack pointer so whenever I make a function call since I need to go and now execute F1 but I need to remember this value temporarily, what I do is I write it on top of the stack address return one and I proceed freely to execute this function. Now this function itself calls F2 and it needs to write down somewhere that it has to return to this instruction. So I use the same trick and I put it on the stack address return two. So this value of the stack pointer is evolving until it gets all the way here and then what happens is as you can imagine you execute F2 and when you finish you return back by popping the top of the stack the address to return to and keep executing at the address pointed by this value and the same thing happens here when we return we pop now this value from the stack and we end up returning to the original position here. So basically what happens is that when I have an instruction which is a call in fact inside that instruction there is a push of the address to return. And when I have an instruction which is return I use the stack again and inside this instruction what it occurs is there is a pop of the address that we return and this value needs to be stored in one of the most important registers which is the program count. So this is what the stack is typically used for these two scenarios and it's mostly to annotate or to remember temporary results.