天天看点

标志寄存器 EFLEFL介绍原文链接

EFL介绍

标志寄存器 EFLEFL介绍原文链接

EFL的所有标志全称如上图所示,前8位(0~7)因为用不到,所以不作介绍,想看的可以点击原文链接。

状态控制位

1. 追踪标志位TF(Trap Flag)

当追踪标志TF被置为1时,CPU进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。

指令系统中没有专门的指令来改变标志位TF的值,但可直接通过文末介绍的方法来进行修改。

2. 中断允许标志位IF(Interrupt-enable Flag)

中断允许标志IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。

但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下:

  • 当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求;
  • 当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。

CPU的指令系统中有专门的指令来改变标志位IF的值。

3. 方向标志DF(Direction Flag)

方向标志DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。

在微机的指令系统中,还提供了专门的指令来改变标志位DF的值。

32位标志寄存器增加的标志位

1. I/O特权标志IOPL(I/O Privilege Level)

I/O特权标志用两位二进制位来表示,也称为I/O特权级字段。

该字段指定了要求执行I/O指令的特权级。

如果当前的特权级别在数值上小于等于IOPL的值,那么,该I/O指令可执行,否则将发生一个保护异常。

2. 嵌套任务标志NT(Nested Task)

嵌套任务标志NT用来控制中断返回指令IRET的执行。

具体规定如下:

(1)、当NT=0,用堆栈中保存的值恢复EFLAGS、CS和EIP,执行常规的中断返回操作;

(2)、当NT=1,通过任务转换实现中断返回。

3. 重启动标志RF(Restart Flag)

重启动标志RF用来控制是否接受调试故障。规定:RF=0时,表示“接受”调试故障,否则拒绝之。在成功执行完一条指令后,处理机把RF置为0,当接受到一个非调试故障时,处理机就把它置为1。

4. 虚拟8086方式标志VM(Virtual 8086 Mode)

如果该标志的值为1,则表示处理机处于虚拟的8086方式下的工作状态,否则,处理机处于一般保护方式下的工作状态。

修改EFL的方法

这节只是提供一个思路,而且不同版本的汇编语言可能会略有不同,大家还是以理解为主。

  1. 思路

    先将EFL标志位的数据全部读取出来,然后对某一位进行操作。

    • 如果要置0,可以声明一个除要修改位其他位全为1的变量,然后与读取的EFL标志位进行与操作
    • 如果要置1,可以声明一个除要修改位其他位全为0的变量,然后与读取的EFL标志位进行或操作
    再将修改后的EFL标志位存入寄存器。
  2. 在汇编文件中定义两个对EFL寄存器进行操作的函数
    _read_elfags:		; int read_elfags(void);
    		PUSHFD
    		POP		EAX
    		RET
               
    _save_elfags:		; void save_elfags(int elfags);
    		MOV		EAX, [ESP + 4]
    		PUSH	EAX
    		POPFD	
    		RET
               
  3. 在源文件中进行调用(C版本)
    /* 声明 */
    #define EFLAGS_AC_BIT		0X00040000 /*  0000 0000 0000 ‭0100 0000 0000 0000 0000‬ */
    int read_elfags(void);
    void save_elfags(int elfags);
    
    /* 调用 */
    int elfags = read_elfags();
    elfags |= EFLAGS_AC_BIT;
    store_elfags(eflags);
               

原文链接

标志寄存器(EFL)

继续阅读