ENTER

Haga el marco para parámetros de procedimiento

estableVMJITAOTinstruccion

Codificaciones

OpcodeInstruccionOp/En64 bitsCompat/LegacyDescripcion
C8 iw 00ENTER imm16, 0IIValidoValidoCree un marco de pila para un procedimiento.
C8 iw 01ENTER imm16,1IIValidoValidoCree un marco de pila con un puntero anidado para un procedimiento.
C8 iw ibENTER imm16, imm8IIValidoValidoCree un marco de pila con punteros anidados para un procedimiento.

Codificacion de operandos

Cada modo es un valor de la columna Op/En de arriba. Dice en que campo de la instruccion codificada va cada operando, en el orden en que se escriben, y si la instruccion lo lee, lo escribe o ambas cosas.

II

  1. iw
  2. imm8byte inmediato que sigue a la instruccion

Coste medido

Cargando las mediciones de arch-data...

Descripción

Crea un marco de pila (compuesta de espacio para almacenamiento dinámico y almacenamiento de puntero de marco 1-32) para un procedimiento. El primer operando (imm16) especifica el tamaño del almacenamiento dinámico en el marco de la pila (es decir, el número de bytes de asignación dinámica en la pila para el procedimiento). El segundo operando (imm8) da el nivel de anidación lexical (0 a 31) del procedimiento. El nivel de anidación (imm8 mod 32) y el atributo OperandSize determinan el tamaño en bytes del espacio de almacenamiento para punteros de marco.

El nivel de anidación determina el número de punteros de marcos que se copian en la "zona de reproducción" del nuevo marco de pila del marco anterior. El tamaño predeterminado del puntero de marco es el atributo StackAddrSize, pero se puede sobrescribir usando el prefijo 66H. Así, el atributo OperandSize determina el tamaño de cada puntero de marco que será copiado en el marco de la pila y los datos que se transfieren de SP/ESP/RSP registrados en el registro BP/EBP/RBP.

Las instrucciones ENTER y compañero LEAVE se proporcionan para apoyar los lenguajes estructurados bloque. La instrucción ENTER (cuando se utiliza) es típicamente la primera instrucción en un procedimiento y se utiliza para establecer un nuevo marco de pila para un procedimiento. La instrucción LEAVE se utiliza al final del procedimiento (justo antes de la instrucción RET) para liberar el marco de la pila.

Si el nivel de anidación es 0, el procesador empuja el puntero del marco desde el BP/EBP/RBPregistro en la pila, copia la corrientepuntero de piladel SP/ESP/RSPregistro en el BP/EBP/RBPregistro, y carga el SP/ESP/RSPregistro con el valor actual del puntero de pila menos el valor del tamañooperando. Para los niveles de anidación de 1 o mayor, el procesador empuja los punteros de marco adicionales en la pila antes de ajustar el puntero de pila. Estos punteros de marco adicionales proporcionan el procedimiento llamado con puntos de acceso a otros marcos anidados en la pila. Ver "Procedimiento Llama para Idiomas Estructurados por Bloques" en el Capítulo 6 de Intel(R) 64 e IA-32 Architectures Software Developer's Manual, Volumen 1, para obtener más información sobre las acciones de la instrucción ENTER.

La instrucción ENTER causa un fallo de pagina cada vez que una escritura usando el valor final del puntero de pila (dentro del segmento de pila actual) lo haría.

En modo de 64 bits, el tamaño de operación predeterminado es de 64 bits; el tamaño de operación de 32 bits no se puede codificar. Uso de 66H prefijo cambios indicador tamaño de operando a 16 bits.

Cuando se utiliza el prefijo 66H y causa que el atributo OperandSize sea inferior al StackAddrSize, el software es responsable de lo siguiente:

el puntero de pila actual (RSP/ESP), tal que el valor de RBP/EBP después de "66H ENTER" sigue siendo una dirección válida en la pila. Esto asegura que "66H LEAVE" puede restaurar 16 bits de datos de la pila.

Operación

AllocSize := imm16;
NestingLevel := imm8 MOD 32;
IF (OperandSize = 64)

    THEN
          Push(RBP); (* RSP decrements by 8 *)
          FrameTemp := RSP;

   ELSE IF OperandSize = 32

          THEN
                Push(EBP); (* (E)SP decrements by 4 *)
                FrameTemp := ESP; FI;

   ELSE (* OperandSize = 16 *)

                Push(BP); (* RSP or (E)SP decrements by 2 *)
                FrameTemp := SP;
FI;

IF NestingLevel = 0

    THEN GOTO CONTINUE;
FI;

IF (NestingLevel > 1)
    THEN FOR i := 1 to (NestingLevel - 1)
          DO
                IF (OperandSize = 64)
                       THEN
                             RBP := RBP - 8;
                             Push([RBP]); (* Quadword push *)
                       ELSE IF OperandSize = 32
                             THEN
                                   IF StackSize = 32
                                         EBP := EBP - 4;
                                         Push([EBP]); (* Doubleword push *)
                                   ELSE (* StackSize = 16 *)
                                         BP := BP - 4;
                                         Push([BP]); (* Doubleword push *)
                                   FI;
                             FI;
                       ELSE (* OperandSize = 16 *)
                             IF StackSize = 64
                                   THEN
                                         RBP := RBP - 2;
                                         Push([RBP]); (* Word push *)
                             ELSE IF StackSize = 32
                                   THEN
                                         EBP := EBP - 2;
                                         Push([EBP]); (* Word push *)
                                   ELSE (* StackSize = 16 *)
                                         BP := BP - 2;
                                         Push([BP]); (* Word push *)
                             FI;
                       FI;
    OD;

FI;

IF (OperandSize = 64) (* nestinglevel 1 *)


    THEN
          Push(FrameTemp); (* Quadword push and RSP decrements by 8 *)

    ELSE IF OperandSize = 32
          THEN
                Push(FrameTemp); FI; (* Doubleword push and (E)SP decrements by 4 *)

    ELSE (* OperandSize = 16 *)
                Push(FrameTemp); (* Word push and RSP|ESP|SP decrements by 2 *)

FI;

CONTINUE:
IF 64-Bit Mode (StackSize = 64)

    THEN
                RBP := FrameTemp;

             RSP := RSP - AllocSize;

    ELSE IF OperandSize = 32
          THEN
                EBP := FrameTemp;

             ESP := ESP - AllocSize; FI;

    ELSE (* OperandSize = 16 *)
                BP := FrameTemp[15:1]; (* Bits 16 and above of applicable RBP/EBP are unmodified *)

             SP := SP - AllocSize;

FI;

END;

Banderas afectadas

None.

Excepciones

Modo protegido
#SS(0)Si el nuevo valor del registro SP o ESP está fuera del límite del segmento de la pila.
#PF(fault-code)Si un fallo de pagina ocurre o si una escritura usando el valor final del puntero de pila (dentro del segmento de pila actual) causaría un fallo de pagina.
#UDSi se utiliza el prefijo LOCK.
Modo real
#SSSi el nuevo valor del registro SP o ESP está fuera del límite del segmento de la pila.
#UDSi se utiliza el prefijo LOCK.
Modo virtual-8086
#SS(0)Si el nuevo valor del registro SP o ESP está fuera del límite del segmento de la pila.
#PF(fault-code)Si un fallo de pagina ocurre o si una escritura usando el valor final del puntero de pila (dentro del segmento de pila actual) causaría un fallo de pagina.
#UDSi se utiliza el prefijo LOCK.
Modo de compatibilidad
Las mismas excepciones que en modo protegido.
Modo de 64 bits
#SS(0)Si la dirección de la pila está en forma no canónica.
#PF(fault-code)Si un fallo de pagina ocurre o si una escritura usando el valor final del puntero de pila (dentro del segmento de pila actual) causaría un fallo de pagina.
#UDSi se utiliza el prefijo LOCK.

Fuentes