Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
The Stack

Let’s go back to our earlier Multiplyexample and examine what happens in
Step 2 when the program allocates storage space for variable “z”. The specific
actions taken at this stage will depend on some seriously complex logic that
takes place inside the compiler. The general idea is that the value is placed
either in a register or on the stack. Placing the value in a register simply means
that in Step 4 the CPU would be instructed to place the result in the allocated
register. Register usage is not managed by the processor, and in order to start
using one you simply load a value into it. In many cases, there are no available
registers or there is a specific reason why a variable must reside in RAM and
not in a register. In such cases, the variable is placed on the stack.
Astackis an area in program memory that is used for short-term storage of
information by the CPU and the program. It can be thought of as a secondary
storage area for short-term information. Registers are used for storing the most
immediate data, and the stack is used for storing slightly longer-term data.
Physically, the stack is just an area in RAM that has been allocated for this pur-
pose. Stacks reside in RAM just like any other data—the distinction is entirely
logical. It should be noted that modern operating systems manage multiple
stacks at any given moment—each stack represents a currently active program
or thread. I will be discussing threads and how stacks are allocated and man-
aged in Chapter 3.
Internally, stacks are managed as simple LIFO (last in, first out) data struc-
tures, where items are “pushed” and “popped” onto them. Memory for stacks
is typically allocated from the top down, meaning that the highest addresses
are allocated and used first and that the stack grows “backward,” toward the
lower addresses. Figure 2.1. demonstrates what the stack looks like after push-
ing several values onto it, and Figure 2.2. shows what it looks like after they’re
popped back out.
A good example of stack usage can be seen in Steps 1 and 6. The machine
state that is being stored is usually the values of the registers that will be used
in the function. In these cases, register values always go to the stack and are
later loaded back from the stack into the corresponding registers.

40 Chapter 2

Free download pdf