CPU
提供了 EFLAGS
寄存器来保存一些 进位, 溢出,奇偶校验,等等状态。在 32 位模式下 EFLAGS
是一个 32 位的寄存器,在 64 位模式下 就会变成 RFLGAS
,
高32位被保留,而低32位则与 EFLAGS
寄存器相同。所以 无论是 32位还是 64 位,都只有 32位被使用了。
那 32 位,是不是就代表 有 32 个标志状态?不是,只有部分的位被使用了。
在 《64-ia-32-architectures-software-developer-vol-1-manual》手册 的 Figures 3 -8 章节,有对 EFLAGS 的各个标志做详细的介绍。推荐阅读。
下图 就是出自 intel 的手册。
从类别上看,上面的标志位一共分为 3 大类:
- Status Flags (状态标志)
- DF flag ,全称 direction flag
- System Flags and IOPL Field (系统标志位)
下面就用 汇编代码,演示各个标志位如何被置为1的。
1,CF,Carry Flag,进位标志。代码如下:
int main() {
__asm__("mov $255,%AL");
__asm__("add $1,%AL");
return 0;
}
AL
是 RAX
寄存器的低 8位。使用 GDB 调试,"add $1,%AL"
未执行之前 RAX
跟 EFLAGS
的状态如下图:
从上图可以看到 rax
最后 两位字母 经过 mov
之后,变成了 ff
,敲 ni
,继续执行,如下图:
从上图可以看到,加 1 之后,AL
寄存器从 ff
变成了 00
。因为 AL 是 8位寄存器,最大值是 255,再加 + 1 就会变成 0 。
eflags
也从 0x246 变成了 0x257,可以看到 gdb
贴心的写上了 CF 。表示 CF 置为 1了。
暂时分析完毕,其他标志位的讲解,后续补充。
相关阅读:
- 《64-ia-32-architectures-software-developer-vol-1-manual》
- 《汇编语言 基于X86处理器》第二章,第 2.2.2 小节
由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1,QQ:2338195090。