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