Why do you need to use the ebp register when organizing the program stack, if you can do without it (if there are no tricky asm inserts)? Why it is impossible to use such optimization by default? What is it connected with?
Closed due to the fact that the question is not clear to the participants of AK ♦ , Regent , user194374, Kromster , Yuri 12 Jan '17 at 18:12 .
Try to write more detailed questions. To get an answer, explain what exactly you see the problem, how to reproduce it, what you want to get as a result, etc. Give an example that clearly demonstrates the problem. If the question can be reformulated according to the rules set out in the certificate , edit it .
- 2Give examples of what use ebp is here and what optimization you are talking about - Mike
- @Mike: Well, you can theoretically address local variables and parameters theoretically and through ESP, if you carefully monitor the current amount of memory allocated on the stack. The question most likely refers to the addressing of local variables and subprogram parameters via EBP. - VladD
- x86_64 ABI, in principle, writes the same about it: AB%. This technique saves the two instructions and makes it possible to complete the general rule-order register (% rbp) available. - 0andriy
- In this whole discussion (question, answers, comments) I’m surprised by one thing. Hasn’t anyone ever heard of the magical ABI? - 0andriy
- @ 0andriy, and what does it change? The compiler himself will figure out how to address the stack to him and whether the prologue / epilogue is needed in each particular case. Manually, the programmer’s private affair, no one bothers him to do as he pleases. ABI speaks only about the organization of the stack, but does not impose any restrictions on how to work with it. - PinkTux
2 answers
This is primarily due to convenience. No one bothers you address through the register esp . But you need to constantly keep in mind that the stack pointer itself in the process of executing the code can jump as you please. And constantly changing the offset for the same entities (would you be comfortable if the variable is now called foo , and after a couple of lines should it be treated like a bar ?). In very simple cases it may make sense, I do it myself :) For example:
print_uint: pushad push dword [esp+36] push format_u ; "%u", 0 call printf pop eax pop eax popad ret 4 And compilers can generate code without enter/leave during optimization. But in the general case, this is a “micro-optimization” (and this is questionable), and it is not worth the hemorrhoids that are dragging along.
It is possible without it ( and it is very a pity sometimes ).
For example, gcc for test program
#include <stdio.h> int f() { return puts("xaxa"); } int main(void) { long a = 10; long long b = 11; int l = 100; float e = 8.8; f(a, b, l, e); return 0; } with optimization flags
avp@avp-ubu1:hashcode$ gcc -O -S tc avp@avp-ubu1:hashcode$ gcc --vers gcc.real (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. avp@avp-ubu1:hashcode$ does code without using ebp ( rbp ) to organize stack frames
.file "tc" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "xaxa" .text .globl f .type f, @function f: .LFB23: .cfi_startproc subq $8, %rsp .cfi_def_cfa_offset 16 movl $.LC0, %edi call puts addq $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE23: .size f, .-f .globl main .type main, @function main: .LFB24: .cfi_startproc subq $8, %rsp .cfi_def_cfa_offset 16 movsd .LC1(%rip), %xmm0 movl $100, %edx movl $11, %esi movl $10, %edi movl $1, %eax call f movl $0, %eax addq $8, %rsp .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE24: .size main, .-main .section .rodata.cst8,"aM",@progbits,8 .align 8 .LC1: .long 2684354560 .long 1075943833 .ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609" .section .note.GNU-stack,"",@progbits - By the way, what was interesting was: can the optimizer not restore the stack after each call to the
cdeclfunction, if there is no obvious need for it? And to do this, for example, once beforeret. You can check it, of course, but today it’s too lazy :) - PinkTux - @PinkTux, I don’t even understand why
subq $8, %rsp. By the way, with -O3 thef()body is reduced to 2 commands:movl $.LC0, %edi;jmp puts(however,call fremains) - avp - Yes, for sure :) pastebin.com/ZcuVXUnt - PinkTux
- @avp, section 3.2.2 x86_64 ABI clarifies this (% rsp) moment. - 0andriy
- 2Sorry, just got it. It is the alignment requirement that causes the compiler to subtract 8 from% rsp. The stack was aligned to 16, after the call it is not aligned (put the return address), to align it is enough to subtract 8. - avp