通常在函数调用中使用堆栈来传递参数,保存函数返回地址和为自动变量分配内存。
通常在进入函数中时有两条命令,如下:
push ebp ; 保存上一个函数的栈帧基地址
mov ebp,esp ; 设置新的函数栈帧基地址
在返回函数前通常有如下两条指令:
mov esp,ebp ; 将当前函数栈帧基地址保存到esp中
pop ebp ; 恢复上一个函数的栈帧基地址
这是前奏。。之后Intel又设计了两条指令来简化上面的两个步骤,那就是ENTER和LEAVE指令。
我先说LEAVE指令吧。。这条指令就相当于 mov esp,ebp 和 pop ebp 两条指令的执行效果。
而ENTER指令要麻烦一点。我先将它的指令格式列出来:
ENTER A,B
A表示的是在栈上分配的临时变量的空间大小,B表示词法嵌套级(我英文不好,原英文是:lexical nesting level)
A很容易理解,就是sub esp,N之类的指令,用来给当前函数的栈帧分配局部变量空间。
B我也不太明白啥意思。不过没关系,一般这个值为0。
举个例子吧,例如:ENTER 4,0 相当于如下三条指令:
push ebp
mov ebp,esp
sub esp,4
就这么简单!但是这条enter指令也有一个先天上的不足,那就是速度慢。所以一般编译器生成代码时很少使用enter指令。还是用以前的老方法,倒是LEAVE指令经常被用到。
附:
ENTER - Make Stack Frame (80188+)
Usage: ENTER locals,level
Modifies flags: None
Modifies stack for entry to procedure for high level language.
Operand "locals" specifies the amount of storage to be allocated
on the stack. "Level" specifies the nesting level of the routine.
Paired with the LEAVE instruction, this is an efficient method of
entry and exit to procedures.
Clocks Size
Operands 808x 286 386 486 Bytes
immed16,0 - 11 10 14 4
immed16,1 - 15 12 17 4
immed16,immed8 - 12+4(n-1) 15+4(n-1) 17+3n 4
C8 iw 00 ENTER imm16,0 Create a stack frame for a procedure
C8 iw 01 ENTER imm16,1 Create a nested stack frame for a procedure
C8 iw ib ENTER imm16,imm8 Create a nested stack frame for a procedure
//***************************************************************************
LEAVE - Restore Stack for Procedure Exit (80188+)
Usage: LEAVE
Modifies flags: None
Releases the local variables created by the previous ENTER
instruction by restoring SP and BP to their condition before
the procedure stack frame was initialized.
Clocks Size
Operands 808x 286 386 486 Bytes
none - 5 4 5 1
C9 LEAVE Set SP to BP, then pop BP
C9 LEAVE Set ESP to EBP, then pop EBP
//***********************************************************
PUSH - Push Word onto Stack
Usage: PUSH src
PUSH immed (80188+ only)
Modifies flags: None
Decrements SP by the size of the operand (two or four, byte values
are sign extended) and transfers one word from source to the stack
top (SS:SP).
Clocks Size
Operands 808x 286 386 486 Bytes
reg16 11/15 3 2 1 1
reg32 - - 2 1 1
mem16 16+EA 5 5 4 2-4 (W88=24+EA)
mem32 - - 5 4 2-4
segreg 10/14 3 2 3 1
immed - 3 2 1 2-3
-------参考YangNas'BlogYangNas'Blog