第十六课_标志寄存器

前言

感觉好长一段时间没写文章了,希望写文章的水平不要退步得太快。今天讲标志寄存器(EFLAGS)。当然只挑几个位来讲。这标志寄存器挺重要,关系到程序怎么跳转,也是学习后面JCC的基础,搞懂这个,对理解C语言中的if等判断语句也有帮助。

今天介绍的标志寄存器有32位,每一位都有它具体的含义,在网上个很全的解析图。

第十六课_标志寄存器

本id针对今天讲的,稍微做了些简化。凑合着看吧,注意蓝色部分的东西是固定的。

第十六课_标志寄存器

为了让大家有更深刻的理解,在OD上,标志寄存器在EFL那一行中。

第十六课_标志寄存器

注意:OD上已经把标志寄存器(EFL)中的内容进行了拆分,得到对应的C、P、A、Z、S、T、D、O几个位。大家有空可以试着把EFL中的值转成二进制,看看对应的位的值对不对。

几个标志的介绍

进位标志CF(Carray Flag):

如果运算(这里的运算是指那些逻辑运算、加、减这些,mov指令不是运算。)结果的最高位产生一个进位或借位,则CF的值是1,否则是0。

我们可以在OD上进行测试:为了方便查看测试的结束,可以双击标志寄存器后面的值,就可以修改寄存器中的值。

测试1:0xef + 0x2

mov al,0xef

add al,0x2

因为16进制的ef和2相加,计算过程如下图,可以知道运算后,最高为没有产生进位或借位,所以CF位是0.

第十六课_标志寄存器

在OD上测试:

第十六课_标志寄存器

按F8运行后的结果如下图:

第十六课_标志寄存器

测试2:1 - 2

mov al,0x1

sub al,0x2

计算过程如下图,可以知道运算后,最高位产生结尾,所以CF位是1。

第十六课_标志寄存器

在OD上进行测试:

第十六课_标志寄存器

按F8运行后的结果如下图。

第十六课_标志寄存器

其他的就自己测试了,注意数据宽度,只有数据宽度确定了,最高位才能确定。

2.奇偶标志PF(Parity Flag):

在运算的结果中,最低有效字节(即最低的8位)中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则为0。这个就不进行测试了。比较少用。

3.辅助进位标志AF(Auxiliary Carry Flag):

在发生如下的几种情况时,AF位为1,否则为0。

(1)在字节(8位)操作中,发生低4位向高4位进位或借位。

(2)在字(16位)操作中,发生低字节向高字节进位或借位。

测试1

mov al,0x4E

add al,0x2

运算过程如下图:al是8位寄存器,可以发现红色的E有没有进位或借位,很明显E是向高位进位的,所以运算后AF位是1 。

第十六课_标志寄存器

在OD上的测试如下。

第十六课_标志寄存器

按F8运行后的结果如下:

第十六课_标志寄存器

 

根据上面的测试,可以发现辅助位的判断是根据操作的宽度,主要看宽度位数中间那一位是否向前进位或借位。

4.零标志ZF(Zero Flag)

如果运算的结果是0,则ZF的值为1,否则为0。

测试

XOR eax,eax

两个相同的数异或运算后的结束是0

在OD上的测试如下:

第十六课_标志寄存器

按F8运行后,可以看到eax寄存器中的值为0,ZF位的值为1 。

第十六课_标志寄存器

5.溢出标志OF(Overflow Flag)

有符号数进行加减运算的结束是否溢出。即运算的结果如果超过当前运算位数所能表示的范围,则溢出,OF位的值为1,否则为0。如果没有看过之前本id写的关于数据宽度的文章,建议看看。

测试

mov al,0x1

sub al,0x2

1-2的结果肯定没有超过8位数据所能表示的负数的范围,没有溢出,所以OF位是0.

第十六课_标志寄存器

按F8运行后的结果如下图:

第十六课_标志寄存器

CPU是如何计算OF位的呢?

(1)判断符号位是否有进位,若有进位,则为1,否则为0.

(2)判断最高有效数值位(即符号位的后一位)是不向符号位产生进位,有进位则为1,没有则为0.

(3)最后把(1)(2)得到的结果进行异或运算,运算的结束就是OF的值。

 

就写这么多吧!

写于2020.6.7 23:44