32位标志寄存器中的标志位/域可以分成3组:状态标志位,控制标志位,以及系统标志位。下图定义了这些标志位以及对应的比特位编号。在处理器刚刚初始化之后(通过激活RESET引脚或者INIT引脚),EFLAGS寄存器的值被设定为0000-0002H。比特位1,3,5,15,以及22~31都是Intel的保留位。软件不要使用或依赖这些比特位的状态,否则将失去跨处理器兼容性。
某些标志位可以使用通用指令(以后介绍)直接修改;但是并不存在一条x86指令可以用来直接检查或修改整个寄存器(有变通的办法可以实现这个目的,下面介绍)。
下面的指令可以用来在程序栈或EAX寄存器与标志寄存器之间搬移某些标志位组。
指令 | 描述 |
LAHF | 将标志寄存器(低16位)加载到AH寄存器 |
SAHF | 将AH寄存器的值存储到标志寄存器(低16位) |
PUSHF | 将EFLAGS标志寄存器(低16位)压栈 |
POPF | 从栈中弹出两个字节(16位)到EFLAGS寄存器的低16位 |
PUSHFD | 将EFLAGS标志寄存器(32位)压栈 |
POPFD | 从栈中弹出4个字节(32位)到EFLAGS寄存器 |
注:其他的可以修改标志位的指令还包括:STC/CLC/CMC(进位标志位),CLD/STD(方向标志),和STI/CLI(中断允许标志)。
当EFLAG标志寄存器的内容被传输到程序栈或者EAX寄存器之后,可以是处理器提供的比特位操作指令(BT/BTS/BTR/BTC)来检查并修改某些标志位。
描述 | |
BT | 测试比特位(即指定的比特位送入标志寄存器的CF标志位) |
BTS | 测试并设置比特位(指定的比特位先送入CF标志位,然后该位设置为1) |
BTR | 测试并清除比特位(指定的比特位先送入CF标志位,然后该位设置为0) |
BTC | 测试并求补比特位(指定的比特位先送入CF标志位,然后该位取反) |
当挂起某个任务时(利用处理器的多任务机制),处理器自动的将EFLAGS标志寄存器保存到被挂起任务的任务状态段TSS中。当切换到新任务时,处理器从新任务的TSS中加载对应的EFLAGS标志寄存器。参看下图的32位TSS结构,EFLAGS标志寄存器起自第36字节(黄色标出)。
当调用中断处理器程序或异常处理程序时,处理器自动的将EFLAGS标志寄存器的内容保存在栈上。当中断/异常处理器程序时通过任务切换执行时,EFLAGS的内容保存在被挂起的任务的TSS中(如上段所述)。
随着IA-32架构的演化,EFLAGS寄存器中的标志位也随之增加,但是已有的标志位的位置与功能都保持与前代处理器一致。这样,访问或修改这些标志位的程序才可以正确的运行在后代处理器上(注:x86架构的重要成功因素之一就是向前兼容,最大的保护了厂商在软件上的投资)。