当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位,减去1从0要么是65,535还是-1取决于无符号数运算是否使用-但目的地持有0xFFFF两种方式。只有通过解释条件代码,含义才是清楚的。甚至说出是否1减去0x8000:在无符号算术中,仅32,768变为32,767;而在有符号算术中,它-32,768变为32,767-更值得注意的溢出!
表中将条件代码分为三个块:不相关的符号,未签名的和已签名的。后两个块中的命名使用“ Above”和“ Below”表示未签名,使用“ Greater”或“ Less”表示签名。因此JB将是“如果低于则跳转”(无符号),而如果是“如果低于则JL跳转”(有符号)。
上面的条件代码对于解释预定义的概念很有用,但是实际的标志位也可以直接通过以下两条指令获得:
LAHFAH用标志加载寄存器
SAHF将AH寄存器存储到标志中
这些指令仅复制某些标志。整FLAGS/ EFLAGS/RFLAGS寄存器可以保存或在堆栈上恢复:
PUSHF/将POPF 16位推入/弹出FLAGS堆栈
PUSHFD/将POPFD32位推入/弹出EFLAGS堆栈
PUSHFQ/将POPFQ64位推入/弹出RFLAGS堆栈
请注意,中断会[R/E]FLAGS自动保存和恢复当前寄存器。
除上述ALU标志外,该FLAGS寄存器还定义了其他系统状态标志:
IF中断标志。通过全局启用中断
的STI指令进行设置,并通过CLI全局禁用中断的指令进行清除。
DF方向标志。作为指令的一部分,
诸如CMPS和的内存到内存操作MOVS(在内存位置之间进行比较和移动)会自动增加或减少索引寄存器。该DF标志指示发生哪一种:如果通过CLD指令清除,则它们递增;如果与STD指令一起设置,则它们将递减。
TF陷阱标志。这是一个调试标志。设置它会使处理器进入“单步”模式:执行每条指令后,它将调用“单步中断处理程序”,该调试器应由调试器处理。没有说明设置或清除此标志:您需要在内存中操纵该位。
为了支持80286中的新多任务处理功能,英特尔在FLAGS寄存器中添加了额外的标志:
IOPLI / O权限级别。
为了保护多任务代码,某些任务需要访问I / O端口的特权,而另一些则必须停止访问它们。英特尔推出了四级特权等级,其中002个特权最高,112个特权最少。如果IOPL小于当前的特权级别,则任何尝试访问I / O端口或启用或禁用中断的尝试都将导致一般保护错误。
NT嵌套任务标志。
如果一个任务执行了CALL另一个任务而导致上下文切换,则设置此标志。设置标志告诉处理器RET在执行后执行上下文切换。
'386需要额外的标志来支持处理器中设计的额外功能。
RF恢复标志。
386添加了调试寄存器,可以在各种硬件访问(例如读取,写入或执行某个内存位置)上调用调试器。但是,当调试处理程序返回执行指令时,访问将立即重新调用调试处理程序!或至少不是因为Resume Flag,它会在进入调试处理程序时自动设置,并在每条指令后自动清除。如果设置了恢复标志,则不会调用调试处理程序。
VM虚拟8086标志。
为了支持较旧的16位代码以及较新的32位代码,80386可以在Virtual 8086执行程序的帮助下以“虚拟8086”模式运行16位任务。该VM标志指示此任务是虚拟8086任务。
随着英特尔架构的改进,它通过缓存和超标量执行等技术获得了更快的发展。这必须通过进行假设来优化对系统的访问。为了控制这些假设,需要更多标志:
AC对齐检查标志x86体系结构始终可以在任何字节边界上访问多字节内存值,这与某些体系结构要求大小对齐(4字节值必须在4字节边界上)不同。但是,这样做效率较低,因为需要多个内存访问来访问未对齐的数据。如果AC设置了标志,则未对齐的访问将引发异常,而不是执行代码。这样,可以在开发过程中使用ACset改进代码,但对于生产代码则将其关闭。
奔腾增加了对虚拟化的更多支持,以及对CPUID指令的支持:
VIF虚拟中断标志。
这是此任务的虚拟副本IF-无论此任务是否要禁用中断而没有实际影响全局中断。
VIP虚拟中断挂起标志。
这表明中断实际上已被阻止VIF,因此当Task执行此操作时,STI可以为其引发虚拟中断。
ID该CPUID-allowed标志。
是否允许该任务执行CPUID指令。虚拟监视器可能不允许它,并且在执行指令时“欺骗”请求的任务。
本文向大家介绍Intel x86 Assembly& Microarchitecture 将进位标志移入寄存器,包括了Intel x86 Assembly& Microarchitecture 将进位标志移入寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 背景 如果Carry(C)标志保存您要放入寄存器的值,那么天真的方法是执行以下操作: 使用“ sbb” 为了避免跳转,一种更直接的方法是使
本文向大家介绍Intel x86 Assembly& Microarchitecture 调零寄存器,包括了Intel x86 Assembly& Microarchitecture 调零寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 将寄存器归零的明显方法是MOV在0—例如: 请注意,这是一个5字节指令。 如果您愿意破坏标志(MOV从不影响标志),则可以使用XOR指令将寄存器与其自身按位异
本文向大家介绍Intel x86 Assembly& Microarchitecture 8位寄存器,包括了Intel x86 Assembly& Microarchitecture 8位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 前四个16位寄存器可以将其高低字节和低半字节直接作为自己的寄存器进行访问: AH和AL是AX寄存器的上半部分和下半部分。 BH和BL是BX寄存器的上半部分和下
本文向大家介绍Intel x86 Assembly& Microarchitecture 32位寄存器,包括了Intel x86 Assembly& Microarchitecture 32位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 英特尔生产80386时,他们从16位处理器升级到了32位处理器。32位处理意味着两件事:要处理的数据都是32位,而要访问的内存地址是32位。为此,他们仍然
本文向大家介绍Intel x86 Assembly& Microarchitecture 16位寄存器,包括了Intel x86 Assembly& Microarchitecture 16位寄存器的使用技巧和注意事项,需要的朋友参考一下 示例 当英特尔定义最初的8086时,它是一个具有20位地址总线的16位处理器(请参阅下文)。他们定义了8个通用16位寄存器-但为某些指令赋予了它们特定的作用:
本文向大家介绍Intel x86 Assembly& Microarchitecture 测试寄存器为0,包括了Intel x86 Assembly& Microarchitecture 测试寄存器为0的使用技巧和注意事项,需要的朋友参考一下 示例 背景 要弄清寄存器是否为零,天真的方法是这样做: 但是,如果您查看此操作码,则会得到以下信息: 采用 test 检查您得到的操作码: 优点 只有两个字