POP

Apaga un valor de la plataforma

estableVMJITAOTinstruccion

Codificaciones

OpcodeInstruccionOp/En64 bitsCompat/LegacyDescripcion
8F /0POP r/m16MValidoValidoParte superior de la pila en m16; aumento puntero de pila.
8F /0POP r/m32MNo codificableValidoParte superior de la pila en m32; aumento puntero de pila.
8F /0POP r/m64MValidoNo codificableTop pop de la pila en m64; aumento puntero de pila. No se puede codificar 32-bit tamaño de operando.
58+ rwPOP r16OValidoValidoParte superior de la pila en r16; aumento puntero de pila.
58+ rdPOP r32ONo codificableValidoParte superior de la pila en r32; aumento puntero de pila.
58+ rdPOP r64OValidoNo codificableTop pop de la pila en r64; aumento puntero de pila. No se puede codificar 32-bit tamaño de operando.
1FPOP DSZONo validoValidoParte superior de la pila en DS; aumento puntero de pila.
07POP ESZONo validoValidoParte superior de la pila en ES; aumento puntero de pila.
17POP SSZONo validoValidoParte superior de la pila en SS; aumento puntero de pila.
0F A1POP FSZOValidoValidoTop Pop de la pila en FS; aumento puntero de pila por 16 bits.
0F A1POP FSZONo codificableValidoTop Pop de la pila en FS; aumento puntero de pila por 32 bits.
0F A1POP FSZOValidoNo codificableTop Pop de la pila en FS; aumento puntero de pila por 64 bits.
0F A9POP GSZOValidoValidoParte superior de la pila en GS; aumento puntero de pila por 16 bits.
0F A9POP GSZONo codificableValidoParte superior de la pila en GS; aumento puntero de pila por 32 bits.
0F A9POP GSZOValidoNo codificableParte superior de la pila en GS; aumento puntero de pila por 64 bits.

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.

M

  1. modrm.rm escriturabyte ModRM, campo r/m (bits 2-0); con el byte SIB y el desplazamiento cuando el campo mod los pide

O

  1. opcode.reg escrituralos tres bits bajos del propio byte de opcode

Coste medido

Cargando las mediciones de arch-data...

Descripción

Carga el valor desde la parte superior de la pila a la ubicación especificada con el operando de destino (o explícita código de operación) y luego aumenta el puntero de pila. El operando de destino puede ser un registro de proposito general, ubicación de memoria, o registro de segmentos.

Los tamaños de dirección y operando se determinan y utilizan de la siguiente manera:

prefijo de instrucción (67H).

El tamaño de la dirección se utiliza sólo cuando se escribe a un operando de destino en memoria.

ser sobrescribido por prefijos de instrucción (66H o REX.W).

El tamaño de operando (16, 32, o 64 bits) determina la cantidad por la que se aumenta el puntero de pila (2, 4 o 8).

tamaño del puntero de pila (16 o 32 bits); en modo de 64 bits, el tamaño del puntero de pila es siempre 64 bits.

El tamaño de la dirección de la pila determina el ancho del puntero de pila cuando la lectura de la pila en la memoria y cuando aumenta el puntero de pila. (Como se indicó anteriormente, la cantidad por la que se aumenta el puntero de pila es determinada por el tamaño de operando.)

Si el operando de destino es uno de los registros del segmento DS, ES, FS, GS o SS, el valor cargado en el registro debe ser un selector de segmento válido. En modo protegido, golpear un selector de segmento en un registro de segmentos automat-

ically causes the descriptor information associated with that segment selector to be loaded into the hidden (shadow) part of the segment register and causes the selector and the descriptor information to be validated (see the "Operation" section below).

Un valor NULL (0000-0003) se puede introducir en el registro DS, ES, FS o GS sin causar una falla de protección general. Sin embargo, cualquier intento subsiguiente de referencia a un segmento cuyo registro de segmento correspondiente se carga con un valor NULL causa una excepción de protección general (#GP). En esta situación, no se produce referencia de memoria y el valor guardado del registro de segmento es NULL.

La instrucción POP no puede introducir un valor en el registro CS. Para cargar el registro CS de la pila, utilice la instrucción RET.

Si el registro ESP se utiliza como un registro base para abordar un operando de destino en memoria, la instrucción POP compute la dirección efectiva del operando después de que aumenta el registro ESP. Para el caso de una pila de 16 bits donde ESP envuelve a 0H como resultado de la instrucción POP, la ubicación resultante de la escritura de memoria es procesor familiar.

La instrucción POP ESP aumenta el puntero de pila (ESP) antes de que los datos en la parte superior antigua de la pila se escriban en el destino.

Cargar el registro SS con una instrucción POP suprime o inhibe algunas excepciones de depuración e inhibe interrumpir en el siguiente límite de instrucción. (La inhibición termina después de la entrega de una excepción o la ejecución de la siguiente instrucción.) Este comportamiento permite que un puntero de pila se cargue en el registro ESP con la siguiente instrucción (POP ESP) antes de que un evento pueda ser entregado. Ver la sección 7.8.3, "Masking Excepciones e Interrupciones Al Interruptores", en Intel(R) 64 e IA-32 Architectures Software Developer's Manual, Volumen 3A. Intel recomienda que el software use la instrucción LSS para cargar el registro SS y ESP juntos.

En modo de 64 bits, el uso de un prefijo REX en forma de REX.R permite el acceso a registros adicionales (R8-R15). Cuando en modo de 64 bits, los COP usando operandos de 32 bits no son encodables y los COP a DS, ES, SS no son válidos. Vea la tabla resumen al comienzo de esta sección para la codificación de datos y límites.

Operación

IF StackAddrSize = 32
    THEN
          IF OperandSize = 32
                THEN
                      DEST := SS:ESP; (* Copy a doubleword *)
                      ESP := ESP + 4;
               ELSE (* OperandSize = 16*)
                      DEST := SS:ESP; (* Copy a word *)
                      ESP := ESP + 2;
          FI;
    ELSE IF StackAddrSize = 64
          THEN
                IF OperandSize = 64
                      THEN
                            DEST := SS:RSP; (* Copy quadword *)
                            RSP := RSP + 8;
                      ELSE (* OperandSize = 16*)
                            DEST := SS:RSP; (* Copy a word *)
                            RSP := RSP + 2;
                FI;
          FI;
    ELSE StackAddrSize = 16
          THEN
                IF OperandSize = 16
                      THEN
                            DEST := SS:SP; (* Copy a word *)
                            SP := SP + 2;


                      ELSE (* OperandSize = 32 *)
                            DEST := SS:SP; (* Copy a doubleword *)
                            SP := SP + 4;

                FI;

FI;

Loading a segment register while in protected mode results in special actions, as described in the following listing.
These checks are performed on the segment selector and the segment descriptor it points to.

64-BIT_MODE
IF FS, or GS is loaded with non-NULL selector;

    THEN
          IF segment selector index is outside descriptor table limits
                OR segment is not a data or readable code segment
                OR ((segment is a data or nonconforming code segment)
                      AND ((RPL > DPL) or (CPL > DPL))
                            THEN #GP(selector);
                IF segment not marked present
                      THEN #NP(selector);
          ELSE
                SegmentRegister := segment selector;
                SegmentRegister := segment descriptor;
          FI;

FI;
IF FS, or GS is loaded with a NULL selector;

          THEN
                SegmentRegister := segment selector;
                SegmentRegister := segment descriptor;

FI;

PREOTECTED MODE OR COMPATIBILITY MODE;

IF SS is loaded;
    THEN
          IF segment selector is NULL
                THEN #GP(0);
          FI;
          IF segment selector index is outside descriptor table limits
               or segment selector's RPL  CPL
                or segment is not a writable data segment
               or DPL  CPL
                      THEN #GP(selector);
          FI;
          IF segment not marked present
                THEN #SS(selector);
                ELSE
                      SS := segment selector;
                      SS := segment descriptor;
          FI;

FI;

IF DS, ES, FS, or GS is loaded with non-NULL selector;
    THEN


          IF segment selector index is outside descriptor table limits
                or segment is not a data or readable code segment
                or ((segment is a data or nonconforming code segment)
                and ((RPL > DPL) or (CPL > DPL))
                      THEN #GP(selector);

          FI;
          IF segment not marked present

                THEN #NP(selector);
                ELSE

                      SegmentRegister := segment selector;
                      SegmentRegister := segment descriptor;
           FI;
FI;

IF DS, ES, FS, or GS is loaded with a NULL selector
    THEN
          SegmentRegister := segment selector;
          SegmentRegister := segment descriptor;

FI;

Banderas afectadas

None.

Excepciones

Modo protegido
#GP(0)Si se intenta cargar el registro SS con el selector de segmento NULL. Si el operado de destino está en un segmento no redactible. Si una dirección efectiva de memoria operada está fuera del límite de segmento CS, DS, ES, FS o GS. Si el registro DS, ES, FS o GS se utiliza para acceder a la memoria y contiene un selector de segmento NULL.
#GP(selector)Siselector de segmentoíndice está fuera de los límites de la tabla descriptor. Si el registro SS está siendo cargado yel selector de segmento's RPLy el descriptor del segmentoDPLno son iguales a losCPL. Si el registro SS está siendo cargado y el segmento apuntado es un segmento de datos no escrito. Si el registro DS, ES, FS o GS está siendo cargado y el segmento apuntado no es un segmento de datos o código legible. Si el registro DS, ES, FS o GS está siendo cargado y el segmento apuntado es un segmento de datos o códigos no conformes, pero ambos elRPLy elCPLson mayores que losDPL.
#SS(0)Si la parte superior actual de la pila no está dentro del segmento de la pila. Si la dirección efectiva un operando de memoria está fuera del límite del segmento SS.
#SS(selector)Si el registro SS está siendo cargado y el segmento apuntado no está presente.
#NPSi el registro DS, ES, FS o GS está siendo cargado y el segmento apuntado no está presente. #PF(fault-code) Si ocurre un fallo de pagina.
#AC(0)Si se hace una referencia de memoria no alineada mientras que el nivel actual de privilegios es 3 y la comprobación de alineación está habilitada.
#UDSi se utiliza el prefijo LOCK.
Modo real
#GPSi un operando de memoria dirección efectiva está fuera del límite de segmento CS, DS, ES, FS o GS.
#UDSi se utiliza el prefijo LOCK.
Modo virtual-8086
#GP(0)Si un operando de memoria dirección efectiva está fuera del límite de segmento CS, DS, ES, FS o GS. #PF(fault-code) Si un fallo de pagina ocurre.
#AC(0)Si se hace una referencia de memoria no alineada mientras se activa la comprobación de alineación.
#UDSi se utiliza el prefijo LOCK.
Modo de compatibilidad
Lo mismo que las excepciones modo protegido.
Modo de 64 bits
#GP(0)Si la dirección de memoria está en forma no canónica.
#SS(0)Si la dirección de la pila está en forma no canónica.
#GP(selector)Si el descriptor está fuera del límite de tabla descriptor. Si el registro de FS o GS está siendo cargado y el segmento a que se refiere no es un segmento de datos o código legible. Si el registro de FS o GS está siendo cargado y el segmento a que se refiere es un segmento de código de datos o no conforme, pero tanto el RPL como el CPL son mayores que el DPL.
#AC(0)Si se hace una referencia de memoria no alineada mientras se activa la comprobación de alineación. #PF(fault-code) Si un fallo de pagina ocurre.
#NPSi el registro FS o GS está siendo cargado y el segmento apuntado no está presente.
#UDSi se utiliza el prefijo LOCK. Si se carga el registro DS, ES o SS.

Fuentes