初学状态寄存器
状态寄存器
解决之前对于标志位半知半解的问题
之前不是讲过cmp和je的组合技吗?但这是怎么实现的呢?理论上,没有存储任何数据,也没有修改任何数据,je是怎么得到条件判断结果的?
我们看起来的代码:
asm
cmp eax,ebx
je xxx
那这个cmp到底干了什么呢?我们只知道cmp做了个减法而已,于是我们的状态寄存器RFLAGS出手了
这个寄存器里面有很多开关,以下是条件码:
- CF(Carry Flag):进位标志,进位时置1,否则置0.注意:Carry标志中存放计算后最右的位
- PF(Parity Flag):奇偶标志.结果操作数中1的个数为偶数时置1,否则置0
- AF(Auxiliary carry Flag):辅助进位标志,记录运算时第3位(半个字节)产生的进位置。有进位时1,否则置0
- ZF(Zero Flag):零标志,运算结果为0时置1,否则置0
- SF(Sign Flag):符号标志,结果为负时置1,否则置0
- OF(Overflow Flag):溢出标志,溢出时为1,否则置0.标明一个溢出了的计算,如:结构和目标不匹配
以下是控制标志位
- DF(Direction Flag):方向标志,在串处理指令中控制信息的方向
- IF(Interrupt Flag):中断标志
- TF(Trap Flag):陷井标志
等等……每个都是1bit的开关,如下图所示:

或者这个图更好看一些?

这些标记出来的标志位十分重要,如果对于逆向开发,这些是需要课在脑子里的,可以不强背,实战中运用熟悉就自然记来了,为了方便描述,仅以8位来描述
这是前辈文章里写的,我真的能刻在脑子里吗(
我们一个个来介绍吧,第一个CF进位标志是在运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0,就是说每次计算应该都会更新
然后就是奇偶标记PF,奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0,这个功能有点神秘,不知道有啥用,就是把数据转二进制来看,记录1的个数,
接着AF,这些感觉都没啥用,所以先讲了:
在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0
- 在字(word)操作时,发生低字节向高字节进位或借位时
- 在字节(byte)操作时,发生低4位向高4位进位或借位时。
不太懂,但是感觉没啥用
零标志ZF(Zero Flag):零标志ZF用来反映运算结果是否为0
如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位
这个就是test用来判断的flag,这就解释了之前strcmp之后的test是如何被下面的条件跳转检测到的
asm
call <JMP.&strcmp>
test eax,eax
jne main.401BDA
test计算后,ZF被置为1,jne获取ZF存储的数,就知道要不要跳转了
符号标志SF(Sign Flag):符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同
Sign Flag仅仅用来反映运算结果最高位是1,还是0,不代表有符号数,无符号数
溢出标志OF(Overflow Flag):溢出标志OF用于反映有符号数加减运算所得结果是否溢出
如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0
这个溢出和进位还是有点区别的:
- 进位标志表示无符号数运算结果是否超出范围
- 溢出标志表示有符号数运算结果是否超出范围
溢出的规律比较神圣,因为正+正=正出现负数就是溢出,反过来负+负=负出现正数就是溢出,正+负永远不会溢出!
所以溢出是根据计算结果来看的,而进位是根据最高位是否进位看的
剩下还有三个,等我要用到再说吧(
评论