x86条件置位指令(SETxx)完全指南:从标志位解读到条件判断实战
本文总结了x86汇编中条件置位指令(SETxx)的相关知识点。主要介绍了SETG/SETL/SETGE/SETLE等指令的功能和使用方法,这些指令通常与CMP指令配合使用,根据标志寄存器(PSW)的状态来设置目标操作数的值。文章详细说明了各指令对应的条件判断规则,如SETGE在ZF=1且SF=0或ZF=SF=0时将操作数设为1。同时列举了PSW中CF、ZF、SF、OF等关键标志位的含义,以及如何在
目录
条件分支是程序的灵魂,而在汇编层,这首先体现为根据标志位进行条件置位。 本文为你彻底厘清SETxx指令家族与标志位之间的映射关系,成为你编写高效条件代码的参考手册。
057-setg,setl指令
知识点:
(NOT)按位取反指令
SETG
SETL
一、SETG
==
>
SETG //setg cl //ZF==0 并 SF==0 并 OF==0 时 cl=1;
//> < =
二、SETL
<
SETL // setl cl; SF==1 或者 OF==1 时 cl=1;
设置标志寄存器的DF标志位:
STD => DF=1
CLD => DF=0
取ZF标志位:
SETZ (SETE) 取ZF位值保存
SETNZ (SETNE) 将ZF位值取反后保存
SETE AL ; AL=ZF
058-setge,setle指令
知识点:
SETGE => G:greater, E:euqal
SETLE => L:less, E:equal
一、SETGE指令
指令格式
SETGE 操作数 //操作数可以是 一字节的存储单元,也可是是一字节宽度的寄存器
作用: >=时设定操作数值1 ,否则为0 (一般与cmp指令组合使用),ZF==1 且 SF==0时,或者ZF==SF==0,设置操作数为1
标志位: JGE对标志位的需求 SF=OF 时 操作的值=1
二、SETLE指令
SETLE 操作数 //操作数可以是 一字节的存储单元,也可是是一字节宽度的寄存器
作用: <=时设定操作数值为1 ,否则为0 //一般与cmp指令组合使用
标志位: JLE对标位的需求一样 ZF=1 || SF!=OF 操作数=1
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int a,b;
a=b=1;
int c=a>=b;
return 0;
}
00401000 /$ 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
00401003 |. 83EC 0C SUB ESP,0C //int a,b,c
00401006 |. C745 F8 01000>MOV DWORD PTR SS:[EBP-8],1 //b=1
0040100D |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00401010 |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX //a=b=1
00401013 |. 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
00401016 |. 33D2 XOR EDX,EDX
00401018 |. 3B4D F8 CMP ECX,DWORD PTR SS:[EBP-8]//影响标志位
0040101B |. 0F9DC2 SETGE DL //把标志位的值给DL
0040101E |. 8955 F4 MOV DWORD PTR SS:[EBP-C],EDX
00401021 |. 33C0 XOR EAX,EAX
00401023 |. 8BE5 MOV ESP,EBP
00401025 |. 5D POP EBP
00401026 \. C3 RETN
如何在OD中检测标志位对执行结果有什么影响?
比如 SETGE DL ,受哪些标志位的影响,标志位的值如何影响执行结果的?
方法:在OD中,选中“SETGE DL”,按空格进入“汇编于此处”窗口,多次执行汇编命令,如下:


然后修改标志位的值,再单步调试,看看EDX中的值如何变化
059-条件置位指令汇总setXX
知识点:
标志位 置位相关指令
标志寄存器PSW
标志寄存器PSW(程序状态字寄存器PSW)
标志寄存器PSW是一个16为的寄存器。它反映了CPU运算的状态特征并且存放某些控制标志。8086使用了16位中的9位,包括6个状态标志位和3个控制标志位。

CF(进位标志位):当执行一个加法(减法)运算时,最高位产生进位(或借位)时,CF为1,否则为0。
ZF零标志位:若当前的运算结果为零,则ZF为1,否则为0。
SF符号标志位:该标志位与运算结果的最高位相同。即运算结果为负,则SF为1,否则为0。
OF溢出标志位:若运算结果超出机器能够表示的范围称为溢出,此时OF为1,否则为0。判断是否溢出的方法是:进行二进制运算时,最高位的进位值与次高位的进位值进行异或运算,若运算结果为1则表示溢出OF=1,否则OF=0
PF奇偶标志:当运算结果的最低16位中含1的个数为偶数则PF=1否则PF=0
AF辅助进位标志:一个加法(减法)运算结果的低4位向高4位有进位(或借位)时则AF=1否则AF=0
另外还有三个控制标志位用来控制CPU的操作,可以由程序进行置位和复位。
TF跟踪标志:该标志位为方面程序调试而设置。若TF=1,8086/8088CPU处于单步工作方式,即在每条指令执行结束后,产生中断。
IF中断标志位:该标志位用来控制CPU是否响应可屏蔽中断。若IF=1则允许中断,否则禁止中断。
DF方向标志:该标志位用来控制串处理指令的处理方向。若DF=1则串处理过程中地址自动递减,否则自动递增。
OD里能查看到 除IF标志外的 8个标志位
JMP //014
JE/JZ //= //012 Jump if Equl
JNE/JNZ //不= //013
//带符号数条件转移指令
JL /JNGE //不>= //小于 < //015
JLE/JNG //不> //小于等于<= //016
JG/JNLE //不<= //大于 >//017
JGE/JNL //不< //大于等于>= //017
Jump 跳转/转移
Not 不
Equal 相等
Zero 零
Less 小于
Greater 大于

条件置位指令
通用写法:SETxx reg8/mem8
作用:若条件xx成立,则dest=1,否则,dest=0;
SETxx有很多种命令形式,这里的xx只是一个描述符,具体的参见下面的三个表,其中,E(Equal)表示相等,G(Greater)表示带符号大于,L(Less)表示带符号小于,A(Above)表示无符号大于,B(Below)表示无符号小于。
表一:用于带符号数比较的SETxx指令,这些指令常用在CMP指令之后,以判断带符号数的大小:

表二:用于无符号数比较的SETxx指令,常用在CMP指令之后,用来判断无符号数的大小:

表三:测试单个标志位的SETxx指令:

计算机科学与技术 & 计算机网络技术:双专业课程体系完全导航指南
本系列目录
1、逆向工程基础:Ollydbg(OD)调试器实战与MOV指令寻址方式精讲
2、汇编语言核心概念精讲:从ADD、SUB、MOVSX/MOVZX到LEA与寄存器详解
3、x86汇编条件跳转指令完全解析:从CMP到有/无符号跳转与If实现
4、x86汇编函数调用完全解析:栈帧(EBP/ESP)构建与三种调用约定(cdecl/stdcall/fastcall)对比
5、汇编逆向还原核心:if-else与switch-case结构的识别与C代码重构
6、编译器优化揭秘:对比for循环的汇编实现与INC vs ADD指令的性能抉择
7、x86浮点运算基础:FPU寄存器、FLD/FSTP与FADD/FSUB等指令精讲
8、汇编位移指令全解与逆向实战:从SHR/SHL到ROL/ROR,逆向分析strcmp
9、汇编位运算指令精讲:掌握AND/OR/XOR/NOT四大核心操作
10、x86汇编字符串处理:SCASB/SCASW指令与REPNE/REPE重复前缀详解
11、汇编实战:用REPNZ SCASB与REPZ CMPSB从零实现strcmpA/W
12、x86汇编批量操作指令:LOOP循环控制与STOS/LODS串操作详解
更多推荐



所有评论(0)