Make Stack Frame for Procedure Paramters

Encoding

EncodingOperand 1Operand 2
iiimm16imm8

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 the SS 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.