学习:标志寄存器
前言:跟着shark恒老师一步一步来学习的,毕竟自己完全是0基础,就不直接追求原理了,自己能先记录就好,如果能理解其中的原理那更好
OF标志寄存器(溢出标志位):为1的时候为溢出,带符号数的运算结果超出有限字长的表示范围的标志
我直接修改当前的EAX寄存器的十六进制为0x7FFFFFFFF,因为这个是有符号位int32中最大的数,如果是0x80000000,那么符号位为0,那么就为负数,如果是负数的话肯定是正数小
再把当前的汇编指令修改为add eax,0x1
把0x1十六进制的数给eax数据寄存器(相当于0x7FFFFFFF + 0x1 7进一 为8 就是0x80000000那么就为-2147483648 唯一改变的就是前面的符号位),然后我们单步步过,
发现0标志寄存器就为1了,那么就为溢出
CF标志寄存器(进位状态标志位):当(比如eax)寄存器中的十六进制值超过了无符号位最大数时候的十六进制值时则为1
然后我们再把当前地址的汇编指令修改为add eax,0x1
,再进行单步步过,发现C标志寄存器中的值为1
以上的两个可以理解为 一个判断有符号位的溢出 一个判断无符号位的溢出
PF标志寄存器(奇偶标志位):如数据寄存器eax中的十六进制转换为二进制数,其中1的个数,如果1的个数为偶数的话 那么P为1 如果1的个数为奇数的话 那么P为0
设置当前eax的寄存器位00000000,然后把当前地址的汇编指令修改为add eax,0x1
,然后单步步过,然后P标识符为0
那么我们继续设置EIP为当前进行单步步过,同样的2的时候也为0
那么再累加一次,此时的寄存器存储的十六进制就为00000003,那么P标识符就为1了
原因是3的二进制为00000011,那么1的个数为偶数,也就是P为1
需要注意的是P标志寄存器,关注的奇偶是在最低有效字节,0x12345678,那么只关注0x78中的1的奇偶数
ZF标志寄存器(零标志位):当计算结果等于0的时候,那么Z标志寄存器中的值为1,比如eax寄存器中的值为0的时候那么Z标志寄存器就为1
这里需要提一下:汇编指令的时候比如add eax,0x1
我们还可以写成add eax,1H
,add eax,1
我们把当前汇编指令修改为add eax,0x1
,然后EAX寄存器中的值修改为FFFFFFFF(有符号位的话就是为-1,存储在内存的值是补码,我们通过补码转原码(正常的原码转补码:符号位不变,数值位按位取反,末尾加1),那么倒着来就是先转成二进制1111 1111 1111 1111 1111 1111 1111 1111 然后-1,则为1111 1111 1111 1111 1111 1111 1111 11110,然后符号为不变其他位取反1000 0000 0000 0000 0000 0000 0000 0001,结果则为-1,因为第一位是符号位
加载程序,默认Z寄存器的值为1,同样的我们也发现了EAX中的值是为0的
把当前汇编指令修改为add eax,0x1
,然后EAX寄存器中的值修改为FFFFFFFE,那么值为-2,然后单步步过,第一次发现Z为0 EAX值为FFFFFFFF
再走一遍过程重新设定EIP然后单步步过,发现Z为1 EAX值为00000000
SF标志寄存器(符号标志位):当寄存器中的值为负数的时候,S则为1
接着上面的,我们发现当前S寄存器中的值为0,我们把当前的EAX重新为FFFFFFFE,设定EIP为第一个地址,然后单步步过,发现S为1,此时的EAX为FFFFFFFF,就为-1
那么我们再次相同的操作设定EIP,然后单步步过,发现S为0,此时的EAX也会00000000,大于负数
DF标志寄存器:使串指令自动递减(从高地址向低地址处理字符串),清除该标志位则使串指令自动递增
串指令有:MOVS,CMPS,SCAS,LODS,STOS
STD和CLD指令分别用于设置和清除DF指令