除法与模运算的识别-大量除法推导过程
Debug版本总结:
有符号 除 2的幂 和无符号除2的幂作了优化, 其它情况都是 直接运用div,或idiv指令
4: #include "stdafx.h"
5: #include "stdio.h"
6:
7: int main(unsigned int argc, char* argv[])
8: {
00401010 push ebp
00401011 mov ebp,esp
00401013 sub esp,4Ch //预留局部变量空间
00401016 push ebx //保存环境
00401017 push esi //保存环境
00401018 push edi //保存环境
00401019 lea edi,[ebp-4Ch]
0040101C mov ecx,13h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi] //预留空间全部初始化为0xCC
9: int x = 0;
00401028 mov dword ptr [ebp-4],0 //变量初始化为0
10: int y = 0;
0040102F mov dword ptr [ebp-8],0
11: unsigned u = 0;
00401036 mov dword ptr [ebp-0Ch],0
12:
13: scanf("%d %d %u", &x, &y ,&u);
0040103D lea eax,[ebp-0Ch]
00401040 push eax
00401041 lea ecx,[ebp-8]
00401044 push ecx
00401045 lea edx,[ebp-4]
00401048 push edx
00401049 push offset string "%d %d %u" (00425364)
0040104E call scanf (00401740)
00401053 add esp,10h
14:
15: printf("x/y = %d \r\n", x/y); //有符号变量/有符号变量
00401056 mov eax,dword ptr [ebp-4]
00401059 cdq
0040105A idiv eax,dword ptr [ebp-8]
0040105D push eax
0040105E push offset string "x/y = %d \r\n" (00425354)
00401063 call printf (004016c0)
00401068 add esp,8
分析1: 有符号两变量相除,直接运用指令idiv,不存在优化.对于编译器来讲都是未知的值.
16: printf("x/u = %d \r\n", x/u); //有符号变量/无符号变量
0040106B mov eax,dword ptr [ebp-4]
0040106E xor edx,edx
00401070 div eax,dword ptr [ebp-0Ch]
00401073 push eax
00401074 push offset string "x/u = %d \r\n" (00425344)
00401079 call printf (004016c0)
0040107E add esp,8
分析2:有符号分母与无符号分子 混除,直接用无符号div处理.有符号数当无符号处理.同样两个变量对于编译器来讲是未知的值,无法忧化.
17: printf("u/x = %d \r\n", u/x); //无符号变量/有符号变量
00401081 mov eax,dword ptr [ebp-0Ch]
00401084 xor edx,edx
00401086 div eax,dword ptr [ebp-4]
00401089 push eax
0040108A push offset string "u/x = %d \r\n" (00425334)
0040108F call printf (004016c0)
00401094 add esp,8
分析3:有符号分子与无符号分母 混除,直接用无符号div处理.有符号数当无符号处理.同样两个变量对于编译器来讲是未知的值,无法忧化.
19: printf("x/2 = %d \r\n", x/2); //有符号变量/常量2
00401097 mov eax,dword ptr [ebp-4] //1. x
0040109A cdq
0040109B sub eax,edx //2. x+1或 x+0 负数调整
0040109D sar eax,1 //3. x /2
0040109F push eax
004010A0 push offset string "x/2 = %d \r\n" (00425324)
004010A5 call printf (004016c0)
004010AA add esp,8
分析4: 代码功能 x/2 第2处代码是不是很诡秘,原因如下
当x > 0 时
当x < 0 时= (x+1) >> 1 这步根据推导7
第2处利用x符号位,巧妙的做了调整,避免了分支.
20: printf("x/-2 = %d \r\n", x/-2); //有符号变量/常量-2
004010AD mov eax,dword ptr [ebp-4] //1. x
004010B0 cdq
004010B1 sub eax,edx //2. 调整
004010B3 sar eax,1 //3. x / 2
004010B5 neg eax //4. -x
004010B7 push eax
004010B8 push offset string "x/-2 = %d \r\n" (00425314)
004010BD call printf (004016c0)
004010C2 add esp,8
分析5: 编译器这样做了 ;先求括号里的值,分析过程 同 分析4 ,最后第4步 结果来个求补.
21: printf("u/2 = %d \r\n", u/2); //无符号变量/常量2
004010C5 mov eax,dword ptr [ebp-0Ch] //1.
004010C8 shr eax,1 //2.直接逻辑移位
004010CA push eax
004010CB push offset string "u/2 = %d \r\n" (00425304)
004010D0 call printf (004016c0)
004010D5 add esp,8
分析6: 无符号 除 2的幂 直接逻辑移位;
22: printf("u/-2 = %d \r\n", u/-2); //无符号变量/常量-2
004010D8 mov eax,dword ptr [ebp-0Ch]
004010DB xor edx,edx
004010DD mov ecx,0FFFFFFFEh
004010E2 div eax,ecx
004010E4 push eax
004010E5 push offset string "u/-2 = %d \r\n" (004252f4)
004010EA call printf (004016c0)
004010EF add esp,8
分析7: 无符号 除 负数,负数被当无符号处理,直接除.无忧化
24: printf("x/3 = %d \r\n", x/3); //有符号变量/常量3
004010F2 mov eax,dword ptr [ebp-4]
004010F5 cdq
004010F6 mov ecx,3
004010FB idiv eax,ecx
004010FD push eax
004010FE push offset string "x/3 = %d \r\n" (004252e4)
00401103 call printf (004016c0)
00401108 add esp,8
分析8: 太直观
25: printf("x/-3 = %d \r\n", x/-3); //有符号变量/常量-3
0040110B mov eax,dword ptr [ebp-4]
0040110E cdq
0040110F mov ecx,0FFFFFFFDh
00401114 idiv eax,ecx
00401116 push eax
00401117 push offset string "x/-3 = %d \r\n" (004252d4)
0040111C call printf (004016c0)
00401121 add esp,8
分析9: 太直观
26: printf("u/3 = %d \r\n", u/3); //无符号变量/常量3
00401124 mov eax,dword ptr [ebp-0Ch]
00401127 xor edx,edx
00401129 mov ecx,3
0040112E div eax,ecx
00401130 push eax
00401131 push offset string "u/3 = %d \r\n" (004252c4)
00401136 call printf (004016c0)
0040113B add esp,8
分析10: 太直观
27: printf("u/-3 = %d \r\n", u/-3); //无符号变量/常量-3
0040113E mov eax,dword ptr [ebp-0Ch]
00401141 xor edx,edx
00401143 mov ecx,0FFFFFFFDh
00401148 div eax,ecx
0040114A push eax
0040114B push offset string "u/-3 = %d \r\n" (004252b4)
00401150 call printf (004016c0)
00401155 add esp,8
分析11: 无符号 除 负数,负数被当无符号处理,直接除.无忧化
29: printf("x/4 = %d \r\n", x/4); //有符号变量/常量4
00401158 mov eax,dword ptr [ebp-4]
0040115B cdq
0040115C and edx,3 //.1调整
0040115F add eax,edx //.2调整
00401161 sar eax,2
00401164 push eax
00401165 push offset string "x/4 = %d \r\n" (004252a4)
0040116A call printf (004016c0)
0040116F add esp,8
分析12: 代码功能 x/4
当x > 0 时
当x < 0 时= (x+3) >> 1 这步根据推导7
第1与2处利用x符号位,巧妙的做了调整,避免了分支.
30: printf("x/-4 = %d \r\n", x/-4); //有符号变量/常量-4
00401172 mov eax,dword ptr [ebp-4]
00401175 cdq
00401176 and edx,3
00401179 add eax,edx
0040117B sar eax,2
0040117E neg eax //1
00401180 push eax
00401181 push offset string "x/-4 = %d \r\n" (00425294)
00401186 call printf (004016c0)
0040118B add esp,8
分析13: 编译器这样做了 ;先求括号里的值,分析过程 同 分析12 ,最后第1处 结果来个求补.
31: printf("u/4 = %d \r\n", u/4); //无符号变量/常量4
0040118E mov eax,dword ptr [ebp-0Ch]
00401191 shr eax,2
00401194 push eax
00401195 push offset string "u/4 = %d \r\n" (00425284)
0040119A call printf (004016c0)
0040119F add esp,8
分析14: 无符号 除 2的幂 直接逻辑右移
32: printf("u/-4 = %d \r\n", u/-4); //无符号变量/常量-4
004011A2 mov eax,dword ptr [ebp-0Ch]
004011A5 xor edx,edx
004011A7 mov ecx,0FFFFFFFCh
004011AC div eax,ecx
004011AE push eax
004011AF push offset string "u/-4 = %d \r\n" (00425274)
004011B4 call printf (004016c0)
004011B9 add esp,8
分析15: 无符号 除 负数,负数被当无符号处理,直接除.无忧化
34: printf("x/5 = %d \r\n", x/5); //有符号变量/常量5
004011BC mov eax,dword ptr [ebp-4]
004011BF cdq
004011C0 mov ecx,5
004011C5 idiv eax,ecx
004011C7 push eax
004011C8 push offset string "x/5 = %d \r\n" (00425264)
004011CD call printf (004016c0)
004011D2 add esp,8
分析16: 有符号 除 非2的幂 无忧化,直接除
35: printf("x/-5 = %d \r\n", x/-5); //有符号变量/常量-5
004011D5 mov eax,dword ptr [ebp-4]
004011D8 cdq
004011D9 mov ecx,0FFFFFFFBh
004011DE idiv eax,ecx
004011E0 push eax
004011E1 push offset string "x/-5 = %d \r\n" (00425254)
004011E6 call printf (004016c0)
004011EB add esp,8
分析17: 有符号 除 非2的幂 无忧化,直接除
36: printf("u/5 = %d \r\n", u/5); //无符号变量/常量5
004011EE mov eax,dword ptr [ebp-0Ch]
004011F1 xor edx,edx
004011F3 mov ecx,5
004011F8 div eax,ecx
004011FA push eax
004011FB push offset string "u/5 = %d \r\n" (00425244)
00401200 call printf (004016c0)
00401205 add esp,8
分析18: 无符号 除 非2的幂 直接除.无忧化
37: printf("u/-5 = %d \r\n", u/-5); //无符号变量/常量-5
00401208 mov eax,dword ptr [ebp-0Ch]
0040120B xor edx,edx
0040120D mov ecx,0FFFFFFFBh
00401212 div eax,ecx
00401214 push eax
00401215 push offset string "u/-5 = %d \r\n" (00425234)
0040121A call printf (004016c0)
0040121F add esp,8
分析19: 无符号 除 负数,负数被当无符号处理,直接除.无忧化
39: printf("x/6 = %d \r\n", x/6); //有符号变量/常量6
00401222 mov eax,dword ptr [ebp-4]
00401225 cdq
00401226 mov ecx,6
0040122B idiv eax,ecx
0040122D push eax
0040122E push offset string "x/6 = %d \r\n" (00425224)
00401233 call printf (004016c0)
00401238 add esp,8
分析20: 有符号 除 非2的幂 无忧化,直接除
40: printf("x/-6 = %d \r\n", x/-6); //有符号变量/常量-6
0040123B mov eax,dword ptr [ebp-4]
0040123E cdq
0040123F mov ecx,0FFFFFFFAh
00401244 idiv eax,ecx
00401246 push eax
00401247 push offset string "x/-6 = %d \r\n" (00425214)
0040124C call printf (004016c0)
00401251 add esp,8
分析21: 有符号 除 非2的幂 无忧化,直接除
41: printf("u/6 = %d \r\n", u/6); //无符号变量/常量6
00401254 mov eax,dword ptr [ebp-0Ch]
00401257 xor edx,edx
00401259 mov ecx,6
0040125E div eax,ecx
00401260 push eax
00401261 push offset string "u/6 = %d \r\n" (00425204)
00401266 call printf (004016c0)
0040126B add esp,8
分析22: 无符号 除 非2的幂 直接除.无忧化
42: printf("u/-6 = %d \r\n", u/-6); //无符号变量/常量-6
0040126E mov eax,dword ptr [ebp-0Ch]
00401271 xor edx,edx
00401273 mov ecx,0FFFFFFFAh
00401278 div eax,ecx
0040127A push eax
0040127B push offset string "u/-6 = %d \r\n" (004251f4)
00401280 call printf (004016c0)
00401285 add esp,8
分析23: 无符号 除 负数,负数被当无符号处理,直接除.无忧化
44: printf("x/7 = %d \r\n", x/7); //有符号变量/常量7
00401288 mov eax,dword ptr [ebp-4]
0040128B cdq
0040128C mov ecx,7
00401291 idiv eax,ecx
00401293 push eax
00401294 push offset string "x/7 = %d \r\n" (004251e4)
00401299 call printf (004016c0)
0040129E add esp,8
分析24: 太直观
45: printf("x/-7 = %d \r\n", x/-7); //有符号变量/常量-7
004012A1 mov eax,dword ptr [ebp-4]
004012A4 cdq
004012A5 mov ecx,0FFFFFFF9h
004012AA idiv eax,ecx
004012AC push eax
004012AD push offset string "x/-7 = %d \r\n" (004251d4)
004012B2 call printf (004016c0)
004012B7 add esp,8
分析25: 太直观
46: printf("u/7 = %d \r\n", u/7); //无符号变量/常量7
004012BA mov eax,dword ptr [ebp-0Ch]
004012BD xor edx,edx
004012BF mov ecx,7
004012C4 div eax,ecx
004012C6 push eax
004012C7 push offset string "u/7 = %d \r\n" (004251c4)
004012CC call printf (004016c0)
004012D1 add esp,8
分析26: 太直观
47: printf("u/-7 = %d \r\n", u/-7); //无符号变量/常量-7
004012D4 mov eax,dword ptr [ebp-0Ch]
004012D7 xor edx,edx
004012D9 mov ecx,0FFFFFFF9h
004012DE div eax,ecx
004012E0 push eax
004012E1 push offset string "u/-7 = %d \r\n" (004251b4)
004012E6 call printf (004016c0)
004012EB add esp,8
分析27: 太直观
49: printf("x/8 = %d \r\n", x/8); //有符号变量/常量8
004012EE mov eax,dword ptr [ebp-4]
004012F1 cdq
004012F2 and edx,7 //1
004012F5 add eax,edx //2
004012F7 sar eax,3
004012FA push eax
004012FB push offset string "x/8 = %d \r\n" (004251a4)
00401300 call printf (004016c0)
分析28: 代码功能 x/8
当x > 0 时
当x < 0 时= (x+7) >> 3 这步根据推导7
第1与2处利用x符号位,巧妙的做了调整,避免了分支.
50: printf("x/-8 = %d \r\n", x/-8); //有符号变量/常量-8
00401308 mov eax,dword ptr [ebp-4]
0040130B cdq
0040130C and edx,7
0040130F add eax,edx
00401311 sar eax,3
00401314 neg eax //1
00401316 push eax
00401317 push offset string "x/-8 = %d \r\n" (00425194)
0040131C call printf (004016c0)
00401321 add esp,8
分析29: 编译器这样做了 ;先求括号里的值,分析过程 同 分析28 ,最后第1处 结果来个求补.
51: printf("u/8 = %d \r\n", u/8); //无符号变量/常量8
00401324 mov eax,dword ptr [ebp-0Ch]
00401327 shr eax,3
0040132A push eax
0040132B push offset string "u/8 = %d \r\n" (00425184)
00401330 call printf (004016c0)
00401335 add esp,8
分析30: 无符号 除 2的幂 直接逻辑右移
52: printf("u/-8 = %d \r\n", u/-8); //无符号变量/常量-8
00401338 mov eax,dword ptr [ebp-0Ch]
0040133B xor edx,edx
0040133D mov ecx,0FFFFFFF8h
00401342 div eax,ecx
00401344 push eax
00401345 push offset string "u/-8 = %d \r\n" (00425174)
0040134A call printf (004016c0)
0040134F add esp,8
分析31: 无符号 除 非2的幂 直接除.无忧化
54: printf("x/9 = %d \r\n", x/9); //有符号变量/常量9
00401352 mov eax,dword ptr [ebp-4]
00401355 cdq
00401356 mov ecx,9
0040135B idiv eax,ecx
0040135D push eax
0040135E push offset string "x/9 = %d \r\n" (00425164)
00401363 call printf (004016c0)
00401368 add esp,8
分析32: 太直观
55: printf("x/-9 = %d \r\n", x/-9); //有符号变量/常量-9
0040136B mov eax,dword ptr [ebp-4]
0040136E cdq
0040136F mov ecx,0FFFFFFF7h
00401374 idiv eax,ecx
00401376 push eax
00401377 push offset string "x/-9 = %d \r\n" (00425154)
0040137C call printf (004016c0)
00401381 add esp,8
分析33: 太直观
56: printf("u/9 = %d \r\n", u/9); //无符号变量/常量9
00401384 mov eax,dword ptr [ebp-0Ch]
00401387 xor edx,edx
00401389 mov ecx,9
0040138E div eax,ecx
00401390 push eax
00401391 push offset string "u/9 = %d \r\n" (00425144)
00401396 call printf (004016c0)
0040139B add esp,8
分析34: 无符号 除 非2的幂 直接除.无忧化
57: printf("u/-9 = %d \r\n", u/-9); //无符号变量/常量-9
0040139E mov eax,dword ptr [ebp-0Ch]
004013A1 xor edx,edx
004013A3 mov ecx,0FFFFFFF7h
004013A8 div eax,ecx
004013AA push eax
004013AB push offset string "u/-9 = %d \r\n" (00425134)
004013B0 call printf (004016c0)
004013B5 add esp,8
分析35: 无符号 除 负数,负数被当无符号处理,直接除.无忧化
54: printf("x/9 = %d \r\n", x/9); //有符号变量/常量9
00401352 mov eax,dword ptr [ebp-4]
00401355 cdq
00401356 mov ecx,9
0040135B idiv eax,ecx
0040135D push eax
0040135E push offset string "x/9 = %d \r\n" (00425164)
00401363 call printf (004016c0)
00401368 add esp,8
分析36: 太直观
55: printf("x/-9 = %d \r\n", x/-9); //有符号变量/常量-9
0040136B mov eax,dword ptr [ebp-4]
0040136E cdq
0040136F mov ecx,0FFFFFFF7h
00401374 idiv eax,ecx
00401376 push eax
00401377 push offset string "x/-9 = %d \r\n" (00425154)
0040137C call printf (004016c0)
00401381 add esp,8
分析37: 太直观
56: printf("u/9 = %d \r\n", u/9); //无符号变量/常量9
00401384 mov eax,dword ptr [ebp-0Ch]
00401387 xor edx,edx
00401389 mov ecx,9
0040138E div eax,ecx
00401390 push eax
00401391 push offset string "u/9 = %d \r\n" (00425144)
00401396 call printf (004016c0)
0040139B add esp,8
分析38: 太直观
57: printf("u/-9 = %d \r\n", u/-9); //无符号变量/常量-9
0040139E mov eax,dword ptr [ebp-0Ch]
004013A1 xor edx,edx
004013A3 mov ecx,0FFFFFFF7h
004013A8 div eax,ecx
004013AA push eax
004013AB push offset string "u/-9 = %d \r\n" (00425134)
004013B0 call printf (004016c0)
004013B5 add esp,8
分析39: 太直观
59: printf("x/10 = %d \r\n", x/10); //有符号变量/常量10
004013B8 mov eax,dword ptr [ebp-4]
004013BB cdq
004013BC mov ecx,0Ah
004013C1 idiv eax,ecx
004013C3 push eax
004013C4 push offset string "x/10 = %d \r\n" (00425124)
004013C9 call printf (004016c0)
004013CE add esp,8
分析40: 太直观
60: printf("x/-10 = %d \r\n", x/-10); //有符号变量/常量-10
004013D1 mov eax,dword ptr [ebp-4]
004013D4 cdq
004013D5 mov ecx,0FFFFFFF6h
004013DA idiv eax,ecx
004013DC push eax
004013DD push offset string "x/-10 = %d \r\n" (00425114)
004013E2 call printf (004016c0)
004013E7 add esp,8
分析41: 太直观
61: printf("u/10 = %d \r\n", u/10); //无符号变量/常量10
004013EA mov eax,dword ptr [ebp-0Ch]
004013ED xor edx,edx
004013EF mov ecx,0Ah
004013F4 div eax,ecx
004013F6 push eax
004013F7 push offset string "u/10 = %d \r\n" (00425104)
004013FC call printf (004016c0)
00401401 add esp,8
分析42: 太直观
62: printf("u/-10 = %d \r\n", u/-10); //无符号变量/常量-10
00401404 mov eax,dword ptr [ebp-0Ch]
00401407 xor edx,edx
00401409 mov ecx,0FFFFFFF6h
0040140E div eax,ecx
00401410 push eax
00401411 push offset string "u/-10 = %d \r\n" (004250f4)
00401416 call printf (004016c0)
0040141B add esp,8
分析43: 太直观
64: printf("x/17 = %d \r\n", x/17); //有符号变量/常量17
0040141E mov eax,dword ptr [ebp-4]
00401421 cdq
00401422 mov ecx,11h
00401427 idiv eax,ecx
00401429 push eax
0040142A push offset string "x/17 = %d \r\n" (004250e4)
0040142F call printf (004016c0)
00401434 add esp,8
分析44: 太直观
65: printf("x/-17 = %d \r\n", x/-17); //有符号变量/常量-17
00401437 mov eax,dword ptr [ebp-4]
0040143A cdq
0040143B mov ecx,0FFFFFFEFh
00401440 idiv eax,ecx
00401442 push eax
00401443 push offset string "x/-17 = %d \r\n" (004250d4)
00401448 call printf (004016c0)
0040144D add esp,8
分析45: 太直观
66: printf("u/17 = %d \r\n", u/17); //无符号变量/常量17
00401450 mov eax,dword ptr [ebp-0Ch]
00401453 xor edx,edx
00401455 mov ecx,11h
0040145A div eax,ecx
0040145C push eax
0040145D push offset string "u/17 = %d \r\n" (004250c4)
00401462 call printf (004016c0)
00401467 add esp,8
分析46: 太直观
67: printf("u/-17 = %d \r\n", u/-17); //无符号变量/常量-17
0040146A mov eax,dword ptr [ebp-0Ch]
0040146D xor edx,edx
0040146F mov ecx,0FFFFFFEFh
00401474 div eax,ecx
00401476 push eax
00401477 push offset string "u/-17 = %d \r\n" (004250b4)
0040147C call printf (004016c0)
00401481 add esp,8
分析46: 太直观
69: printf("x/128 = %d \r\n", x/128); //有符号变量/常量128
00401484 mov eax,dword ptr [ebp-4]
00401487 cdq
00401488 and edx,7Fh //1
0040148B add eax,edx //2
0040148D sar eax,7
00401490 push eax
00401491 push offset string "x/128 = %d \r\n" (004250a4)
00401496 call printf (004016c0)
0040149B add esp,8
分析47: 代码功能 x/4
当x > 0 时 = x>>7
当x < 0 时= (x+127) >> 7 这步根据推导7 0x7f = 127
第1与2处利用x符号位,巧妙的做了调整,避免了分支.
70: printf("x/-128 = %d \r\n", x/-128); //有符号变量/常量-128
0040149E mov eax,dword ptr [ebp-4]
004014A1 cdq
004014A2 and edx,7Fh
004014A5 add eax,edx
004014A7 sar eax,7
004014AA neg eax //1
004014AC push eax
004014AD push offset string "x/-128 = %d \r\n" (00425090)
004014B2 call printf (004016c0)
004014B7 add esp,8
分析48: 编译器这样做了 ;先求括号里的值,分析过程 同 分析47 ,最后第1处 结果来个求补.
71: printf("u/128 = %d \r\n", u/128); //无符号变量/常量128
004014BA mov eax,dword ptr [ebp-0Ch]
004014BD shr eax,7
004014C0 push eax
004014C1 push offset string "u/128 = %d \r\n" (00425080)
004014C6 call printf (004016c0)
004014CB add esp,8
分析49: 无符号 除 2的幂 直接发逻辑右移.
72: printf("u/-128 = %d \r\n", u/-128); //无符号变量/常量-128
004014CE mov eax,dword ptr [ebp-0Ch]
004014D1 xor edx,edx
004014D3 mov ecx,0FFFFFF80h
004014D8 div eax,ecx
004014DA push eax
004014DB push offset string "u/-128 = %d \r\n" (0042506c)
004014E0 call printf (004016c0)
004014E5 add esp,8
分析50: 太直观
74: printf("x/7000 = %d \r\n", x/7000); //有符号变量/常量7000
004014E8 mov eax,dword ptr [ebp-4]
004014EB cdq
004014EC mov ecx,1B58h
004014F1 idiv eax,ecx
004014F3 push eax
004014F4 push offset string "x/7000 = %d \r\n" (00425058)
004014F9 call printf (004016c0)
004014FE add esp,8
分析51: 太直观
75: printf("x/-7000 = %d \r\n", x/-7000); //有符号变量/常量-7000
00401501 mov eax,dword ptr [ebp-4]
00401504 cdq
00401505 mov ecx,0FFFFE4A8h
0040150A idiv eax,ecx
0040150C push eax
0040150D push offset string "x/-7000 = %d \r\n" (00425044)
00401512 call printf (004016c0)
00401517 add esp,8
分析52: 太直观
76: printf("u/7000 = %d \r\n", u/7000); //无符号变量/常量7000
0040151A mov eax,dword ptr [ebp-0Ch]
0040151D xor edx,edx
0040151F mov ecx,1B58h
00401524 div eax,ecx
00401526 push eax
00401527 push offset string "u/7000 = %d \r\n" (00425030)
0040152C call printf (004016c0)
00401531 add esp,8
分析53: 太直观
77: printf("u/-7000 = %d \r\n", u/-7000); //无符号变量/常量-7000
00401534 mov eax,dword ptr [ebp-0Ch]
00401537 xor edx,edx
00401539 mov ecx,0FFFFE4A8h
0040153E div eax,ecx
00401540 push eax
00401541 push offset string "u/-7000 = %d \r\n" (0042501c)
00401546 call printf (004016c0)
0040154B add esp,8
分析54: 太直观
79: return 0;
0040154E xor eax,eax
80: }
00401550 pop edi
00401551 pop esi
00401552 pop ebx
00401553 add esp,4Ch
00401556 cmp ebp,esp
00401558 call __chkesp (004017a0)
0040155D mov esp,ebp
0040155F pop ebp
00401560 ret
; int __cdecl main(int argc, const char **argv, const char **envp)
main proc near ; CODE XREF: start+AFp
x= dword ptr -0Ch
u= dword ptr -8
y= dword ptr -4
argc= dword ptr 4
argv= dword ptr 8
envp= dword ptr 0Ch
sub esp, 0Ch //预留局部变量空间
xor eax, eax
lea ecx, [esp+0Ch+y]
mov [esp+0Ch+x], eax //变量们初始化为0
mov [esp+0Ch+y], eax
mov [esp+0Ch+u], eax
lea eax, [esp+0Ch+u]
push eax
lea edx, [esp+10h+x]
push ecx
push edx
push offset Format ; "%d %d %u"
call _scanf
//下面这段代码见的比较少见所以提前放在这里
mov ecx, [esp+4Ch+u] //1. u
mov eax, 7 //2. m = 7
mul ecx //3. um
sub ecx, edx //4. u-um/232
add esp, 40h
shr ecx, 1 //5. ( u-um/232)/2
add ecx, edx //6. ( u-um/232)/2+ um/232
shr ecx, 1Fh //7.结果 (( u-um/232)/2+ um/232)/ 231
push ecx
push offset aU6D_0 ; "u/-6 = %d \r\n"
call sub_401570
分析0: 第7步结果(( u-um/232)/2+ um/232)/ 231 =
向上面结果靠拢推: 如果有u/b 那么
则:m = ---> m+= ---> b = = FFFFFFF9 = -7
即u/ FFFFFFF9. 源码中是 u/-6.原因详见分析11 .
如果源码中是printf(“%d”,u/0xFFFFFFFA)不管 debug版本还是realse版本都不会这样去忧化.都是直接
div 0xFFFFFFFA.所以上面这种情况也可以推断是用一个无符号数除一个负数 的重要依据.
mov eax, [esp+1Ch+x]
cdq
idiv [esp+1Ch+y]
push eax
push offset aXYD ; "x/y = %d \r\n"
call sub_401570
分析1: x/y 两个变量相除,无忧化
mov eax, [esp+24h+x]
xor edx, edx
div [esp+24h+u]
push eax
push offset aXUD ; "x/u = %d \r\n"
call sub_401570
分析2: x/u 两个变量相除,无忧化.有符号x被当成无符号看待.
mov eax, [esp+2Ch+u]
xor edx, edx
div [esp+2Ch+x]
push eax
push offset aUXD ; "u/x = %d \r\n"
call sub_401570
分析3: u/x 两个变量相除,无忧化.有符号x被当成无符号看待.
mov eax, [esp+34h+x]
cdq
sub eax, edx //1
sar eax, 1
push eax
push offset aX2D ; "x/2 = %d \r\n"
call sub_401570
分析4: x/2
当x>0时 = x >> 1 ; 当x<0时 = (x+1) >> 1
第1处巧妙的运用了x符号作了调整,避免分支了!
mov eax, [esp+3Ch+x]
cdq
sub eax, edx //1
sar eax, 1
neg eax //2
push eax
push offset aX2D_0 ; "x/-2 = %d \r\n"
call sub_401570
分析5: x/-2
译器这样处理了 先求括号里的值,分析过程同 分析4. 然后第2处对结果求补.
mov eax, [esp+44h+u]
shr eax, 1 //无符号 除 2
push eax
push offset aU2D ; "u/2 = %d \r\n"
call sub_401570
分析6: u/2
mov eax, [esp+4Ch+u]
xor edx, edx
mov ecx, 0FFFFFFFEh
add esp, 40h
div ecx
push eax
push offset aU2D_0 ; "u/-2 = %d \r\n"
call sub_401570
分析7: u/0FFFFFFFEh
mov ecx, [esp+14h+x] //1.x
mov eax, 55555556h //2.设m=55555556h = 1431655766
imul ecx //3.xm
mov eax, edx
shr eax, 1Fh //4. 拿符号位
add edx, eax //5. 调整
push edx //6. 结果: xc/2^32
push offset aX3D ; "x/3 = %d \r\n"
call sub_401570
分析8: 最终结果 xc/2^32 = 如果有x/b : =
则m = --> b = = 2.9999999986030161387273035297509 即x/3
mov ecx, [esp+1Ch+x] //1. x
mov eax, 55555555h //2. m = 55555555h
imul ecx //3. xm
sub edx, ecx //4. xm-232x
sar edx, 1 //5.
mov ecx, edx //6以下为调整
shr ecx, 1Fh //7.拿符号位
add edx, ecx //8.调整
push edx
push offset aX3D_0 ; "x/-3 = %d \r\n"
call sub_401570
分析9: 第5步结果表达式: =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -2.9999999 即x/-3;
发现 b的表达 跟结果表达式有规律. b的分子 是结果表达式的分母,而b的分母是结果表达式的分子.注意看!(分析8也是这种情况).暂时命名这个规律叫 颠倒规律.
为什么第六步要调整呢?
根据第5步结果表达式: ,m是编译器生成的幻数.通过指令分析如有sar,imul .x肯定是个整数.则整个表达式的值 则是个实数.根据推导3
当x>0时 则:
当x<0时 则:
第7处与第8处巧妙的利用x的符号位决定要不要+1,避免了分支. 以下内容均以推出除数的值为重点,调整不再说明.
mov eax, 0AAAAAAABh //1. m = 0AAAAAAABh = 2863311531
mul [esp+24h+u] //2. um
shr edx, 1 //3. um / 233
push edx
push offset aU3D ; "u/3 = %d \r\n"
call sub_401570
分析10: 第3步结果
向上面结果靠拢推: 如果有u/b 那么
则:m = --> b = = 2.9999 即u/3. 也符合颠倒规律 !
mov eax, 40000001h //1. m = 40000001h = 1073741825
mul [esp+2Ch+u] //2. um
shr edx, 1Eh //3. (um)/232+30 0x1E=30
push edx
push offset aU3D_0 ; "u/-3 = %d \r\n"
call sub_401570
分析11: 第3步结果 (um)/232+30 =
若有u/b: 则 m = -->
b = = 4294967292 = 0xFFFFFFFC = -4
即u/0xFFFFFFFC其实这里是u/-3
.为什么会出现这种情况呢?
这段代码 源码中是u/-3. 但是我们把无符号u与有符号-3相除,编译器只认为是无符号相除,把-3当成无符号数,从指令中mul,shr也可以看出这点. VC是向0取整的.所以无符号只能向下取整 .而不考虑负数向上调整,即+1 .后面碰到此情况不再累述.
符合颠倒规律 !
mov eax, [esp+34h+x] //1. x
cdq
and edx, 3 //2.调整
add eax, edx
sar eax, 2 //3. x/22
push eax
push offset aX4D ; "x/4 = %d \r\n"
call sub_401570
分析12: x/22
当x>0时 = x >> 2 ; 当x<0时 = (x+3) >> 2
第2处巧妙的运用了x符号作了调整,避免分支了!
mov eax, [esp+3Ch+x] //1. x
cdq
and edx, 3 //2. 调整
add eax, edx
sar eax, 2 //3. x/22
neg eax //4. x求补
push eax
push offset aX4D_0 ; "x/-4 = %d \r\n"
call sub_401570
分析13: x/-22
译器这样处理了 先求括号里的值,分析过程同 分析12. 然后第4处对结果求补.
mov edx, [esp+44h+u] //1. u
shr edx, 2 //2. u/22
push edx
push offset aU4D ; "u/4 = %d \r\n"
call sub_401570
分析14: u/22
mov eax, [esp+4Ch+u] //1. u
xor edx, edx
mov ecx, 0FFFFFFFCh //2.-4
add esp, 40h
div ecx
push eax
push offset aU4D_0 ; "u/-4 = %d \r\n"
call sub_401570
分析15: u/0FFFFFFFCh 不再累述.
mov ecx, [esp+14h+x] //1. x
mov eax, 66666667h //2. m = 66666667h = 1717986919
imul ecx //3. xm
sar edx, 1 //4. 结果 xm/232+1
mov eax, edx //5. 开始调整
shr eax, 1Fh
add edx, eax
push edx
push offset aX5D ; "x/5 = %d \r\n"
call sub_401570
分析16: 结果xm/232+1 = 如果有x/b : =
则m = --> b = = 4.9999999982537701732058415050132即x/5 .符合颠倒规律 !
mov ecx, [esp+1Ch+x] //1. x
mov eax, 99999999h //2. m = 99999999h = 2576980377
imul ecx //3. x * -(232-m) = xm - 232x
sar edx, 1 //4.结果 ( xm - 232x)/232+1
mov ecx, edx //5. 开始调整
shr ecx, 1Fh
add edx, ecx
push edx
push offset aX5D_0 ; "x/-5 = %d \r\n"
call sub_401570
分析17: 第4步结果: ( xm - 232x)/232+1 =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -4.9999 即x/-5; 符合颠倒规律 !
mov eax, 0CCCCCCCDh //1. m = 0CCCCCCCDh = 3435973837
mul [esp+24h+u] //2. um
shr edx, 2 //3.结果um/232+2
push edx
push offset aU5D ; "u/5 = %d \r\n"
call sub_401570
分析18: 第3步结果 um/232+2 =
向上面结果靠拢推: 如果有u/b 那么
则:m = --> b = = 4.9999 即u/5. 也符合颠倒规律 !
mov eax, 80000003h //1. m = 80000003h = 2147483651
mul [esp+2Ch+u] //2. um 无符号mul不需要把80000003h转补码,这里当正数就是原码.
shr edx, 1Fh //3. 结果 um /232+31
push edx
push offset aU5D_0 ; "u/-5 = %d \r\n"
call sub_401570
分析19: 第3步结果 (um)/232+31 = 若有u/b: 则 m = -->
b = = 4294967290 = FFFFFFFA = -6 即u/ FFFFFFFA
源码中是 u/-5 原因详见分析11 .符合颠倒规律 !
mov ecx, [esp+34h+x] //1. x
mov eax, 2AAAAAABh //2. m = 2AAAAAABh = 715827883
imul ecx //3. xm
mov eax, edx //4.开始调整
shr eax, 1Fh
add edx, eax
push edx //5.结果xm/232
push offset aX6D ; "x/6 = %d \r\n"
call sub_401570
分析20: 结果xm/232 = 如果有x/b : =
则m = --> b = = 5.9999999972060322774546070595018即x/6 .符合颠倒规律 !
mov ecx, [esp+3Ch+x] //1. x
mov eax, 0D5555555h //2. m = 0D5555555h = 3579139413
imul ecx //3. 有符号转真值 x(m-232) = xm - 232x
mov ecx, edx //4. 开始调整
shr ecx, 1Fh
add edx, ecx
push edx //5.结果(xm - 232x)/ 232
push offset aX6D_0 ; "x/-6 = %d \r\n"
call sub_401570
分析21: 第5步结果表达式: (xm - 232x)/ 232 = =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -5.9999999 即x/-6;
符合颠倒规律 !
mov eax, 0AAAAAAABh //1. m = 0AAAAAAABh = 2863311531
mul [esp+44h+u] //2. um
shr edx, 2 //3. 结果 um/232+2
push edx
push offset aU6D ; "u/6 = %d \r\n"
call sub_401570
分析22: 第3步结果um/232+2 =
向上面结果靠拢推: 如果有u/b 那么
则:m = --> b = = 5.9999 即u/6. 也符合颠倒规律 !
mov ecx, [esp+4Ch+u] //1. u
mov eax, 7 //2. m = 7
mul ecx //3. um
sub ecx, edx //4. u-um/232
add esp, 40h
shr ecx, 1 //5. ( u-um/232)/2
add ecx, edx //6. ( u-um/232)/2+ um/232
shr ecx, 1Fh //7.结果 (( u-um/232)/2+ um/232)/ 231
push ecx
push offset aU6D_0 ; "u/-6 = %d \r\n"
call sub_401570
分析23: 第7步结果(( u-um/232)/2+ um/232)/ 231 =
向上面结果靠拢推: 如果有u/b 那么
则:m = ---> m+= ---> b = = FFFFFFF9 = -7
即u/ FFFFFFF9. 源码中是 u/-6.原因详见分析11 .符合颠倒规律 !
mov ecx, [esp+14h+x] //1. x
mov eax, 92492493h //2. m = 92492493h = 2454267027
imul ecx //3. xm-232x 有符号imul 数学公式要 还原真值
add edx, ecx //4. (xm-232x) +232x = xm 同edx相加相当于x>>32
sar edx, 2 //5.结果 xm/232+2
mov eax, edx //6.开始调整
shr eax, 1Fh
add edx, eax
push edx
push offset aX7D ; "x/7 = %d \r\n"
call sub_401570
分析24: 结果 xm/232+2 = 如果有x/b : =
则m = --> b = = 6.9999999986 即x/7 .符合颠倒规律 !
mov ecx, [esp+1Ch+x] //1. x
mov eax, 6DB6DB6Dh //2. m = 6DB6DB6Dh = 1840700269
imul ecx //3. xm
sub edx, ecx //4. xm-232x 同edx相减相当于x>>32,再减
sar edx, 2 //5.( xm-232x)/ 232+2
mov ecx, edx //6. 开始调整
shr ecx, 1Fh
add edx, ecx
push edx
push offset aX7D_0 ; "x/-7 = %d \r\n"
call sub_401570
分析25: 第5步结果表达式: ( xm-232x)/ 232+2 = =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -6.9999 即x/-7; 符合颠倒规律 !
mov ecx, [esp+24h+u] //1. u
mov eax, 24924925h //2. m = 24924925h = 613566757
mul ecx //3. um
sub ecx, edx //4. 232u-um 同edx相减 u>>32再减
shr ecx, 1 //5. ( 232u-um)/ 232+1
add ecx, edx //6. ( 232u-um)/ 233 + um/232
shr ecx, 2 //7.结果 ( ( 232u-um)/ 233 + um/232 ) /22
push ecx
push offset aU7D ; "u/7 = %d \r\n"
call sub_401570
分析26: 结果 ( ( 232u-um)/ 233 + um/232 ) / 22=
向上面结果靠拢推: 如果有u/b 那么
则:m = ---> m+= ---> b = = 6.9999 = 7
即u/ 7.符合颠倒规律 !
mov eax, 20000001h //1. m = 536870913
mul [esp+2Ch+u] //2. um
shr edx, 1Dh //3.结果 um/232+29
push edx
push offset aU7D_0 ; "u/-7 = %d \r\n"
call sub_401570
分析27: 第3步结果um/232+29 = 若有u/b: 则 m = -->
b = = 4294967290 = FFFFFFF8= -8 还原 源码中则是 u/-7 原因详见分析11 .符合颠倒规律 !
mov eax, [esp+34h+x]
cdq
and edx, 7
add eax, edx
sar eax, 3
push eax
push offset aX8D ; "x/8 = %d \r\n"
call sub_401570
分析28: x/23
当x>0时 = x >> 3 ; 当x<0时 = (x+7) >>3
mov eax, [esp+3Ch+x]
cdq
and edx, 7
add eax, edx
sar eax, 3
neg eax
push eax
push offset aX8D_0 ; "x/-8 = %d \r\n"
call sub_401570
分析29: x/-23
译器这样处理了 先求括号里的值,分析过程同 分析28. 然后第4处对结果求补.
mov edx, [esp+44h+u] //1. u
shr edx, 3 //2. u/23
push edx
push offset aU8D ; "u/8 = %d \r\n"
call sub_401570
分析30: u/8 太直观
mov eax, [esp+4Ch+u] //1. u
xor edx, edx
mov ecx, 0FFFFFFF8h //2.
add esp, 40h
div ecx
push eax
push offset aU8D_0 ; "u/-8 = %d \r\n"
call sub_401570
分析30: u/0FFFFFFF8h 太直观
mov ecx, [esp+14h+x] //1. x
mov eax, 38E38E39h //2. m = 38E38E39h = 954437177
imul ecx //3. xm
sar edx, 1 //4.结果 xm/232+1
mov eax, edx //5. 开始调整
shr eax, 1Fh
add edx, eax
push edx
push offset aX9D ; "x/9 = %d \r\n"
call sub_401570
分析31: 最终结果xm/232+1 = 如果有x/b : =
则m = --> b = = 8.999999998603016 即x/9 .符合颠倒规律 !
mov ecx, [esp+1Ch+x] //1. x
mov eax, 0C71C71C7h //2. m = C71C71C7h = 3340530119
imul ecx //3. xm – x232
sar edx, 1 //4.结果 (xm – x232)/232+1
mov ecx, edx //5.调整
shr ecx, 1Fh
add edx, ecx
push edx
push offset aX9D_0 ; "x/-9 = %d \r\n"
call sub_401570
分析32: 结果: (xm – x232)/232+1 = =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -8.99999 即x/-9; 符合颠倒规律 !
mov eax, 38E38E39h //1. m = 38E38E39h = 954437177
mul [esp+24h+u] //2. um
shr edx, 1 //3. um/232+1
push edx
push offset aU9D ; "u/9 = %d \r\n"
call sub_401570
分析33: 第3步结果um/232+1 =
向上面结果靠拢推: 如果有u/b 那么
则:m = --> b = = 8.9999 即u/9. 也符合颠倒规律 !
mov eax, 80000005h //1. m = 80000005h = 2147483653
mul [esp+2Ch+u] //2. um
shr edx, 1Fh //3. 结果 um/232+31
push edx
push offset aU9D_0 ; "u/-9 = %d \r\n"
call sub_401570
分析34: 第3步结果 (um)/232+31 = 若有u/b: 则 m = -->
b = = 4294967290 = FFFFFFF6= -10 即u/ FFFFFFF6
源码中是 u/-9 原因详见分析11 .符合颠倒规律 !
mov ecx, [esp+34h+x] //1. x
mov eax, 66666667h //2. m = 66666667h = 1717986919
imul ecx //3. mx
sar edx, 2 //4. 结果mx/232+2
mov eax, edx //5.开始调整
shr eax, 1Fh
add edx, eax
push edx
push offset aX10D ; "x/10 = %d \r\n"
call sub_401570
分析35: 结果 xm/232+2 = 如果有x/b : =
则m = --> b = = 9.9999999即x/10 .符合颠倒规律 !
mov ecx, [esp+3Ch+x] //1. x
mov eax, 99999999h //2.m = 99999999h = 2576980377
imul ecx //3. x(m-232)
sar edx, 2 //4. x(m-232)/232+2
mov ecx, edx //5. 开始调整
shr ecx, 1Fh
add edx, ecx
push edx
push offset aX10D_0 ; "x/-10 = %d \r\n"
call sub_401570
分析36 第4步结果表达式: x(m-232)/232+2 = =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -9.9999 即x/-10; 符合颠倒规律 !
mov eax, 0CCCCCCCDh //1. m = 0CCCCCCCDh = 3435973837
mul [esp+44h+u] //2. um
shr edx, 3 //3. 结果 um/232+3
push edx
push offset aU10D ; "u/10 = %d \r\n"
call sub_401570
分析37: 第3步结果um/232+3 =
向上面结果靠拢推: 如果有u/b 那么
则:m = --> b = = 9.9999 即u/10. 也符合颠倒规律 !
mov ecx, [esp+4Ch+u] //1. u
mov eax, 0Bh //2. m = 11
mul ecx //3. um
sub ecx, edx //4. 232u-um
add esp, 40h
shr ecx, 1 //5. (232u-um)/232+1
add ecx, edx //6. (232u-um)/232+1+um/232
shr ecx, 1Fh //7. ((232u-um)/232+1+um/232)/231
push ecx
push offset aU10D_0 ; "u/-10 = %d \r\n"
call sub_401570
分析38: 结果 ( ( 232u-um)/ 233 + um/232 ) / 231=
向上面结果靠拢推: 如果有u/b 那么
则:m = ---> m+= ---> b = = FFFFFFF5 = -11
即u/ FFFFFFF5
源码中是 u/-10 原因详见分析11 .符合颠倒规律 !
mov ecx, [esp+14h+x] //1. x
mov eax, 78787879h //2. m = 78787879h = 2021161081
imul ecx //3. xm
sar edx, 3 //4. xm/232+3
mov eax, edx //5. 开始调整
shr eax, 1Fh
add edx, eax
push edx
push offset aX17D ; "x/17 = %d \r\n"
call sub_401570
分析39: 最终结果xm/232+3 = 如果有x/b : =
则m = --> b = = 16.999999998603 即x/17 .符合颠倒规律 !
mov ecx, [esp+1Ch+x] //1. x
mov eax, 87878787h //2. m = 87878787h = 2273806215
imul ecx //3. x(m-232)
sar edx, 3 //4. x(m-232)/232+3
mov ecx, edx //5. 开始调整
shr ecx, 1Fh
add edx, ecx
push edx
push offset aX17D_0 ; "x/-17 = %d \r\n"
call sub_401570
分析40: 结果: x(m – 232)/232+3 = =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -16.999 即x/-17; 符合颠倒规律 !
34359738368/(2273806215-4294967296)
mov eax, 0F0F0F0F1h //1. m = F0F0F0F1h = 4042322161
mul [esp+24h+u] //2. um
shr edx, 4 //3. um/232+4
push edx
push offset aU17D ; "u/17 = %d \r\n"
call sub_401570
分析41: 第3步结果um/232+4 =
向上面结果靠拢推: 如果有u/b 那么
则:m = --> b = = 16.9999 即u/17. 也符合颠倒规律 !
mov eax, 80000009h //1. m = 80000009h = 2147483657
mul [esp+2Ch+u] //2. um
shr edx, 1Fh //3. um/232+31
push edx
push offset aU17D_0 ; "u/-17 = %d \r\n"
call sub_401570
分析42: 第3步结果 (um)/232+31 = 若有u/b: 则 m = -->
b = = FFFFFFEE = -18 即u/ FFFFFFEE
源码中是 u/-17 原因详见分析11 .符合颠倒规律 !
mov eax, [esp+34h+x] //1. x
cdq
and edx, 7Fh //2.开始调整
add eax, edx
sar eax, 7 //3.x/27
push eax
push offset aX128D ; "x/128 = %d \r\n"
call sub_401570
分析43: .x/27
当x>0时 = x >> 7 ; 当x<0时 = (x+7) >> 7
第2处巧妙的运用了x符号作了调整,避免分支了!
mov eax, [esp+3Ch+x]
cdq
and edx, 7Fh
add eax, edx
sar eax, 7
neg eax
push eax
push offset aX128D_0 ; "x/-128 = %d \r\n"
call sub_401570
分析44: x/-27
译器这样处理了 先求括号里的值,分析过程同 分析43. 然后对结果求补.
mov edx, [esp+44h+u]
shr edx, 7
push edx
push offset aU128D ; "u/128 = %d \r\n"
call sub_401570
分析45: u/128 太直观
mov eax, [esp+4Ch+u] //1. u
xor edx, edx
mov ecx, 0FFFFFF80h //2. m = 0FFFFFF80h
add esp, 40h
div ecx u/m
push eax
push offset aU128D_0 ; "u/-128 = %d \r\n"
call sub_401570
分析45: u/0FFFFFF80h太直观 源码中是 u/-128
mov ecx, [esp+14h+x] //1. x
mov eax, 2572FB07h //2. m = 2572FB07h = 628292359
imul ecx //3. xm
sar edx, 0Ah //4. xm/232+10
mov eax, edx //5.开始调整
shr eax, 1Fh
add edx, eax
push edx
push offset aX7000D ; "x/7000 = %d \r\n"
call sub_401570
分析46: 结果xm/232+10 = 如果有x/b : =
则m = --> b = = 6999.9999982即x/7000 .符合颠倒规律 !
mov ecx, [esp+1Ch+x] //1. x
mov eax, 0DA8D04F9h //2. m = 0DA8D04F9h = 3666674937
imul ecx //3. x(m-232)
sar edx, 0Ah //4. x(m-232)/232+10
mov ecx, edx //5. 开始调整
shr ecx, 1Fh
add edx, ecx
push edx
push offset aX7000D_0 ; "x/-7000 = %d \r\n"
call sub_401570
分析47 第4步结果表达式: x(m-232)/232+10 = =
向上面结果靠拢推: 如果有x/b 那么
则:m = ---> m-= ---> b = = -6999.9999 即x/-7000; 符合颠倒规律 !
4398046511104/(3666674937-4294967296)
xor eax, eax
add esp, 34h
retn
main endp