Those familiar with x86 assembly programming are very used to the typical function prologue / epilogue:
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 This same sequence of code can also be implemented with the ENTER and LEAVE instructions:
enter [size of local variables], 0 ... leave ret The ENTER instruction's second operand is the nesting level, which allows multiple parent frames to be accessed from the called function.
This is not used in C because there are no nested functions; local variables have only the scope of the function they're declared in. This construct does not exist (although sometimes I wish it did):
void func_a(void) { int a1 = 7; void func_b(void) { printf("a1 = %d\n", a1); /* a1 inherited from func_a() */ } func_b(); } Python however does have nested functions which behave this way:
def func_a(): a1 = 7 def func_b(): print 'a1 = %d' % a1 # a1 inherited from func_a() func_b() Of course Python code isn't translated directly to x86 machine code, and thus would be unable (unlikely?) to take advantage of this instruction.
Are there any languages which compile to x86 and provide nested functions? Are there compilers which will emit an ENTER instruction with a nonzero second operand?
Intel invested a nonzero amount of time/money into that nesting level operand, and basically I'm just curious if anyone uses it :-)
References:
grep-inggcc-4.8.2/gcc/config/i386/i386.c:10339that GCC simply never emitsENTERat all nowadays. And the comment at that line is quite clear:/* Note: AT&T enter does NOT have reversed args. Enter is probably slower on all targets. Also sdb doesn't like it. */git log -pon their cvs->svn->git converted repository shows that it already existed in the initial check-in in 1992.llvm/lib/Target/X86/X86FrameLowering.cpp:355a comment for theemitPrologue()method which reads in part; Spill general-purpose registers [for all callee-saved GPRs] pushq %<reg> [if not needs FP] .cfi_def_cfa_offset (offset from RETADDR) .seh_pushreg %<reg>. There are no mentions ofENTER, only pushes; And the enum constant for x86ENTERoccurs only 3 times in all of LLVM; It doesn't even look as though they have testcases for it.