Koray Tugay
Koray Tugay

Reputation: 23800

What is the difference between stack and stack frame?

Here is the code I have:

17 mov      ebx,msg
18 mov      edx,5   
19 push     ebx

I am debugging with gdb and here is the output I have:

Breakpoint 1, print () at hello.asm:17
(gdb) info register sp 
sp: 0xbffff37c
(gdb) info stack
#0  print () at hello.asm:17

(gdb) step
(gdb) info register sp
sp: 0xbffff37c
(gdb) info stack
#0  print () at hello.asm:18

(gdb) step
(gdb) info register sp
sp: 0xbffff378
(gdb) info stack
#0  print () at hello.asm:19

Well obviously

push ebx

'decrements' the register sp by 4 bytes.. However when I type

info stack

I am still seeing print() at hello.asm:19

My question is, what is info stack showing me, and what is info register sp showing me? What is the relation between the stack register and the info stack?

Upvotes: 2

Views: 4058

Answers (4)

Jonathon Reinhart
Jonathon Reinhart

Reputation: 137438

"The stack" is a run-time data structure used by your application with two main purposes:

  1. Record information about called functions, so that you can call sub-routines, and return from them to where they were called from.
  2. Store temporary local variables in a context specific to the function which declared them.

Your CPU has a special register whose sole purpose is to maintain the address of the top of the stack in memory. This is the "stack pointer", or sp. Each "push" will decrement sp by 4 (in 32-bit mode), and store a value on the top of stack, at the address indicated by sp. Each "pop" will do the opposite, retrieving the value on the top of the stack, and adding 4 to sp.

Every time you call another function, additional information is stored on the stack, including the return address (#1) and the values of local variables (#2). Each function-call's-worth of information is known as a "frame".


info stack is a GDB command. It will "walk" the stack looking for the boundaries of these "stack frames". From the frame, it will display information like the function that it is associated with. It is smart enough, to not necessarily care about individual pushes and pops within a function; its purpose is to show you the higher-level information of the order in which functions were called.


The step command in GDB works at a source code line level. Normally, this is a line of C code. However, since you're working with assembly source, each line corresponds to one instruction.

Also, since you're working in assembly source, the concept of functions and stack frames might not apply! Compiling with -g embeds additional information into the binary file to help GDB match up assembly instructions with C functions, as well as information about local variables, etc.

I suggest that you first write a simple C program that calls functions and does interesting things. Compile it with -g, and play around stepping through it in GDB. Once you are familiar with this, it may be easier to work with debugging your assembly code.

Upvotes: 3

Dmitry Tolmachov
Dmitry Tolmachov

Reputation: 395

The esp register holds pointer into stack. Stack is special region of memory, that is used by applications written in c and c++ for holding the return addresses and local variables of functions. When debugger wants to determine the chain of function calls, that led to current proccess instructions - it does so by looking through chain of return addresses located in stack. This might have led to your confusion. So, current instruction != stack. Basically everytime you execute "call" instruction the address of next instruction is put into stack and stack pointer is decreased, so that when the "return" instruction will be called - the processor knows where to return.

Upvotes: 2

Hal
Hal

Reputation: 1139

when a new function is called, a new stack frame is set up. Each stack frame represents a function. Within that stack frame, when you push variables onto the stack, the stack pointer changes as the stack grows due to the push. The print() hello.asm:19 is gdb using the instruction pointer to show you where in your source execution is. You're in the print() function, line 19, which is "push %ebx" After you execute a callq to call another function, bt will show you the current stack frame has changed.

C-x a C-x 2 crl-2

in gdb will split your terminal into 3. Commands in the bottom pain, disassembly in the middle pane, and registers in the top pane. This way you can step and know where you're up to and what in the register state changes and when - which is really useful.

<rant> Until it crashes because gdb's ncurses interfaces (aka tui) is broken, the gdb gatekeepers don't care, don't accept patches that fix these crashes. If it gets to you too much you need to use a gdb front end, eg eclipse or insight which can show you the same information and may not crash due to stupid ncurses code</rant>

Upvotes: 2

zch
zch

Reputation: 15278

info stack is an alias to backtrace - it shows you what functions you are in, as far as it can determine it.

Stack and esp register are irrelevant to finding the deepest position on stack trace - the function you are currently executing. To find it you need to check eip - pointer to next instruction to execute. Only after that you can analyze the stack to find return addresses to other functions you are in.

Upvotes: 1

Related Questions