Debug版本總結:優化
有符號 除 2的冪 和無符號除2的冪做了優化, 其它狀況都是 直接運用div,或idiv指令spa
4: #include "stdafx.h"debug
5: #include "stdio.h"orm
6:編譯器
7: int main(unsigned int argc, char* argv[])源碼
8: {數學
00401010 push ebpstring
00401011 mov ebp,espio
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