我让Google告诉我该gcc选项的含义-fomit-frame-pointer,它将我重定向到以下声明.
-fomit帧指针
不要将帧指针保存在寄存器中以查找不需要的函数.这避免了保存,设置和恢复帧指针的指令; 它还在许多功能中提供额外的寄存器.它还使某些机器无法进行调试.
根据我对每个函数的了解,将在进程内存的堆栈中创建激活记录,以保留所有局部变量和更多信息.我希望这个帧指针意味着一个函数的激活记录的地址.
在这种情况下,什么是函数类型,它不需要将帧指针保持在寄存器中?如果我得到这个信息,我会尝试设计基于它的新函数(如果可能),因为如果帧指针没有保存在寄存器中,一些指令将在二进制中省略.在具有许多功能的应用程序中,这将显着提高性能.
我有一个仅包含以下内容的cpp文件:
void f(int* const x)
{
(*x)*= 2;
}
Run Code Online (Sandbox Code Playgroud)
我编译:
g++ -S -masm=intel -O3 -fno-exceptions -fno-asynchronous-unwind-tables f.cpp
Run Code Online (Sandbox Code Playgroud)
这导致f.s包含:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.intel_syntax noprefix
.globl __Z1fPi
.p2align 4, 0x90
__Z1fPi: ## @_Z1fPi
## BB#0:
push rbp
mov rbp, rsp
shl dword ptr [rdi]
pop rbp
ret
.subsections_via_symbols
Run Code Online (Sandbox Code Playgroud)
如果我删除了push,mov和pop指令并组装(在mac上,我正在使用Clang),结果对象文件要小4个字节.链接和执行结果具有相同的行为和相同大小的可执行文件.
这表明这些指令是多余的 - 为什么编译器会把它们放入?这只是一个留给链接器的优化吗?