EFL介绍
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)
32位标志寄存器增加的标志位
1. I/O特权标志IOPL(I/O Privilege Level)
2. 嵌套任务标志NT(Nested Task)
3. 重启动标志RF(Restart Flag)
4. 虚拟8086方式标志VM(Virtual 8086 Mode)
修改EFL的方法
这节只是提供一个思路,而且不同版本的汇编语言可能会略有不同,大家还是以理解为主。
- 思路
先将EFL标志位的数据全部读取出来,然后对某一位进行操作。- 如果要置0,可以声明一个除要修改位其他位全为1的变量,然后与读取的EFL标志位进行与操作
- 如果要置1,可以声明一个除要修改位其他位全为0的变量,然后与读取的EFL标志位进行或操作
再将修改后的EFL标志位存入寄存器。
- 在汇编文件中定义两个对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
- 在源文件中进行调用(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)
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233243.html原文链接:https://javaforall.net