Bar*_*mar 5 c optimization x86 assembly gcc
采取一个空的程序
//demo.c
int main(void)
{
}
Run Code Online (Sandbox Code Playgroud)
在默认优化时编译程序.
gcc -S demo.c -o dasm.asm
Run Code Online (Sandbox Code Playgroud)
我得到汇编输出为
//Removed labels and directive which are not relevant
main:
pushl %ebp // prologue of main
movl %esp, %ebp // prologue of main
popl %ebp // epilogue of main
ret
Run Code Online (Sandbox Code Playgroud)
现在在-O2优化时编译程序.
gcc -O2 -S demo.c -o dasm.asm
Run Code Online (Sandbox Code Playgroud)
我得到了优化的装配
main:
rep
ret
Run Code Online (Sandbox Code Playgroud)
在我最初的搜索中,我发现优化标志-fomit-frame-pointer负责删除序言和结尾.
我在gcc编译器手册中找到了有关该标志的更多信息.但是,由于手册的原因,我无法理解下面的原因,用于删除序言和结尾.
不要将帧指针保存在寄存器中以查找不需要的函数.
出于上述原因,还有其他方法吗?
"rep"教学的原因是什么,出现在-02优化?
为什么主函数,不需要堆栈帧初始化?
如果没有在主函数内设置帧指针,那么谁来完成这项工作呢?
它是由操作系统完成还是硬件的功能?
小智 5
编译器变得聪明,它知道你不需要存储在寄存器中的堆栈帧指针,因为你放入main()函数的任何东西都不使用堆栈.
至于rep ret:
这是原则.处理器尝试获取要执行的下几条指令,以便它可以开始解码和执行它们的过程.它甚至可以通过跳转和返回指令来做到这一点,猜测程序将在下一步发挥作用.
AMD在这里说的是,如果ret指令紧跟在条件跳转指令之后,它们的预测器就无法确定ret指令的去向.预取必须停止,直到ret实际执行,然后才能再次开始向前看.
"rep ret"技巧显然可以解决问题,并让预测器完成它的工作."rep"对指令没有影响.
来源:一些论坛,谷歌一句话找到它.
有一点需要注意的是,仅仅因为没有序言它并不意味着没有堆栈,你仍然可以轻松地推送和弹出它只是复杂的堆栈操作将是困难的.
没有序言/结语的函数通常被称为裸体.黑客喜欢使用它们,因为当你对它们进行jmp时它们不会污染堆栈,我必须承认我知道在优化之外没有其他用途.在Visual Studio中,它通过以下方式完成:
__declspec(naked)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1902 次 |
| 最近记录: |