1

I don't see what I am doing wrong, this is my C code:

main() {
    int i = 0;
    if (i == 0) i++;
    return 0;
}

Compiling with gcc -S test.c

I was expecting "leave" instead of "popq %rbp".

.L2:
movl $0, %eax
popq %rbp
ret
joakim
  • 1,612
  • 1
  • 14
  • 23
  • 3
    `main()` should be `int main(void)` – Spikatrix Feb 04 '15 at 14:36
  • Add a -fomit-frame-pointer during compilation and observe the output. – a_pradhan Feb 04 '15 at 14:37
  • The `mov %rbp, %rsp` part of `leave` isn't needed when `%rsp` is still pointing to the right place, so `pop %rbp` is faster. `gcc` will still use `leave` (with most tuning options) if it needed a frame pointer *and* it had to reserve some extra stack space. – Peter Cordes Mar 01 '18 at 19:50

2 Answers2

1

I don't see what I am doing wrong

It's up to GCC to decide if it uses ENTER/LEAVE.
Since even INTEL deprecates the use of ENTER/LEAVE it's no wonder GCC doesn't use it (anymore).
Also movq %rbp,%rsp wasn't needed here and so you only found popq %rbp.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 2
    `gcc-4.8` *does* occasionally emit `leave`. Probably something to do with alignment or the size of the function. – EOF Feb 04 '15 at 22:02
  • @EOF: If RSP is already pointing to the right place, it just uses POP. Otherwise it uses LEAVE, e.g. at the end of a function with a C99 variable-length array. (gcc6.2 still does this, like in this example: https://godbolt.org/g/xRsk0m). clang uses mov / pop. Agner Fog says LEAVE is 3 uops, but I wonder if his measurement method accounted for extra stack-engine uops. (e.g. a sequence of `mov %rbp, %rsp` / `pop %rbp` would also be 3 uops per pair). – Peter Cordes Oct 01 '16 at 05:18
0

Intel64 and IA-32 Architectures Software Developer's Manual says:

The LEAVE instruction, which does not any operands, reverses the action of the previous ENTER instruction. The LEAVE instruction copies the contents of the EBP register into the ESP register to release all stack space allocated to the procedure. Then it restores the old value of the EBP register from the stack. This simultaneously restores the ESP register to its original value. A subsequent RET instruction then can remove any arguments and the return address pushed on the stack by the calling program for use by the procedure.

and gcc do this manually.

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Parham Alvani
  • 2,305
  • 2
  • 14
  • 25