![34d26d1ac13265330c3749953e95c7b7.png](https://i-blog.csdnimg.cn/blog_migrate/83b2a0ea174d4da0843a624d8e052a36.jpeg)
对于段寄存器/标志位寄存器/指令指针寄存器
对于这几个寄存器我们这里简单的介绍一下,在刚接触这几个寄存器的时候,并不用说非常深入的研究这几个寄存器,等积累到一定后,就很好理解了。
段寄存器
首先帖一下各个段寄存器和对应的含义
- CS:Code Segement,代码段寄存器
- SS:Stack Segment,栈段寄存器
- DS:Data Segment,数据段寄存器
- ES:Extra(Data) Segment,数据段寄存器
- FS:Data Segment,数据段寄存器
- GS:Data Segment,数据段寄存器
这里的用法就是不同的段代表了不同区域,最常见的就是数据段取值ds:[]和栈段取值ss:[],如图下OD中的汇编指令就是从数据段ds:[]中取值。这里重点在哪里呢?其实只要知道汇编指令中ds:[]这些是从那个段里取值就行,常见的如ss:[],ds:[]。这里的难点是fs寄存器,它用于SEH、PEB、TEB这些,不过这些都是之后的内容,大家这里知道就行。
![152baf8f7937e91238720290740b0839.png](https://i-blog.csdnimg.cn/blog_migrate/c64de9906a574a092331ee0f756ff738.png)
标志位寄存器
标志位寄存器算是比较难以理解的一个部分了,首先标志位寄存器是4字节大小的寄存器,而它的每个位都包含了不同含义
![57d11b9784237d1e19d59f9e0e6a070e.png](https://i-blog.csdnimg.cn/blog_migrate/31ec7d97c2d85dc2e830631867556272.jpeg)
OD中列出了几个比较总要的标志位如下(逆向工程师偷师一下别人的资料):
- CF:若算术操作产生的结果在最高有效位(most-significant bit)发生进位或借位则将其置1,反之清零。这个标志指示无符号整型运算的溢出状态,这个标志同样在多倍精度运算(multiple-precision arithmetic)中使用。
- PF:如果结果的最低有效字节(least-significant byte)包含偶数个1位则该位置1,否则清零。
- AF:如果算术操作在结果的第3位发生进位或借位则将该标志置1,否则清零。这个标志在BCD(binary-code decimal)算术运算中被使用。
- ZF:若结果为0则将其置1,反之清零。
- SF:该标志被设置为有符号整型的最高有效位。(0指示结果为正,反之则为负)
- TF:将该位设置为1以允许单步调试模式,清零则禁用该模式。
- DF:这个方向标志(位于EFLAGS寄存器的第10位)控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)。设置DF标志使得串指令自动递减(从高地址向低地址方向处理字符串),清除该标志则使得串指令自动递增。STD以及CLD指令分别用于设置以及清除DF标志。
- OF:如果整型结果是较大的正数或较小的负数,并且无法匹配目的操作数时将该位置1,反之清零。这个标志为带符号整型运算指示溢出状态。
看了上面这些可能会有点懵,我们这里主要就说一下ZF、OF和CF这几个标志位,还是来一个实际例子来看看
#include
首先就是最简单的1=1的问题了,cmp指令就是“local.2-0x1”,这个汇编指令并不会改变local.2的值,那这里的运算用来做什么呢?其实就类似于if判断,然后这个判断用什么来标识结果呢?其实就是ZF标志位,ZF是当结果位0时置1,这里“local.2-0x1”运算结果为零,所以ZF置1,然后再结合下面的jnz就是完整的一个判断了。而jnz就是ZF=0时才实现跳转,至于jz/jnz这些跳转,我们这里可以暂时不用管,以后会列举出所有的跳转再慢慢对比。
![8302bc3c6684078da82d6b77f82b2f0f.png](https://i-blog.csdnimg.cn/blog_migrate/4aba51070ff0cc8bf02d9df8d4423e2e.png)
然后就是CF和OF,CF是无符号整型溢出置1,OF是有符号整型溢出置1
![7dbb3218cb468349b285d1bba9f5bdeb.png](https://i-blog.csdnimg.cn/blog_migrate/999c88a9c1e3184a9bccc3733b781e69.jpeg)
![f663f78e29349ea826617beb6f41fe05.png](https://i-blog.csdnimg.cn/blog_migrate/aa97222414176741660576af9f8eae8e.jpeg)
这里就简单的列举了3个例子,还有其他的大家可以自己写代码来测试一下
指令指针寄存器
所谓的指令指针寄存器就是我们用OD时最常见的eip,它指向的就是我们将要运行的汇编指令,而这里我们知道这个就行。下图就是我们运行完了0096DB63处的mov ebp,esp后,eip就指向了0096DB65
![b353017be11d281813210eabe9fd75c0.png](https://i-blog.csdnimg.cn/blog_migrate/6ab6815b0b21b9104b5b66dfbea7743d.jpeg)
参考
<<逆向工程核心原理>>
x86—EFLAGS寄存器详解:https://blog.csdn.net/jn1158359135/article/details/7761011