标志注册
当 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
寄存器添加了额外的标志:
IOPL
I / O 权限级别。
为了保护多任务代码,某些任务需要访问 I / O 端口的权限,而其他任务必须停止访问它们。英特尔推出了四级权限级别,其中00
2 享有最高权限,而11
2 则最少。如果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
时,可以为它提出一个虚拟中断。ID
CPUID
允许的标志。
是否允许此任务执行CPUID
指令。虚拟监视器可以禁止它,并且如果它执行指令则撒谎到请求任务。