Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description |
---|---|---|---|---|---|
C8 iw, ib ENTER imm16, imm8 | ii | Invalid | Invalid | Invalid | Create a stack frame with imm16 bytes reserved for locals and imm8 levels of nesting. |
Encoding
Encoding | Operand 1 | Operand 2 |
---|---|---|
ii | imm16 | imm8 |
Description
The ENTER
instruction is used to create a stack frame for procedure parameters. The first operand specifies the number of bytes to be reserved for the callee's local variables. The second operand (modulus 32) specifies the nesting level of the procedure.
If the nesting level (the second operand) is 0
, the processor pushes the frame pointer from rBP
onto the stack, and moves rSP
into rBP
. For nesting levels of one or more, the processor does the same, but pushes that number of frame pointers onto the stack as well.
This instruction's companion instruction, LEAVE
, is used to tear down the stack frame.
In Long Mode, the default operand size is 64 bits; 32-bit operation size cannot be encoded. Use of the OSIZE
prefix changes the operand size to 16-bit.
Operation
public void ENTER_16(U16 imm16, U8 imm8)
{
U8 nesting = imm8 % 32;
Push(BP);
U16 frameTemp = SP;
for (U8 i = 0; i < nesting; i++)
{
BP -= 2;
if (i < nesting - 1)
Push(Mem16[BP]); // only push the frame pointer if it's not the last one
}
BP = frameTemp;
SP -= imm16;
}
public void ENTER_16(U16 imm16, U8 imm8)
{
U8 nesting = imm8 % 32;
Push(EBP);
U32 frameTemp = ESP;
for (U8 i = 0; i < nesting; i++)
{
EBP -= 4;
if (i < nesting - 1)
Push(Mem32[EBP]); // only push the frame pointer if it's not the last one
}
EBP = frameTemp;
ESP -= imm16;
}
public void ENTER_64(U16 imm16, U8 imm8)
{
U8 nesting = imm8 % 32;
Push(RBP);
U64 frameTemp = RSP;
for (U8 i = 0; i < nesting; i++)
{
RBP -= 8;
if (i < nesting - 1)
Push(Mem64[RBP]); // only push the frame pointer if it's not the last one
}
RBP = frameTemp;
RSP -= imm16;
}
Flags Affected
None.Exceptions
Real-Address Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If the new value of
SS
- is outside the
SS
- segment' limit.
Virtual-8086 Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If the new value of
SS
- is outside the
SS
- segment' limit.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Protected Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If the new value of
SS
- is outside the
SS
- segment' limit.
#GP(0)
- If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULL
selector.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Compatibility Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If the new value of
SS
- is outside the
SS
- segment' limit.
#GP(0)
- If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULL
selector.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Long Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If a memory operand using the
SS
segment is in non-canonical form. - If the new value of
SS
is outside theSS
segment' limit.
#GP(0)
- If a memory operand (using a segment other than
SS
) is in non-canonical form. - If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULL
selector.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.