标志注册
当 x86 算术逻辑单元(ALU)执行 NOT 和 ADD 等操作时,它会在特殊的 16 位 FLAGS 寄存器中标记这些操作的结果(变为零,溢出,变为负)。32 位处理器将其升级为 32 位并将其称为 EFLAGS,而 64 位处理器将其升级为 64 位并将其称为 RFLAGS。
条件代码
但无论名称如何,寄存器都不能直接访问(除了几条指令 - 见下文)。相反,在某些指令中引用了单个标志,例如条件跳转或条件集,称为 Jcc 和 SETcc,其中 cc 表示条件代码并引用下表:
| 条件代码 | 名称 | 定义 |
|---|---|---|
E,Z |
相等,零 | ZF == 1 |
NE,NZ |
不等于,不是零 | ZF == 0 |
O |
溢出 | OF == 1 |
NO |
没有溢出 | OF == 0 |
S |
签 | SF == 1 |
NS |
没有签名 | SF == 0 |
P |
平价 | PF == 1 |
NP |
没有奇偶性 | PF == 0 |
| -————- | -— | -——— |
C,B,NAE |
携带,下方,不高于或等于 | CF == 1 |
NC,NB,AE |
不携带,不低于,高于或等于 | CF == 0 |
A,NBE |
以上,不低于或等于 | CF == 0 和 ZF == 0 |
NA,BE |
不高于,低于或等于 | CF == 1 或 ZF == 1 |
| -————– | -— | -——— |
GE,NL |
更大或更相等,而不是更少 | SF == OF |
NGE,L |
不大于或等于,小于 | SF != OF |
G,NLE |
更大,更小或相等 | ZF == 0 和 SF == OF |
NG,LE |
不大于,小于或等于 | ZF == 1 或 SF != OF |
在 16 位中,从 0 中减去 1 是 65,535 或 -1,具体取决于是使用无符号算法还是带符号算法 - 但目标在任何一种情况下都保持 0xFFFF。只有通过解释条件代码才能明确含义。更有说服力是从 0x8000 中减去 1:在无符号算术中,只是将 32,768 变为 32,767; 在签名算术中,它将 -32,768 改为 32,767 - 一个更值得注意的溢出!
条件代码分为表中的三个块:符号无关,无符号和有符号。后两个块中的命名使用 Above 和 Below 表示无符号,Greater 或 Less 表示签名。所以 JB 将是如果下面跳跃(未签名),而 JL 将是 Jump if less(签名)。
直接访问 FLAGS
上述条件代码对于解释预定义概念很有用,但实际标志位也可直接使用以下两条指令:
LAHF使用 Flags 加载AH寄存器SAHF将AH存储到 Flags 中
使用这些指令仅复制某些标志。整个 FLAGS / EFLAGS / RFLAGS 寄存器可以在堆栈中保存或恢复:
PUSHF/POPF将 16 位FLAGS推入/弹出堆栈PUSHFD/POPFD将 32 位EFLAGS推入/弹出堆栈PUSHFQ/POPFQ将 64 位RFLAGS推入/弹出堆栈
请注意,中断会自动保存并恢复当前的 [R/E]FLAGS 寄存器。
其他标志
除了上面描述的 ALU 标志之外,FLAGS 寄存器还定义了其他系统状态标志:
IF中断标志。
这是通过STI指令设置为全局启用中断,并使用CLI指令清除以全局禁用中断。DF方向标志。
内存到内存操作(如CMPS和MOVS)(在内存位置之间进行比较和移动)会自动递增或递减索引寄存器作为指令的一部分。DF标志指示哪一个发生:如果用CLD指令清除,它们会增加; 如果使用STD指令设置,它们会递减。TF陷阱标志。这是一个调试标志。设置它将使处理器进入单步模式:执行每条指令后,它将调用单步中断处理程序,预计将由调试器处理。没有设置或清除此标志的指令:你需要在内存中操作该位。
80286 标志
为了支持 80286 中的新多任务设施,英特尔为 FLAGS 寄存器添加了额外的标志:
IOPLI / O 权限级别。
为了保护多任务代码,某些任务需要访问 I / O 端口的权限,而其他任务必须停止访问它们。英特尔推出了四级权限级别,其中002 享有最高权限,而112 则最少。如果IOPL小于当前的权限级别,则任何访问 I / O 端口或启用或禁用中断的尝试都将导致一般性保护错误。NT嵌套任务标志。
如果一个任务提示另一个任务导致上下文切换,则设置此标志。设置标志告诉处理器在执行RET时执行上下文切换。
80386 标志
‘386 需要额外的标志来支持处理器中设计的额外功能。
RF简历标志。
`386 添加了调试寄存器,它可以在各种硬件访问上调用调试器,如读,写或执行某个存储位置。但是,当调试处理程序返回执行指令时*,访问将立即重新调用调试处理程序!* 或者至少它不会用于 Resume Flag,它会在进入调试处理程序时自动设置,并在每条指令后自动清除。如果设置了 Resume Flag,则不会调用 Debug 处理程序。VM虚拟 8086 标志。
为了支持较旧的 16 位代码以及较新的 32 位代码,80386 可以在“虚拟 8086”模式下运行 16 位任务,借助 Virtual 8086 执行程序。VM标志表明此任务是虚拟 8086 任务。
80486 标志
随着英特尔架构的改进,它通过缓存和超标量执行等技术得到了更快的发展。这必须通过做出假设来优化对系统的访问。为了控制这些假设,需要更多的标志:
AC对齐检查标志 x86 架构总是可以在任何字节边界上访问多字节内存值,这与一些需要它们进行大小对齐的架构(4 字节值需要在 4 字节边界上)不同。但是,这样做的效率较低,因为访问未对齐数据需要多次内存访问。如果设置了AC标志,那么未对齐的访问将引发异常而不是执行代码。这样,在使用AC设置开发期间可以改进代码,但是关闭生产代码。
奔腾标志
Pentium 为虚拟化增加了更多支持,并支持 CPUID 指令:
VIF虚拟中断标志。
这是此任务的IF的虚拟副本 - 此任务是否要禁用中断,而不会实际影响全局中断。VIP虚拟中断挂起标志。
这表明VIF实际上阻止了一个中断,所以当 Task 执行一个STI时,可以为它提出一个虚拟中断。IDCPUID允许的标志。
是否允许此任务执行CPUID指令。虚拟监视器可以禁止它,并且如果它执行指令则撒谎到请求任务。