能力值:
( LV13,RANK:260 )
|
-
-
2 楼
这段代码 好熟悉。。是哪个crack的 吗。。好熟悉
好像是验证输入框 的长度。。。如果符合 才能进行下一轮验证。。。
是吗?
越想越熟悉,记不起来了
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
不是,我自己在学习反汇编,就想看看对3取余的代码是怎么样的...vs2008-release版本的...呵呵
|
能力值:
( LV13,RANK:260 )
|
-
-
4 楼
提醒我了 估计那道cm题也是这样的做法, 最终结果确实是你说的那样。。
我怎么当时没看出来呢,最后手动出来的。。。
我觉得 你用计算器 直接照着算一遍,由于他做了优化,以后碰到了知道就行了。。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
嗯,手工肯定可以出来,我就想知道这样优化的原理?有什么好处,呵呵~~~
|
能力值:
( 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
|
能力值:
( LV9,RANK:610 )
|
-
-
7 楼
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
发重复了。。。。。。。
|
能力值:
( 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
这只是正数有符号的除法,还有无符号,负数等情况。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
这里应该是n+1 还有就是2^n / o 这里的除法指令怎么做,这不相当于没优化吗
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
x / o == 100/3 == (100 * 2^31 / 3 ) / 2^31 == 100 *魔法数 >> 31
即魔法数为:2^32 / 3 == 55555556
OK理解了...那可以根据魔法数来算出对多少取余喽,谢谢!
|
|
|