注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

风雨夜归人

专业收集资料,个人爱好!

 
 
 

日志

 
 

逆向_第九课  

2010-05-12 07:28:02|  分类: 逆向 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

条件设置指令的形式是:SETcc r/m8,其中r/m8是表示8位寄存器或单字节内存单元.
条件设置指令根据处理器定义的16种条件cc,测试一些标志位,然后把结果记录到目标操作数中.当条件满足时,目标操作数会被置1,否则置0.这16种条件与条件转移指令jcc中的条件是一样的.
条件设置指令可以用来消除程序中的转移指令.在C语言里,常会见到执行以下功能的语句:
c=(a<B)?C1:C2;
如果允许出现条件分支,编译器会产生如下的代码或者是非常类似的代码:
cmpa,b
moveax,c1

moveax,c2
@@:
如果使用条件设置指令,编译器将会产生不包含条件分支的逻辑判断代码:
xoreax,eax
cmpa,b
setgeal;a>=b,则al置1,否则al置0
deceax
addeax, (c1-c2)
addeax,c2
也可用条件转移传输指令cmov或fcmov去除程序中的转移指令,但是他们仅仅被Pentium Pro以后的处理器支持.实现同样功能的代码入下:
moveax,c2
cmpa,b
cmov1eax,c1
一些编译器优化时,在不改变原逻辑的情况下,使用数学技巧把源代码中的一些逻辑分支转变成算术操作,消除或减少程序中出现的条件转移指令.可以提高CPU的流水线性能
看一段C的代码:
int main()
{
if(FindWindow(NULL,\"计算器\"))
return 1;
else
return 2;
}
用VC编译连接后,其反汇编代码如下:
00401000/$68 30604000 PUSH 4_5_5.00406030; /Title = \"计算器\"
00401005|.6A 00 PUSH 0 ; |Class = 0
00401007|.FF15 9C504000 CALL DWORD PTR DS:[<&USER32.FindWindowA>>;
0040100D|.F7D8NEG EAX
0040100F|.1BC0SBB EAX,EAX
00401011|.24 FC AND AL,0FC
00401013|.83C0 05 ADD EAX,2
00401016\\.C3RETN
编译生成的代码没有一句跳转转移指令,却实现原程序的逻辑.代码首先用neg指令检查eax是否为0,结果存放在CF标志位中.sbb指令将目的操作数减去源操作数,再减去减去借位CF(进位),结果送到目的操作数\"sbb eax,eax\"这句的结果由CF决定,当CF为1时,eax为-1,否则为0,用伪码来表示:
if(eax)
cf=1;
esle
cf=0;
eax=-cf;
接下来两句指令根据eax的值:FFFFFFFh和0来决定最终结果,当eax是FFFFFFFFh的结果是1;当eax是0时,计算结果为2.
00401011|.24 FC AND AL,0FC
00401013|.83C0 05 ADD EAX,2
这类代码比较常见,当知道是条件转移转移指令优化生成的,还原就比较简单了.

  评论这张
 
阅读(289)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017