Two Minute Drill: Stack Basics

Welcome back AskPerf!  Carrying on with our debugging / architectural theme from the last couple of weeks, today’s topic is about the stack.  A stack is a way of storing information – a data structure.  When a new object is placed on the stack it is placed on the top of the stack.  Similar to a stack of plates, papers or anything else that you can stack and manipulate in the real world, the first thing removed from the stack is the last thing put on.  This is referred to as LIFO – Last In, First Out.

There are two fundamental operations that are performed on the stack, the push and the pop.  A push operation initializes the stack if it is empty, and if there are items already on the stack, then the push operation adds an item to the top of the stack.  The pop operation removes an item from the top of the stack.  The pop operation exposes the next item on the stack, or results in an empty stack.

Stack information is stored in values called registers.  If you are analyzing a dump using the Windows Debugger, you can see what the register values are by using the r command as shown below:

kd> r
eax=ffdff13c ebx=000000e2 ecx=00000000 edx=00000100 esi=80d10cc0 edi=80d10c08
eip=804fc1bb esp=fbbfebf4 ebp=fbbfec0c iopl=0         nv up ei ng nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000286
804fc1bb 5d              pop     ebp

If you haven’t done any debugging or programming, the output of the r command probably looks like gibberish.  Don’t worry – once you learn how to decipher the information, it becomes clearer.  The most common registers that you’ll see are listed below:

  • esp = stack pointer
  • ebp = base pointer
  • eip = instruction pointer
  • eax, ebx, ecx, edx = general-purpose registers that are used to store intermediate results
  • edi, esi = used as general registers

When we’re looking at a stack trace in a debugger, what we’ll be looking at is assembly code.  There are a number of instructions that can be used in assembly, but some of the most common ones that you’ll see are listed below:

  • push – adds an item to the top of the stack or initializes the stack if it is empty
  • pop – removes an item from the top of the stack, or results in an empty stack
  • add / sub – add / subtract operations
  • cmp – compare the values of two
  • ret – return to the calling function

Armed with this information, here’s what a very simple assembly routine might look like (this is taken from an MSDN Article called Anatomy of a Stack Trace):

Assembly Code Explanation
push ebp Places the caller’s base pointer (ebp) onto the stack
mov ebp,esp Sets the base pointer (ebp) equal to the stack pointer (esp)
mov eax, [ebp+8] Grab the value of the first argument off the stack and store it in eax
add eax, [ebp+c] Add the second argument’s value to the value in eax
pop ebp Restore the caller’s base pointer
ret 8 Return to the calling function and remove 8 bytes from the stack

It may look extremely confusing, but what this routine does is add two values.  Again, don’t worry too much if you’re not an Assembly language guru or if things here aren’t 100% clear – the purpose of this post is just to get our feet wet.  In future posts, we’ll be digging in a little deeper and things should become clearer.

That’s all for today folks!  Hope you enjoyed this post.  Until next time …

Additional Resources:

CC Hameed

Share this post :