首页
社区
课程
招聘
求高手指点 TEST指令的用法以及在下边这个例子里判断的是什么,为什么做这样的判断
发表于: 2014-7-20 21:04 6451

求高手指点 TEST指令的用法以及在下边这个例子里判断的是什么,为什么做这样的判断

2014-7-20 21:04
6451
源代码
int _tmain(int argc, _TCHAR* argv[])

   char *s1 = "s123456" , *s2 = "s2abcdef2222" ;
    strcmp(s1 , s2);
    return 0;

OD下的汇编代码
7855B580 >  8B5424 04       MOV EDX,DWORD PTR SS:[ESP+4]   
7855B584    8B4C24 08       MOV ECX,DWORD PTR SS:[ESP+8]
7855B588    F7C2 03000000   TEST EDX,3
7855B58E    75 3C           JNZ SHORT MSVCR90.7855B5CC
7855B590    8B02            MOV EAX,DWORD PTR DS:[EDX]
7855B592    3A01            CMP AL,BYTE PTR DS:[ECX]
7855B594    75 2E           JNZ SHORT MSVCR90.7855B5C4
7855B596    0AC0            OR AL,AL
7855B598    74 26           JE SHORT MSVCR90.7855B5C0
7855B59A    3A61 01         CMP AH,BYTE PTR DS:[ECX+1]
7855B59D    75 25           JNZ SHORT MSVCR90.7855B5C4
7855B59F    0AE4            OR AH,AH
7855B5A1    74 1D           JE SHORT MSVCR90.7855B5C0
7855B5A3    C1E8 10         SHR EAX,10
7855B5A6    3A41 02         CMP AL,BYTE PTR DS:[ECX+2]
7855B5A9    75 19           JNZ SHORT MSVCR90.7855B5C4
7855B5AB    0AC0            OR AL,AL
7855B5AD    74 11           JE SHORT MSVCR90.7855B5C0
7855B5AF    3A61 03         CMP AH,BYTE PTR DS:[ECX+3]
7855B5B2    75 10           JNZ SHORT MSVCR90.7855B5C4
7855B5B4    83C1 04         ADD ECX,4
7855B5B7    83C2 04         ADD EDX,4
7855B5BA    0AE4            OR AH,AH
7855B5BC  ^ 75 D2           JNZ SHORT MSVCR90.7855B590
7855B5BE    8BFF            MOV EDI,EDI
7855B5C0    33C0            XOR EAX,EAX
7855B5C2    C3              RETN
用OD查看的汇编代码 TEST EDX,3这里我搞不明白是怎样判断跳转的目的是什么 求高人指点 为什么用这句  为什么是3   后面还有一句TEST EDX,1  不知道这么使用是什么目的 下面跟着跳转语句 应该是判断指令  但是要判断的是什么  为什么这么做我是搞不懂了 憋了好几天了  求高人指点啊 百度上只是说用这指令改变标志位  实现跳转 **** 但是在这里为什么这么做  是个什么样的思路呢****????
谢谢大家的指点 但是我最想知道的是在这段代码的汇编代码中  在这个位置用这句汇编想要实现的思路是什么  后面还有个TEST  EDX,1  难不成是仅仅就是改变标志位么  目的不是判断  跳转么
既然是判断跳转  为的是判断什么呢  这才是我最困惑的地方
另外  如果是仅仅是想改变标志位  为什么和0x3  0x1 做与运算  为什么不是别的数字呢  期望大家能给我详细的指点  感激不尽

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 1372
活跃值: (5343)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
2
TEST 用法和 AND 一样,只是不改变操作数的值。然后改变标志位
2014-7-20 21:14
0
雪    币: 207
活跃值: (39)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
AND指令~
2014-7-20 21:14
0
雪    币: 135
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
test一般是用来做判断,and一般用来计算出变量里的新值
2014-7-20 22:27
0
雪    币: 68
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
7855B588    F7C2 03000000   TEST EDX,3
7855B58E    75 3C           JNZ SHORT MSVCR90.7855B5CC
这里TEST EDX,3
把edx和0x3作与运算
  如果edx跟0x3相等的话,标志寄存器的Z标志位会被设置为1
  如果edx跟0x3不相等的话,标志寄存器的Z标志位会被设置为0
如果Z标志位被设置为1(edx等于0x3),JNZ跳转不会实现
如果Z标志位被设置为0(edx不等于0x3),JNZ跳转会实现
2014-7-20 23:08
0
雪    币: 68
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
test和and的区别是
test会改变标志位,然后jnz,jz,cmovnz这样的指令会根据标志位选择性执行代码/移动数据
and不改变标志位,只作算术的 与运算
2014-7-20 23:10
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
TEST EDX,3在这里是检查内存地址是否为4的倍数,32位系统cpu分配的内存地址都是4的倍数的;
同理TEST EDX,1是针对16位系统的情况,检查地址是否为2的倍数。
这里就是这个知识点,网上很多资料,你可以自己搜索一下。
2014-7-22 11:54
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
没太看懂。。请问为什么test edx 3 是在检查内存地址是否为4的倍数? edx中存放的是地址吗? 能再详细解释下吗 谢谢
2014-7-22 14:37
0
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
作者贴出的汇编代码只是部分而已,你就看那些代码当然难理解EDX是地址值了,你要跟着作者做一遍就知道了,作者的问题就是“数据对齐”这个知识点,百度一下吧。
2014-7-22 22:31
0
雪    币: 1121
活跃值: (752)
能力值: ( LV5,RANK:66 )
在线值:
发帖
回帖
粉丝
10
这个是MSVCR90模块,就容易理解段代码了。因为现在的编译器优化的比较厉害,不会出现这种代码。MSVCR90这样的模块,很多如strcmp,strcpy等函数,为了实现极致效率,很多代码都是汇编层面精益求精改进的。
这个strcmp的思路就是4个字节4个字节的比,这样效率高一些。最后不够的4字节的,就2个字节比,再不够的,就1个字节比。所以就有了test edx 3,test edx 1。至于为啥要比地址而不是比长度,这个还不清楚。
2014-7-23 14:35
0
雪    币: 940
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这个strcmp的思路就是4个字节4个字节的比,这样效率高一些。最后不够的4字节的,就2个字节比,再不够的,就1个字节比。所以就有了test edx 3,test edx 1。至于为啥要比地址而不是比长度,这个还不清楚。

再等等吧  现在好像是思路越来越清晰了  希望高手们能有更详尽细致的解答  谢谢大家的解答  我一直再看  总是觉得不够详尽  透彻  所以还在等待
2014-7-23 18:09
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
按照我的理解就是B,W,L的地址区别,对某些不是4的倍数 不是2的倍数的地址做单独操作,我遇到一些cpu的指令是不能对非4倍数的地址做L的读写操作的,非2的倍数也是不能做w操作

test edx 3 为0 则地址肯定是4的倍数,可以做L读写操作

test edx 3 不为0,则继续test edx 1,继续判断地址是否2的倍数在分别操作

x64 x86上没有这种限制,估计还有其他意思,比如优化加速什么的.....

以上个人意见,仅供参考
2014-7-26 01:27
0
雪    币: 474
活跃值: (1242)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
关注中 看看有没有详细的解释
2014-7-26 14:32
0
雪    币: 940
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
test edx 3 为0 则地址肯定是4的倍数,可以做L读写操作

test edx 3 不为0,则继续test edx 1,继续判断地址是否2的倍数在分别操作

我的个人基础不大好  能不能请高手讲的再细致些  很多人都说是通过与运算实现的  能不能从二进制的角度仔细说下怎么实现对地址是4的倍数和2的倍数呢   谢谢
2014-7-26 22:51
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
先看看4的倍数的地址

0 4 8 c  这几个换成2进制最低2bit肯定是0了,所以test edx 3 就是为了检测最低2bit位  为0的话地址位数当然就是4的倍速地址,地址末位当然就是前面那几个了

在看看2的倍数的地址

0 2 4 6 8 a c e  这几个换成2进制最低1bit肯定是0了,所以test edx 1为0的话地址位数当然就是2的倍数地址,地址末位当然就是前面那几个了

因为程序是先test edx 3 ,为0就是4倍数地址,不为0的话地址也许是2倍数也许是单数地址,所以这时候再来个
test edx 1 (其实 test edx 2 也可以),结果为0当然就是2倍数,不为0就当然是单数了

这个熟悉二进制的话应该很简单的~

我不是高手,也是来学习的,有说错的地方请指正
2014-7-27 09:28
1
雪    币: 940
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
多谢指教  无限感激   谢谢大家的回复   让我真正的懂得了一段代码  有人指点的学习真的很开心
2014-7-27 10:33
0
雪    币: 940
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
大家回答的都很好  这也让我很无奈   为了感谢大家的回复   我把分拆开给了   至于多少请大家不要介意  再次感谢大家的指点
2014-7-27 10:44
0
游客
登录 | 注册 方可回帖
返回
//