我是汇编语言的初学者,并注意到编译器发出的x86代码通常在释放/优化模式下保持帧指针,当它可以使用EBP寄存器时.
我理解为什么帧指针可能使代码更容易调试,并且如果alloca()在函数内调用则可能是必要的.但是,x86只有很少的寄存器,并使用其中两个寄存器来保存堆栈帧的位置,当一个就足够了,对我来说没有意义.为什么即使在优化/发布版本中省略框架指针也是一个坏主意?
enter和之间的区别是什么?
push ebp
mov ebp, esp
sub esp, imm
Run Code Online (Sandbox Code Playgroud)
说明?是否存在性能差异?如果是这样,哪个更快,为什么编译器总是使用后者呢?
以相若方式将leave和
mov esp, ebp
pop ebp
Run Code Online (Sandbox Code Playgroud)
说明.
我不完全理解下面的注释内容.我在SO和gcc手册中阅读了一些帖子,并了解到它是用于堆栈地址对齐但却无法理解它是如何做到的.代码如下所示:
(gdb) disas main
Dump of assembler code for function main:
0x08048414 <+0>: push ebp
0x08048415 <+1>: mov ebp,esp
0x08048417 <+3>: and esp,0xfffffff0 ; why??
0x0804841a <+6>: sub esp,0x10
0x0804841d <+9>: mov DWORD PTR [esp],0x8048510
0x08048424 <+16>: call 0x8048320 <puts@plt>
0x08048429 <+21>: mov DWORD PTR [esp],0x8048520
0x08048430 <+28>: call 0x8048330 <system@plt>
0x08048435 <+33>: leave
0x08048436 <+34>: ret
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
代码是gcc在linux上使用(版本4.6.3)生成的.谢谢.
据说"离开"指令类似于:
movl %ebp, %esp
popl %ebp
Run Code Online (Sandbox Code Playgroud)
我理解这movl %ebp, %esp部分,并且它用于释放存储的内存(如本问题中所讨论的).
但是popl %ebp代码的目的是什么?
我必须学习汇编,我对于不同的寄存器/指向的内容感到非常困惑.
采取一个空的程序
//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优化?
为什么主函数,不需要堆栈帧初始化?
如果没有在主函数内设置帧指针,那么谁来完成这项工作呢?
它是由操作系统完成还是硬件的功能?
简单地说:
($esp) = 0xbffff49c。ret指令,该指令以Cannot access memory at address 0x90909094.0x90909094当堆栈顶部的值是 时,gdb 尝试访问的原因是0xbffff49c什么?
随机信息(以防万一):
[----------------------------------registers-----------------------------------]
EAX: 0x5a ('Z')
EBX: 0xb7fbeff4 --> 0x15ed7c
ECX: 0xbffff428 --> 0xb7fbf4e0 --> 0xfbad2a84
EDX: 0xb7fc0360 --> 0x0
ESI: 0x0
EDI: 0x0
EBP: 0x90909090
ESP: 0xbffff49c --> 0xbffff450 --> 0xdb31c031
EIP: 0x80485dd (<greeting+113>: ret)
EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x80485d0 <greeting+100>: mov DWORD PTR [esp],0x80487f4
0x80485d7 <greeting+107>: call 0x80483f0 …Run Code Online (Sandbox Code Playgroud)