16

I am currently learning assembly for Intel processors. Since the stack 'grows down', why do we have to add in order to access a specific element

[ebp + 8] ;; This will access the first param

I konw we have to skip the old ebp value and the return address and that's why we use 8 ( because each are 4 bytes long ). This is kinda strange.

Also, if ebp is a backup copy for esp, what is ebp's value in the main function Ex:

_start:

;; what's ebp value here ?

push eax
push ebx
call someFunction ;; this will create a stack frame

+-----------+
|   param1  |
+-----------+
|   param0  | <--- this is [ebp + 8] ( assuming mov ebp, esp )
+-----------+
|ret_address|
+-----------+
|    ebp    |
+-----------+ <--- esp

And also when we allocate memory for locals, we have to substract from ebp ... Please give a non-ambiguous answer. Thank you!

Andrei
  • 159
  • 1
  • 1
  • 3
  • 1
    A main() function is no different from a regular function, it has a prologue too. You didn't show one in your assembly snippet, not sure why. Space for locals is created by adjusting esp, not ebp. – Hans Passant Dec 02 '11 at 20:10
  • There are same questions: http://stackoverflow.com/questions/1395591/what-is-exactly-the-base-pointer-and-stack-pointer-to-what-do-they-point , and other linked to it – Abyx Dec 02 '11 at 21:30

2 Answers2

14

The initial value for %ebp is usually 0. This is so debuggers know when to end following the link chain in a backtrace.

You should think of %ebp as a reference point. For convenience, it is placed between the function arguments and local variables. That way, you access arguments with a positive offset, and variables with a negative offset, so it's easy to tell whether you are accessing a variable or an argument.

ninjalj
  • 42,493
  • 9
  • 106
  • 148
  • Why 0? Initial when CPU is powered on? – Abyx Dec 02 '11 at 21:11
  • `%ebp` is usually initialized to 0 by either the loader or the runtime library. That initialization to 0 is sometimes specified in a formal document (e.g: IIRC the ELF x86 psABI specifies it). – ninjalj Dec 02 '11 at 21:17
  • what loader or what runtime? If you are talking about specific OS, please explicitly state it. On my OS `ebp` isn't initialized to 0, at least in user-mode. Also, to be precise, register name is `ebp`, not `%ebp`. `%` is a prefix for register name. – Abyx Dec 02 '11 at 21:25
  • btw, there is `intel` tag, so why do you use AT&T syntax? – Abyx Dec 02 '11 at 21:26
  • @Abyx: note I wrote _usually_, though if your system doesn't initialize EBP, I wonder how debuggers are supposed to stop backtracing. In Linux, it's apparently done by `libc`. As to why I use `%ebp`, it's mostly an inconscious reflex. – ninjalj Dec 02 '11 at 21:33
3

Just as you said, the stack grows down. So, you subtract to grow the stack down for locals. You add to look back in the stack for elements stored there.

Brian Knoblauch
  • 20,639
  • 15
  • 57
  • 92