Assembly 为什么编译器不使用输入和输出指令?

Assembly 为什么编译器不使用输入和输出指令?,assembly,x86,x86-64,compiler-optimization,Assembly,X86,X86 64,Compiler Optimization,在阅读程序的反汇编时,我注意到了一种模式。设置函数框架时,很少使用指令enter。我还将编译器资源管理器与最新的GCC一起使用——GCC不使用enter,而是使用leave 为什么不使用指令enter?为什么编译器使用两条或多条指令来执行可以在一条指令中完成的操作?(按下rbp,保存rsp,并使用子rsp在堆栈上分配,而不是使用输入0x20,0)。但是使用了离开。。。还有什么事是我不知道的吗?据我所知,离开相当于 mov ebp, esp pop ebp GCC使用leave,而MSVC不使用

在阅读程序的反汇编时,我注意到了一种模式。设置函数框架时,很少使用指令
enter
。我还将编译器资源管理器与最新的GCC一起使用——GCC不使用
enter
,而是使用
leave

为什么不使用指令
enter
?为什么编译器使用两条或多条指令来执行可以在一条指令中完成的操作?(按下rbp,保存rsp,并使用
子rsp
在堆栈上分配,而不是使用
输入0x20,0
)。但是使用了
离开
。。。还有什么事是我不知道的吗?据我所知,
离开
相当于

mov ebp, esp
pop ebp
GCC使用
leave
,而MSVC不使用。我不明白为什么从不使用
enter
,而有时使用
leave

为什么编译器不使用输入和输出指令

这些说明已在和年代使用,因此在1999年之前

今天,这些机器指令通常是
比简单的等价物慢。编译器编写者确实知道这一点,因此避免发出这些机器指令。

tl;dr:一条指令而不是两条指令并不总是意味着更快。是的,那很好,谢谢。问题不在于
leave
做什么,而是
enter
做什么
enter
太疯狂了,它应该为块结构高级语言中的嵌套堆栈框架提供汇编支持。由于现代处理器无法快速实现一般形式的
enter
,因此处理器实现者甚至忽略了仅为当前堆栈帧保留堆栈空间的不那么疯狂的版本。如果您查看Agner Fog的指令表,您会看到
输入a,0
~3-4倍于
推送;压敏电阻;sub
输入a、b
实际上需要很长时间。此外,现代编译器通常可以避免使用帧指针(因为现代调试和展开表使帧指针变得多余),因此帧指针大多是过去的遗迹,特别是在x86(_64)等寄存器匮乏的体系结构上,其中一个额外的寄存器对于编译器的寄存器分配器是非常有价值的。哦?我还有两个问题。如果我们不使用
enter
,为什么有时会使用
leave
?另外,我在哪里可以了解更多关于展开表的信息?(像例子一样)@EOF