开发者

GCC with the -fomit-frame-pointer option

开发者 https://www.devze.com 2023-01-10 12:25 出处:网络
I\'m using GCC with the -fomit-frame-pointer and -O2 options. When I looked through the assembly code it generated,

I'm using GCC with the -fomit-frame-pointer and -O2 options. When I looked through the assembly code it generated,

push %ebp
movl %esp, %ebp

at the start and pop %ebp at the end i开发者_运维问答s removed. But some redundant subl/addl instructions to esp is left in - subl $12, %esp at the start and addl $12, %esp at the end.

How will I be able to remove them as some inline assembly will jmp to another function before addl is excecuted.


You probably don't want to remove those -- that's usually the code that allocates and deallocates your local variables. If you remove those, your code will trample all over the return addresses and such.

The only safe way to get rid of them is not to use any local variables. Even in macros. And be really careful about inline functions, as they often have their own locals that'll get put in with yours. You may want to consider explicitly disabling function inlining for that section of code, if you can.

If you're absolutely sure that the adds and subs aren't needed (and i mean really, really sure), on my machine GCC apaprently does some stack manipulation to keep the stack aligned at 16 byte boundaries. You may be able to say "-mpreferred-stack-boundary=2", which will align to 4-byte boundaries -- which x86 processors like to do anyway, so no code is generated to realign it. Works on my box with my GCC; int main() { return 0; } turned into

main: 
    xorl %eax, %eax
    ret

but the alignment code looked different to start with...so that may not be the problem for you.

Just so you're warned: optimization causes a lot of weird stuff like that to happen. Be careful with hand-coded assembler language and optimized <insert-almost-any-language-here> code, especially when you're doing something as unstructured as a jump from the middle of one function into another.


I solved the problem by giving a function prototype, then defining it manually like this:

void my_function();

asm (
    ".globl _my_function\n"
"_my_function:\n\t"
/* Assembler instructions go here */
);

Later I also wanted the function to be exported, so I added this at the end of the source file:

asm (
    ".section  .drectve\n\t"
    ".ascii \" -export:my_function\"\n"
);


How will I be able to remove them as some inline assembly will jmp to another function before addl is executed.

This will corrupt your stack, that caller expects the stack pointer to be corrected on function return. Does the other function return by ret instruction? What exactly do you try to achieve? maybe there's another solution possible?

Please, show us the lines around the function call (in the caller) and your entry/exit part of your function in question.

0

精彩评论

暂无评论...
验证码 换一张
取 消