assembly - 是否有任何语言/编译器使用具有非零嵌套级别的 x86 ENTER 指令?

标签 assembly x86 compiler-construction nested-function stack-frame

熟悉 x86 汇编编程的人非常习惯典型的函数序言/结尾:

push ebp ; Save old frame pointer.
mov  ebp, esp ; Point frame pointer to top-of-stack.
sub  esp, [size of local variables]
...
mov  esp, ebp ; Restore frame pointer and remove stack space for locals.
pop  ebp
ret

同样的代码序列也可以使用 ENTERLEAVE 指令实现:

enter [size of local variables], 0
...
leave
ret

ENTER 指令的第二个操作数是嵌套级别,它允许从被调用的函数访问多个父框架。

这在 C 中不使用,因为没有嵌套函数;局部变量仅具有它们所声明的函数的范围。这种构造不存在(尽管有时我希望它存在):

void func_a(void)
{
    int a1 = 7;

    void func_b(void)
    {
        printf("a1 = %d\n", a1);  /* a1 inherited from func_a() */
    }

    func_b();
}

然而,Python确实有这样的嵌套函数:

def func_a():
    a1 = 7
    def func_b():
        print 'a1 = %d' % a1      # a1 inherited from func_a()
    func_b()

当然,Python 代码不会直接转换为 x86 机器代码,因此无法(不太可能?)利用此指令。

是否有任何语言可以编译为 x86 并提供嵌套函数?是否有编译器会发出带有非零第二个操作数的 ENTER 指令?

英特尔在该嵌套级操作数上投入了非零的时间/金钱,基本上我只是好奇是否有人使用它:-)

引用文献:

最佳答案

enter 在实践中被避免,因为它的性能很差 - 请参阅 "enter" vs "push ebp; mov ebp, esp; sub esp, imm" and "leave" vs "mov esp, ebp; pop ebp" 中的答案。 。有一堆 x86 指令已过时,但出于向后兼容性的原因仍受支持 - enter 就是其中之一。 (leave 是可以的,编译器很乐意发出它。)

像在 Python 中一样完全通用地实现嵌套函数实际上是一个比简单地选择一些帧管理指令更有趣的问题 - 搜索“闭包转换”和“向上/向下 funarg 问题”,您会发现许多有趣的讨论.

请注意,x86 最初被设计为 Pascal 机器,这就是为什么有指令支持嵌套函数(enterleave),pascal 调用约定,其中被调用者从堆栈中弹出已知数量的参数 (ret K)、边界检查 (bound) 等。其中许多操作现已过时。

关于assembly - 是否有任何语言/编译器使用具有非零嵌套级别的 x86 ENTER 指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26323215/

相关文章:

c - 在 gcc 中编译时,如何在 c++ 的汇编代码中使用 C 变量?

汇编编程 : NASM VS MASM code

compiler-construction - 为什么需要虚拟机?

assembly - 以下带有 FLDCW 指令的 x86 汇编代码有何作用?

c++ - AVX2 代码比没有 AVX2 慢

asp.net-mvc - 在 Razor View 中使用 #pragma 语句

c# - 您不应该将 bin 文件夹视为临时文件夹吗?

c - 单个 sqrt() 的运行速度如何比放入 for 循环时慢两倍

c - 从磁盘读取文件期间使用中断

c - Y86 1 步停止异常 HLT