吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9684|回复: 34
收起左侧

[调试逆向] 逆向基础笔记五 标志寄存器

  [复制链接]
lyl610abc 发表于 2021-2-28 15:32
本帖最后由 lyl610abc 于 2021-3-12 16:35 编辑

继续更新个人的学习笔记,
其它笔记传送门
逆向基础笔记一 进制篇
逆向基础笔记二 数据宽度和逻辑运算
逆向基础笔记三 通用寄存器和内存读写
逆向基础笔记四 堆栈篇
逆向基础笔记六 汇编跳转和比较指令
逆向基础笔记七 堆栈图(重点)
逆向基础笔记八 反汇编分析C语言
逆向基础笔记九 C语言内联汇编和调用协定
逆向基础笔记十 汇编寻找C程序入口
逆向基础笔记十一 汇编C语言基本类型
逆向基础笔记十二 汇编 全局和局部 变量
逆向基础笔记十三 汇编C语言类型转换
逆向基础笔记十四 汇编嵌套if else
逆向基础笔记十五 汇编比较三种循环
逆向基础笔记十六 汇编一维数组
逆向基础笔记十七 汇编二维数组 位移 乘法
逆向基础笔记十八 汇编 结构体和内存对齐
逆向基础笔记十九 汇编switch比较if else
逆向基础笔记二十 汇编 指针(一)
逆向基础笔记二十一 汇编 指针(二)
逆向基础笔记二十二 汇编 指针(三)
逆向基础笔记二十三 汇编 指针(四)
逆向基础笔记二十四 汇编 指针(五) 系列完结

EFLAGS寄存器

image-20210227214452385

进位标志CF(Carry Flag)

如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0

例子:

MOV AL,0xFF

ADD AL,1

0x80+0x40

加黑的为最高位

0x80:0 1000 0000

0x40:0 0100 0000

image-20210228144357633

结果为1100 0000 最高位并没有发生变化,于是CF位为0

0x80-0x40

image-20210228144309961

注意这里借位的位是1000 0000中的加黑部分

而非0 1000 0000这里的最高位

结果为0100 0000 最高位并没有发生变化,于是CF位为0

0x80-0x81

0x80:1000 0000

0x81:1000 0001

image-20210228144551161

结果为1111 1111= -1,最高位被借位,于是CF位为1

奇偶标志PF(Parity  Flag)

奇偶标志PF用于反映运算结果中最低有效字节中“1”的个数的奇偶性

如果“1”的个数为偶数,则PF的值为1,否则其值为0。

指令 指令执行后AL的结果 PF
MOV AL,3 0011 1
ADD AL,3 0110 1
ADD AL,2 1000 0

例:

MOV AX,803
ADD AX,1

0x803: 0000 1000 0000 0011

执行结果

0x804: 0000 1000 0000 0100        总共2个1 ,PF应为1,但实际运行结果PF为0

因为PF是根据最低有效字节来看,即804后面04的这部分

04: 0000 0100 总共1个1,所以PF为0

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

在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:

  • 在字操作时,发生低字节向高字节进位或借位时
  • 在字节操作时,发生低4位向高4位进位或借位时

AF与数据宽度相关

32位时 FFFF F FFF

16位时 FF F F

8位时 F F

加黑的字体为AF标志位判断的位置,如果该位置要向前进位则AF为1,否则为0,和CF相似,不过判断的位置不同        

32位例:

MOV EAX,55EEFFFF

ADD EAX,2

16位例:

MOV AX,5EFE

ADD AX,2

8位例:

MOV AL,4E

ADD AL,2

零标志ZF(Zero  Flag)

零标志ZF用来反映运算结果是否为0

如果运算结果为0,则其值为1,否则其值为0

作用:在判断运算结果是否为0时,可使用此标志位

例子:

XOR EAX,EAX

通过xor将eax清零,会改变zf标志位为1

MOV EAX,0

通过MOV将EAX赋值为0,非运算,不改变zf标志位

符号标志SF(Sign  Flag)

符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同

例子:

MOV AL,7F
ADD AL,2

溢出标志OF(Overflow  Flag)

溢出标志OF用于反映有符号数加减运算所得结果是否溢出

注意与CF区分!!!

最高位进位与溢出的区别:

进位标志表示无符号数运算结果是否超出范围.

溢出标志表示有符号数运算结果是否超出范围.

溢出主要是给有符号运算使用的,在有符号的运算中,有如下的规律:

  • 正 + 正 = 正  如果结果是负数,则说明有溢出
  • 负 + 负 = 负  如果结果是正数,则说明有溢出
  • 正 + 负 永远都不会有溢出

无符号、有符号都不溢出例

MOV AL,8
ADD AL,8

AL的数据宽度为8,即

无符号数范围为0~FF即0~255

8+8=16在0~255内 不溢出

有符号数的范围为

正数:0~7F           即0~127

负数:80~FF         即 -128~0

8+8=16 在0~127内 两正数相加结果仍为正数,不溢出

无符号溢出、有符号不溢出例

MOV AL,0FF
ADD AL,2

无符号数时

FF+2=255+2=257        在0~255外,溢出

有符号数时

FF+2=-1+2=1

正 + 负 永远都不会有溢出

无符号不溢出、有符号溢出例

MOV AL,7F
ADD AL,2

无符号数时

7F+2=127+2=129        在0~255内 不溢出

有符号数时

7F+2=0x81在80~FF (负数范围)内,两正数相加结果为负数,溢出

无符号、有符号都溢出

MOV AL,0FE
ADD AL,80

无符号数时

FE+2=254+2=256=0x100        在0~255外 溢出

有符号数时

FE+2=0x100在0~FF外,溢出

CPU如何计算OF位

首先引入两个概念:

  • 符号位有进位
  • 最高有效数值位向符号位产生的进位

对于一个有符号数:如0x80和0xC0

符号位有进位

0x80:1 000 0000

0xC0:1 100 0000

最高有效数值位向符号位产生的进位

0x80:1 0 00 0000

0xC0:1 1 00 0000

接下来看一组汇编指令

MOV AL,80
ADD AL,0C0

就是运算0x80+0xc0

0x80:1  0  00 0000

0xC0:1 1  00 0000

符号位1+1有产生进位,于是符号位有进位为1

最高有效数值位向符号位产生的进位0+1没有产生进位,于是最高有效数值位向符号位产生的进位为0

OF = 符号位有进位 xor 最高有效数值位向符号位产生的进位

OF = 1 xor 0 = 1 所以此时OF=1

方向标志DF(Direction Flag)

DF:方向标志位

DF=1时串操作为减地址方式 DF=0为增地址方式

下面的MOVS指令有说明DF的具体应用

相关汇编指令

符号 含义
r 寄存器
m 内存
imm 立即数
r8 8位通用寄存器
m8 8位内存
imm8 8位立即数

ADC指令:带进位加法

格式:ADC R/M,R/M/IMM  两边不能同时为内存   数据宽度要一样

例:

MOV AL,1
MOV CL,2
手动修改CF为1
ADC AL,CL

计算结果为4,原本1+2=3,但是现在变成了4,注意与ADD的区别就在于进位

SBB指令:带借位减法

格式:SBB R/M,R/M/IMM   两边不能同时为内存 数据宽度要一样

MOV AL,4
MOV CL,2
手动修改CF为1
SBB AL,CL

计算结果为1,原本4-2=2,但是现在变成了1,注意与SUB的区别就在于进位

XCHG指令:交换数据

格式:XCHG R/M,R/M  两边不能同时为内存   数据宽度要一样

XCHG AL,CL
XCHG DWORD PTR DS:[12FFC4],EAX
XCHG BYTE PTR DS:[12FFC4],AL

例:

MOV AL,1
MOV CL,2
XCHG AL,CL

执行前:AL=1 CL=2

执行后:AL=2 CL=1

MOVS指令:移动数据 内存-内存

BYTE/WORD/DWORD

MOVS指令常用于复制字符串

MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]        简写为:MOVSB
MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]        简写为:MOVSW
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]        简写为:MOVSD

例:

MOV EDI,12FFD8
MOV ESI,12FFD0
MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

执行后,EDI内存里的值被修改为ESI内存里的值,且EDI和ESI各加4

为什么各加4?

和DOWRD数据宽度相关,如果为WORD 则各加2

为什么执行完是加而不是减?

由DF(Direction Flag)方向标志位决定,当DF位为1时为减,当DF位为0时,则为加

STOS指令

将Al/AX/EAX的值存储到[EDI]指定的内存单元,和数据宽度相关

STOS BYTE PTR ES:[EDI]                将AL存储到[EDI]
STOS WORD PTR ES:[EDI]                将AX存储到[EDI]
STOS DWORD PTR ES:[EDI]                将EAX存储到[EDI]

注意这里使用的是ES: 之前写的都是DS:

当后面为[EDI]时要使用ES: 这和后面要学的段寄存器有关,先记住

存储完数据后EDI地址的变化方向也受DF标志控制,1减0增

REP指令

按计数寄存器 (ECX)  中指定的次数重复执行指令

MOV ECX,10
REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]        也可以写成REP MOVSD

这里的10为十六进制,也就是0x10=16

代码将会重复执行16次,会不会往同一个地方覆盖?

不会,因为每执行一次EDI和ESI都会变化4,变化方向由DF决定

免费评分

参与人数 10吾爱币 +10 热心值 +10 收起 理由
junjia215 + 1 + 1 谢谢@Thanks!
Aspark + 1 + 1 谢谢@Thanks!
南山楠 + 1 + 1 支持一下
erh + 1 + 1 谢谢@Thanks!
status_0 + 1 + 1 我很赞同!
且行且珍惜hx + 1 + 1 谢谢@Thanks!
非凡公子 + 1 + 1 谢谢@Thanks!
bailemenmlbj + 1 + 1 谢谢@Thanks!
ttxs1235 + 1 + 1 我很赞同!
laiyuou + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

bester 发表于 2021-3-1 09:08
方向标志需要补充:   cld指令 清除DF标志位,结果为0 std指令设置DF标志位DF,结果为1,不然根本不知道咋用这个标志位
erh 发表于 2021-4-20 22:01
bester 发表于 2021-3-1 09:08
方向标志需要补充:   cld指令 清除DF标志位,结果为0 std指令设置DF标志位DF,结果为1,不然根本不知道咋 ...

谢谢补充新知识
Mdr 发表于 2021-2-28 15:37
zxcvbnm139 发表于 2021-2-28 15:43
辛苦了,谢谢。
小和尚666 发表于 2021-2-28 15:54
摩拜大神
tzhv_9w6 发表于 2021-2-28 16:17
基础很重要
hao3han3 发表于 2021-2-28 16:24
啊,终于看到一篇教程了。多谢大大
w5606389 发表于 2021-2-28 17:19

基础很重要
CraTalentzY 发表于 2021-2-28 17:21
🐮🐮
butwatch 发表于 2021-3-1 12:22
看看,非常不错的。。。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-31 00:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表