首页
社区
课程
招聘
对3取余汇编代码,不是太理解~~~
发表于: 2011-4-6 21:04 7538

对3取余汇编代码,不是太理解~~~

2011-4-6 21:04
7538
00401017  |.  8BC8          MOV ECX,EAX                              ;  eax为输入的数字,假设为100
00401019  |.  B8 56555555   MOV EAX,55555556
0040101E  |.  F7E9          IMUL ECX
00401020  |.  8BC2          MOV EAX,EDX
00401022  |.  C1E8 1F       SHR EAX,1F
00401025  |.  03C2          ADD EAX,EDX
00401027  |.  8D0440        LEA EAX,DWORD PTR DS:[EAX+EAX*2]
0040102A  |.  2BC8          SUB ECX,EAX                               ;ecx为取余结果...

我对这个取余过程不是很理解...谁能帮忙分析下原理?vs2008-release

大概应该是:100-3*33... 但是对33如何来的 不是很理解~~~

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
2
这段代码 好熟悉。。是哪个crack的  吗。。好熟悉
好像是验证输入框 的长度。。。如果符合 才能进行下一轮验证。。。
是吗?
越想越熟悉,记不起来了
2011-4-6 21:16
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不是,我自己在学习反汇编,就想看看对3取余的代码是怎么样的...vs2008-release版本的...呵呵
2011-4-6 21:23
0
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
4
提醒我了 估计那道cm题也是这样的做法,  最终结果确实是你说的那样。。
我怎么当时没看出来呢,最后手动出来的。。。
我觉得 你用计算器 直接照着算一遍,由于他做了优化,以后碰到了知道就行了。。
2011-4-6 21:25
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
嗯,手工肯定可以出来,我就想知道这样优化的原理?有什么好处,呵呵~~~
2011-4-6 21:44
0
雪    币: 4443
活跃值: (2066)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
这个怎么理解啊 ~~我只能理解成这样额
MOV ECX,EAX                          ;100送ecx
   MOV EAX,55555556                  55555556送eax
   IMUL ECX                          ;带符号乘
   MOV EAX,EDX                       ;edx送eax
   SHR EAX,1F                        ;右移31位
   ADD EAX,EDX                       ;eax加edx
   LEA EAX,DWORD PTR DS:[EAX+EAX*2]  ;偏移首地址送EAX
   SUB ECX,EAX                       ;ecx减eax
2011-4-6 21:58
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
http://bbs.pediy.com/showthread.php?t=106975

希望对你有用。。。
2011-4-6 21:59
0
雪    币: 99
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
发重复了。。。。。。。
2011-4-6 23:46
0
雪    币: 99
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这些代码的意思应该是   eax - 3 * eax / 3 .这是求除的问题
简单说一下为什么这样优化
乘法效率要高于除法所以转换成乘法计算
x / o == x   * 1/o == x * 2^n  / (o * 2^n)  == (x * 2^n / o )  / 2^n
等价于  (x * 常数 )>> n这个常数也就称为魔法数 c = 2 ^n / o

00401017  |.  8BC8          MOV ECX,EAX                      ;  eax为输入的数字,假设为100
00401019  |.  B8 56555555   MOV EAX,55555556     //55555556 为魔法数 c
0040101E  |.  F7E9          IMUL ECX                          //x * c, EAX为结果的低位。EDX放的高位4字节
00401020  |.  8BC2          MOV EAX,EDX                 //EDX赋值给EAX相当于(x * c) >> 32
00401022  |.  C1E8 1F       SHR EAX,1F                //向右移动31位相当于取EAX最高位
00401025  |.  03C2          ADD EAX,EDX              //如果为负则加1
00401027  |.  8D0440        LEA EAX,DWORD PTR DS:[EAX+EAX*2]
0040102A  |.  2BC8          SUB ECX,EAX     
常数 c = 2 ^n / o 那么 除数 o = 2^n / c
所以 o == 2^32 / 55555556 约等于 3
这只是正数有符号的除法,还有无符号,负数等情况。
2011-4-6 23:49
1
雪    币: 201
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这里应该是n+1  还有就是2^n / o 这里的除法指令怎么做,这不相当于没优化吗
2011-4-7 00:56
0
雪    币: 236
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
x / o == 100/3 == (100 * 2^31 / 3 )  / 2^31 == 100 *魔法数 >> 31

即魔法数为:2^32 / 3 == 55555556

OK理解了...那可以根据魔法数来算出对多少取余喽,谢谢!
2011-4-7 12:09
0
游客
登录 | 注册 方可回帖
返回
//