Behold the Stack, Part II

At the lowest programming level, you encounter machine code. This is the language of the processor itself. Machine code directs the processor to do things, such as read from or write to memory, store data, perform math, and other tasks. And if you dare to program a processor directly, you’ll encounter something called the stack pointer register.

In Figure 1, you see the Code::Blocks debugger showing the processor’s register dump. The Registers are storage areas in the processor; the values stored in each register are shown in the Hex and Integer columns.

Figure 1. The processor's register dump.

Figure 1. The processor’s register dump.

Most of the registers store data or reference locations in memory. All-in-all, I find processor programming fascinating, but it’s all terribly trivial these days.

Of note for this Lesson, register esp is the stack pointer register (The e means that it’s 32-bits wide.) The register holds the memory location of the top of the stack.

Register ebp is the base pointer register. It references the bottom or start of the stack.

As the processor churns through machine code, the various registers are manipulated. The stack pointer is also manipulated, but only under certain conditions.

For example, a push instruction sets a value onto the stack, either directly or the value stored in a register. The value is copied to the stack pointer’s memory location, then the stack pointer is incremented. Figure 2 illustrates this process.

Figure 2. The direct value 0x002A is pushed onto the stack.

Figure 2. The direct value 0x002A is pushed onto the stack.

A pop instruction removes a value from the stack. The value stored at the stack pointer’s location is transferred into a named register (typically eax, known as the accumulator) and the stack pointer is decremented. Figure 3 illustrates this concept.

Figure 3. The value 0x002A is popped from the stack and stored in register eax.

Figure 3. The value 0x002A is popped from the stack and stored in register eax.

Stack storage is used in several ways. To directly manipulate the stack, you can use the Assembly language push and pop instructions. In the following chunk of Assembly code, the contents of register eax and swapped with register ebx:

    push eax        ;save register value on the stack
    push ebx
    pop eax         ;put ebx into eax
    pop ebx         ;put eax into ebx

This operation succeeds because the last item sent (pushed) to the stack is the first item popped out — that’s LIFO or last-in, first-out. The result is that the register’s values are exchanged. And this operation is necessary because Assembly language lacks an assignment operator. (And even if the processor’s instruction set features a swap or similar instruction, using push-pop works faster.)

The other way the stack is used is for Assembly call and ret (return) instructions, which has direct application in C and other programming languages. I’ll cover more on this topic in next week’s Lesson.

Leave a Reply