Hello guys, In today tutorial I'm going to cover an important topic in Computer science. Stack is a concept used in computer architecture. Before continue I would recommend you following tutorials to get a basic idea in C. Introduction to C language , Compiling C programs  Also read protostar stack0 tutorial if you want to learn about CPU , GDB and some basic assembly. Let's start. Hear you can see the source of C program we are using to build a binary. If you have some basic knowledge in C you can understand what's going on .
#include <stdio.h>

int testFunction(int a , int b , int c){
	char buff[40];
	int d = a + b + c ;
	return 0;
}	

int main(int argc, char const *argv[])
{
	testFunction(3,4,5);
	printf("after testFunction I'll be printed\n");
	return 0;
}
First it declare a function called testFunction . Actually testFunction does nothing. It gets 3 integer arguments as a,b and c. After a character buffer is declared. Finally assign the sum of a,b and c to integer d. Next in Main function we call testFunction with 3,4 and 5 as the arguments. In main function last thing to do is print a string using printf. Let's compile the program and run it. firstRunStack Did you notice I used some additional commands for compile the program. we use  command -g for give some additional information about the binary file to GDB. So we can list the source of binary in GDB. What means mpreferred-stack-boundary=2 ? . It tells GCC compiler to don't use stack alignment .If we don't use that command the assembly instructions will be more complex. So for now we use this command to understand things simply. Now the time to disassemble the binary. disassedMainandTFunc Hear I used GDB for disassemble the binary. First of all I have set disassembly-flavor to Intel. Personally I like to use Intel's syntax for assembly. Because it's clear and well presented. In above SS you can see I listed the source code in blue box. After that I disassembled the main function [in red box]. Next you can see the disassemble of testFunction function [green box]. setaBreacPoint After that I have set a break point at main+6. You can set a break point using the command break. To use a memory address as the argument for break command we use a asterisk '*' in-front of the memory address. stacklook As a yello box you can see the stack frame of Main function. Don't worry too much about that. I'll explain step by step how a stack frame is building. when we call  testFunction  inside the main function , first thing to do is put argument for  testFunction  in stack.
mov    DWORD PTR [esp+0x8],0x5
This assembly instruction will copy hex value 5 into a place in stack. Yes it is  esp + 0x8. You know that stack is starting from high address and grows to low address of memory. So esp + 8 means a lower address. Also 0x4 and 0x3 is copied in same way. 0x4 into esp+0x4 and 0x3 into esp (That means to the top of the stack). Did you notice some special thing? We push three arguments in reverse order. (5 , 4 and finally 3). Why that happens? . When we talk about the Stack there is a special concept called LIFO. It is an acronym for Last In First Out. Yes the name says it's all. If we put something on to the top of the stack first we can remove that lastly. Also the last item we put on the stack is the first thing get removed. Actually the word to put something in to the top of stack is PUSH. When we remove an item from the top of stack we call it POP. I think you can understand this in GDB by looking at following image. copied3Values Also hear is a graphical image to clear-up any confusion about this situation. stackaftercopied3values The next instruction in Main is call testFunction.  Call instruction does two things. First it push the return address to the top of the stack. Don't bother too much about ret address. I'll explain about it later. Next it'll overwrite eip with the address of first instruction in testFunction. So testFunction can continue the execution. In the following image you can see the return address is copied to the top of stack. (In a red box) copiedeip After we copy the ret-address to stack it will grow to the direction of low memory. So esp now pointing to a different location. (Actually old_esp - 0x4) . Take a look at what inside the red box. Yes we call it return address. There is a memory address in hex form. (0x08048402). Did you notice any special thing about it?. Go to the image we disassembled main and testFunction. You can see 0x08048402 is the address of printf instruction that print the string "after testFunction I'll be printed" . So can you build a connection between them? . Think in this way. After completing the function cpu should jump to main function again. We call it returning to main. Actually CPU should return to next instruction in main after testFunction. During the testFunction EIP will get changed. So if we want to set EIP to a address in main we must save that address in somewhere for future usage. Yes buddy, that place is the stack. That's why we saved that address[return address] in stack. :-) copiedEipGr Next there is an instruction called push ebp. EBP stands for extended base pointer. We can use ebp as a offset for fetch arguments. If we copy current value of esp to ebp, both esp and ebp will point to top of stack. Now we can access arguments like ebp+0x4 , ebp+0x8 etc. Wait why we can't use ESP for this purpose? During a function esp is not static. When we push something into stack esp is reduced and if we pop of stack esp will go high. First of all we want to put current value of ebp on the stack. copiedebp But why we put ebp in stack? .At the moment ebp is using by main function to fetch arguments. After completing testFunction , main function needs ebp again. So if we backup current value of ebp in stack , after completing testFunction we can restore old value of ebp. Hear I added a graphical image also. copiedEbpGr In above paragraph I said we want to copy esp into ebp. ebpandespbefore You can see values of esp and ebp before copy esp to ebp. Next instruction is mov ebp , esp. ebpandespafter Hear is the result of above instruction  Now both of esp and ebp point to top of the stack. espToEbpGr After hat there is a simple assembly instruction called sub esp,0x2c. It'll reduce esp by some value . So stack will grow to lower addresses. Actually what happened hear is we set some space for character buffer. In our C program we allocated bytes for this variable.
char buff[40];
subfromEsp subEspGr Next  five instructions are actually produced to do a special operation. Let's see what they do .
mov eax, DWORD PTR [ebp+0xc]
mov eax, DWORD PTR [ebp+0x8]
First instruction will copy what inside ebp+0xc to eax. In following image you can see that. copyintoeax Next it will put 0x3 into edx. Yes 0x3 is coming from ebp+0x8. I think now it is clear how we can use ebp as a offset to access arguments. In above two commands we saw somthing like DWORD PTR [ebp+0x8]. What that means? When we move something into stack we don't copy actual values. We only put the address of the value into that place. Take this example if we want to push the value of eax to stack we use push eax. But what if we use push [eax] ? . Then first CPU take the address in eax. After it will check what inside that address and what found on that address is pushed to the stack. I'll explain more about these addressing modes in a separate tutorial. copytoedx Now eax contains 4 and edx contains 3. Next there is a lea instruction. It is Load Effective Address. It will load the sum of eax and edx to eax Finally what happened is CPU will calculate 3+4 and put it in eax . Let's see what in eax after above instruction. leatoeax Yes it is 7. ebpOffset After that we fetch our last argument (5) and add it to our last result(7). So finall value will be 12 (0xc). returnSum Now if we think about  above 5 instructions , what they did?
int d = a + b + c ;
:-) . Yes we wanted many assembly code lines to do that simple operation. But in C it took one line. Now the job of testFunction is over. Now execution should  transferred to main function. Before that let's take a look at the current view of the stack. stackBeforeRet In green box we can see three arguments we pushed to stack. After that in a red box we can see the ret-address . Then in the blue box ebp is there . Finally there is a yellow box that filled with 0x000000C (this is the value that we calculated). Next there is an instruction called leave. It'll move the old value to ebp Did you remember we backed up the old value of ebp in stack. There is another thing to notice. After leave instruction top of the stack contains return address. leaveInstruction Finally there is a instruction called ret. It does nothing but take the value from the top of stack and put it in eip. So CPU can execute next things in main function. retInstruction OK . A long tutorial. I think I explained all things clearly. If you have any question , please leave a comment. So we can discuss more. Thank you for reading. If you enjoyed reading take a moment to share it.