POPF, POPFD, POPFQ

Pop Stack Into EFLAGS 注册

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
9DPOPFZO有效有效堆叠的顶部弹出为下16位的EFLAGS.
9DPOPFDZO不可编码有效堆叠的顶部弹入EFLAGS.
9DPOPFQZO有效不可编码堆栈的流行顶部和零延伸到RFLAGS.

实测开销

正在从 arch-data 加载实测数据...

说明

从堆栈顶部弹出一个双字(POPFD)(如果当前操作数的大小属性为32),并将该值存储在EFLAGS的寄存器中,或者从堆栈顶部弹出一个单词(如果操作数的大小属性为16),并将其存储在EFLAGS寄存器的下16位(即FLAGS寄存器)中. 这些指令推翻了PUSHF/PUSHFD/PUSHFQ指令的操作.

POPF(流行旗)和POPFD(流行旗双人)mnemonics参考了相同的操作码. POPF指令用于操作数大小属性16时;POPFD指令用于操作数大小属性32时. 一些组装器可能会将操作数大小强制到16对POPF,将POPFD强制到32对. 其他可能将mnemonics作为同义词(POPF/POPFD),并使用操作数大小属性的设置来确定从堆栈中弹出值的大小.

POPF/POPFD对EFLAGS寄存器变化的影响,取决于运行模式. 详情见下文表4-20和密钥。

在保护,兼容性,或64位模式下运行特权级别0(或相当于特权级别0的实地址模式)时,除了RF1,VIP,VIF,和VM之外,EFLAGS登记册中的所有非保留旗帜都可以修改. VIP,VIF,和VM保持不受影响.

当在保护,兼容,或64位模式下运行时,特权级别大于0,但小于或等于IOPL时,除了IOPL字段和RF,IF,VIP,VIF,和VM之外,所有旗帜都可以修改;这些旗帜不受影响. 只有操作数的大小属性为32,才能修改AC和ID旗. 中断的旗帜( IF) 只有在执行级别至少与 IOPL 相同时才会更改 。 如果一个 POPF/POPFD 指令执行时没有足够特权,则不发生例外,但特权位不变.

当在虚拟 8086 模式(EFLAGS.VM = 1)中运行时,没有虚拟 8086 模式扩展(CR4.VME = 0),POPF/POPFD指令只能使用IOPL = 3;否则,会出现一般保护例外(#GP). 如果启用虚拟-8086模式扩展(CR4.VME = 1),则POPF(但不是POPFD)可以用IOPL < 3.

(保护-mode虚拟间断功能--通过设置CR4.PVI而启用--以与虚拟 8086 模式扩展相同的方式影响CLI和STI指令. 然而,POPF不受CR4.PVI的影响. )

在64位模式中,mnemonic指定为POPFQ(注意32位操作数不能编码). POPFQ从堆栈中弹出64位. 预留的RFLAGS位(包括RFLAGS的上32位)不受影响.

见英特尔(R)64和IA-32架构软件开发者手册第1卷第3章,关于EFLAGS登记册的更多信息.

  1. 联合国 RF在POPF执行后总是0. 这是因为POPF像所有指令一样,在RF开始执行时会清除它.

POPF/POPFD对EFLAGS登记册的影响

模式操作大小CPLIOPL2120191817161413:1211109876420页:1
IDVIPVIFACVMRFNTIOPLOFDFIFTFSFZFAFPFCF
实时地址1600-3NNNNN0SSSSSSSSSSS
模式3200-3SNNSN0SSSSSSSSSSS
(CR0.PE = 0)
保护,1600-3NNNNN0SSSSSSSSSSS
兼容性,161-3<CPLNNNNN0SNSSNSSSSSS
和 64比特161-3CPLNNNNN0SNSSSSSSSSS
模式32, 6400-3SNNSN0SSSSSSSSSSS
(CR0.PE = 132, 641-3<CPLSNNSN0SNSSNSSSSSS
EFLAGS.VM = 0)32, 641-3CPLSNNSN0SNSSSSSSSSS
1630-2XXXXXXXXXXXXXXXXX1
虚拟-80861633NNNNN0SNSSSSSSSSS
(CR0.PE = 1
EFLAGS.VM = 13230-2XXXXXXXXXXXXXXXXX1
CR4.VME = 0)3233SNNSN0SNSSSSSSSSS
1630-2N/N/SV/N/N/0/S/N/XS/S/N/S/S/S/S/S/S/2,3
VMEXXXXXXXXXXXXXXXX
(CR0.PE = 11633NNNNN0SNSSSSSSSSS
EFLAGS.VM = 13230-2XXXXXXXXXXXXXXXXX1
CR4.VME = 1)
3233SNNSN0SNSSSSSSSSS

行动

IF EFLAGS.VM = 0 (* Not in Virtual-8086 Mode *)
    THEN IF CPL = 0 OR CR0.PE = 0
          THEN
                IF OperandSize = 32;
                      THEN
                            EFLAGS := Pop(); (* 32-bit pop *)
                            (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;
                            VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)
                      ELSE IF (Operandsize = 64)
                            RFLAGS = Pop(); (* 64-bit pop *)
                            (* All non-reserved flags except RF, VIP, VIF, and VM can be modified;
                            VIP, VIF, VM, and all reserved bits are unaffected. RF is cleared. *)


                  ELSE (* OperandSize = 16 *)
                        EFLAGS[15:0] := Pop(); (* 16-bit pop *)
                        (* All non-reserved flags can be modified. *)

            FI;
      ELSE (* CPL > 0 *)

            IF OperandSize = 32
                  THEN
                        IF CPL > IOPL
                              THEN
                                    EFLAGS := Pop(); (* 32-bit pop *)
                                    (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;
                                    IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)
                              ELSE
                                    EFLAGS := Pop(); (* 32-bit pop *)
                                    (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;
                                    IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)
                        FI;
                  ELSE IF (Operandsize = 64)
                        IF CPL > IOPL
                              THEN
                                    RFLAGS := Pop(); (* 64-bit pop *)
                                    (* All non-reserved bits except IF, IOPL, VIP, VIF, VM, and RF can be modified;
                                    IF, IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)
                              ELSE
                                    RFLAGS := Pop(); (* 64-bit pop *)
                                    (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;
                                    IOPL, VIP, VIF, VM, and all reserved bits are unaffected; RF is cleared. *)
                        FI;
                  ELSE (* OperandSize = 16 *)
                        EFLAGS[15:0] := Pop(); (* 16-bit pop *)
                        (* All non-reserved bits except IOPL can be modified; IOPL and all
                        reserved bits are unaffected. *)

            FI;
      FI;
ELSE (* In virtual-8086 mode *)
      IF IOPL = 3

            THEN
                IF OperandSize = 32
                        THEN
                              EFLAGS := Pop();
                              (* All non-reserved bits except IOPL, VIP, VIF, VM, and RF can be modified;
                              VIP, VIF, VM, IOPL, and all reserved bits are unaffected. RF is cleared. *)
                        ELSE
                              EFLAGS[15:0] := Pop(); FI;
                              (* All non-reserved bits except IOPL can be modified; IOPL and all reserved bits are unaffected. *)
                  FI;

            ELSE (* IOPL < 3 *)
                  IF (Operandsize = 32) OR (CR4.VME = 0)
                        THEN #GP(0); (* Trap to virtual-8086 monitor. *)
                        ELSE (* Operandsize = 16 and CR4.VME = 1 *)
                              tempFLAGS := Pop();
                              IF (EFLAGS.VIP = 1 AND tempFLAGS[9] = 1) OR tempFLAGS[8] = 1
                                    THEN #GP(0);
                                    ELSE


                                              EFLAGS.VIF := tempFLAGS[9];
                                              EFLAGS[15:0] := tempFLAGS;
                                              (* All non-reserved bits except IOPL and IF can be modified;
                                              IOPL, IF, and all reserved bits are unaffected. *)
                                  FI;
                      FI;
          FI;
FI;

受影响的旗帜

所有旗帜都可能会受到影响;详情见行动科。

异常

保护模式
#SS(0)如果堆栈顶部不在堆栈段之内。 #PF(fault-code) 如果发生 页面错误 。
#AC(0)如果在CPL = 3 和对齐检查时进行不匹配的内存引用.
#UD如果使用 LOCK 前缀 。
实地址模式
#SS如果堆栈顶部不在堆栈段之内.
#UD如果使用 LOCK 前缀 。
虚拟 8086 模式
#GP(0)如果IOPL <联合国VME未启用。如果IOPL <3和32位数操作数大小。如果IOPL < 3, EFLAGS.VIP=1,第9项(IF)设置在FLAGS堆栈上的值。如果IOPL <3和比特 8 (TF) 设置在FLAGS。如果试图执行POPF/POPFD带有指令操作数- 大小覆盖前缀。
#SS(0)如果堆栈顶部不在堆栈段之内。 #PF(fault-code) 如果发生 页面错误 。
#AC(0)如果在启用对齐检查时进行了不匹配的内存引用 。
#UD如果使用 LOCK 前缀 。
兼容模式
与保护模式例外相同.
64 位模式
#SS(0)如果堆栈地址是非冠状的。 #PF(fault-code) 如果发生 页面错误 。
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果使用 LOCK 前缀 。

来源