AI摘要
push 16位寄存器 栈顶+2
push 8位 16位 32位立即数 栈顶+4
push 16位内存数据 栈顶+2
push 32位内存数据 栈顶+4
Pushad
一次性把 8 个 32 位通用寄存器全部压入栈,用来保存现场。
popad
一次性把 8 个 32 位通用寄存器全部弹入栈,用来还原现场。
1.PE
2.下断点
3.WIN32 api
4.什么是函数调用
5.熟悉堆栈-画过堆栈图
一个程序执行之前栈顶存放着执行这个程序的返回地址
6.call jcc
标志寄存器->jcc->程序的走向
CF PF AF ZF SF OF 背 熟记第几位
0 2 4 6 7 11
CF进位标志位
最高位产生了进位或者借位 为1 else 0
EFLAGS 寄存器标志位
00000246 =>001001000110
CF = 0
PF = 1
AF = 0
ZF = 1
SF = 0
OF = 0
PF 奇偶标志位
反映二进制结果中的“1”的个数的奇偶性 如果1是偶数 PF=1 else PF = 0
只看运算结果的「最低有效字节」里,1 的个数是偶数还是奇数。
规则:
- 最低字节中 1 的个数为偶数 → PF = 1
- 最低字节中 1 的个数为奇数 → PF = 0
哪怕是 16 位、32 位、64 位运算,PF 也只关心最后 8 位,高位全部忽略。
会改变标志位的指令
这些指令执行后,ZF、SF、CF、OF、PF、AF 都会被更新:
算术运算
ADD、ADCSUB、SBB、CMPINC、DECNEGMUL、IMULDIV、IDIV
逻辑运算
AND、OR、XOR、NOTTEST
移位 / 循环移位
SHL、SHR、SAL、SARROL、ROR、RCL、RCR
AF辅助进位标志位
在以下情况发生时候为1 否则为0
在进行四字节操作时候,发生低字向高字进位
在进行字操作时候,发生低字节向高字节进位
在进行字节操作时候,发生低4位向高4位进位
ZF反映运算结果是否为0
如果运算结果为0 则ZF为1否则为0
Xor eax,eax
SF符号标志位
符号标志SF用来反映运算结果的符号位 他与运算结果的最高位相同
7F+2 = 81h->10000001
最高位 = 1 → SF=1(表示这个结果作为有符号数是负数)
OF溢出标志位
正数 + 正数,结果跑到负数区 = 溢出
负数 + 负数,结果跑到正数区 = 溢出
正数 + 负数,永远不会有溢出
1000 0000->80
1100 0000->C0 ->-40h
符号位有进位 1
最高有效数值位向符号位产生的进位 0
1 xor 0 =/=1 of = 1
homework
无符号数、有符号数都不会溢出
mov al,8
ad al,8
如果是无符号数,那么就看 CF标志位 即原数是否超过数据宽度最大值
如果是有符号数,那么看OF标志位 即原数是否超过数据宽度正数的最大值
无符号数溢出,有符号数不溢出
mov al,0xff
mov al,2
无符号数不溢出,有符号数溢出
mov al,0x7f
add al,2
无符号、有符号都溢出
adc 带进位加法
ADC R/M,R/M/IMM
意思就是如果俩个操作数会产生进位 那么目标操作数 = 源操作数+CF位
SBB 带进位减法
SBB R/M,R/M/IMM
意思就是如果俩个操作数会产生进位 那么目标操作数 = 源操作数-CF位
XCHG 交换俩个寄存器或者内存的值
XCHG R/M,R/M
MOVS 移动数据 内存-内存
byte/WORD/DWORD
MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
MOVS WORD PTR ES: [EDI],BYTE PTR DS: [ESI]
MOVS DWORD PTR ES:[EDI],BYTE PTR DS: [ESI]
movsb
把 DS:SI 指向的 1 个字节数据,传送到 ES:DI 指向的内存单元,然后根据方向标志位 DF 自动修改 SI 和 DI 的值。
执行流程(固定逻辑)
- 取源字节:
(ES:DI) = (DS:SI)也就是根据命令要求长度将esi赋值给edi 修改地址指针:
- 若
DF=0(正向传送,默认):SI += 1,DI += 1根据宽度加1 2 4 - 若
DF=1(反向传送):SI -= 1,DI -= 1根据宽度加1 2 4
- 若
从低地址 → 高地址SI+1,DI+1正向传送
从高地址 → 低地址SI-1,DI-1反向传送
STOS指令 将AL/AX/EAX的值存储到[EDI]指定的内存单元
STOS BYTE PTR ES:[EDI]
简写为STOSB AL
STOS WORD PTR ES: [EDI]
简写为STOSW AX
STOS DWORD PTR ES:[EDI]
简写为STOSD EAX
修改地址指针 DI:
- **DF=0(CLD,正向)** → `DI += 数据长度`(+1 / +2 / +4)
- **DF=1(STD,反向)** → `DI -= 数据长度`(-1 / -2 / -4)
REP指令 按计数寄存器(ecx)中指定的次数重复执行字符串指令
MOV RCX,10
rep movsd //根据ecx的值决定movsd的执行次数
rep stosd //根据ecx的值决定stosd的执行次数
- 只影响CF位 需注意OF PF AF位
- 只影响PF位(二进制1为偶数个)
- 只影响AF位
- .只影响SF位
- 只影响OF位
我试了很多的算数指令 都会有类似SF改变的情况 溢出有俩个条件 ① 正数+正数=负数 ② 负数+负数=正数 ① 会SF = 1 ②CF= 1 - movs分别移动五个字节 五个字 五个双字
**字和双字 - stos
- 用rep指令重写7 8题










