吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5542|回复: 3
收起左侧

[调试逆向] VC6 Debug下的除法优化技术

[复制链接]
Snow 发表于 2012-6-22 14:20
Debug版本的除法优化比较简单,我也不多说些什么了,重点看注释吧下面汇编代码中只有从地址0040108C 开始的代码才有优化,上面的是 普通除法,可略过。
C:
#include <stdio.h>
#include <stdlib.h>void main(int argc)
{
    printf("03=%d",argc/3);  //-*
    printf("05=%d",argc/5);  // |
    printf("11=%d",argc/11); // |
    printf("59=%d",argc/59); //-*
    printf("04=%d",argc/4);
    printf("64=%d",argc/64);
}ASM:00401010 >|> \55            push ebp
00401011  |.  8BEC          mov ebp,esp
00401013  |.  83EC 40       sub esp,0x40
00401016  |.  53            push ebx
00401017  |.  56            push esi
00401018  |.  57            push edi
00401019  |.  8D7D C0       lea edi,[local.16]
0040101C  |.  B9 10000000   mov ecx,0x10
00401021  |.  B8 CCCCCCCC   mov eax,0xCCCCCCCC
00401026  |.  F3:AB         rep stos dword ptr es:[edi]
00401028  |.  8B45 08       mov eax,[arg.1]                          ;  eax=被除数
0040102B  |.  99            cdq
0040102C  |.  B9 03000000   mov ecx,0x3                              ;  ecx=3(除数)
00401031  |.  F7F9          idiv ecx
00401033  |.  50            push eax                                 ; /<%d>
00401034  |.  68 44204200   push Debugasm.00422044                   ; |format = "03=%d"
00401039  |.  E8 D2000000   call Debugasm.printf                     ; \printf
0040103E  |.  83C4 08       add esp,0x8
00401041  |.  8B45 08       mov eax,[arg.1]                          ;  eax=被除数
00401044  |.  99            cdq
00401045  |.  B9 05000000   mov ecx,0x5                              ;  ecx=除数(5)
0040104A  |.  F7F9          idiv ecx
0040104C  |.  50            push eax                                 ; /<%d>
0040104D  |.  68 3C204200   push Debugasm.0042203C                   ; |format = "05=%d"
00401052  |.  E8 B9000000   call Debugasm.printf                     ; \printf
00401057  |.  83C4 08       add esp,0x8
0040105A  |.  8B45 08       mov eax,[arg.1]                          ;  eax=被除数
0040105D  |.  99            cdq
0040105E  |.  B9 0B000000   mov ecx,0xB                              ;  ecx=除数(11)
00401063  |.  F7F9          idiv ecx
00401065  |.  50            push eax                                 ; /<%d>
00401066  |.  68 34204200   push Debugasm.00422034                   ; |format = "11=%d"
0040106B  |.  E8 A0000000   call Debugasm.printf                     ; \printf
00401070  |.  83C4 08       add esp,0x8
00401073  |.  8B45 08       mov eax,[arg.1]                          ;  eax=被除数
00401076  |.  99            cdq
00401077  |.  B9 3B000000   mov ecx,0x3B                             ;  ecx=除数(59)
0040107C  |.  F7F9          idiv ecx
0040107E  |.  50            push eax                                 ; /<%d>
0040107F  |.  68 2C204200   push Debugasm.0042202C                   ; |format = "59=%d"
00401084  |.  E8 87000000   call Debugasm.printf                     ; \printf
00401089  |.  83C4 08       add esp,0x8                              ;  上面的除法运算均无优化(就是说下面的都有。。)
;  上面的除法运算均无优化(就是说下面的都有。。)
;  上面的除法运算均无优化(就是说下面的都有。。)
;  上面的除法运算均无优化(就是说下面的都有。。)
;  上面的除法运算均无优化(就是说下面的都有。。)
0040108C  |.  8B45 08       mov eax,[arg.1]                          ;  eax=被除数
0040108F  |.  99            cdq                                      ;  eax是正则edx=0 否则 edx=FFFFF……(32个F)
00401090  |.  83E2 03       and edx,0x3                              ;  eax是正数则什么都不做(因为edx(值为0)跟任何数AND都是0) eax是负数的话,就取除数-1
00401093  |.  03C2          add eax,edx                              ;  用"除数-1"跟被除数相加
00401095  |.  C1F8 02       sar eax,0x2                              ;  然后右移2位(除以4)  以上代码可得出 被除数除以除数的结果(根据公式.....)
也不说什么公式了,看下下面这些式子的规律吧:
-16/4 = (-16+3)>>2 = -13>>2 = -4
-5/4  = (-5+3) >>2 = -2 >>2 = -1
-4/4  = (-4+3) >>2 = -1 >>2 = -1
-3/4  = (-3+3) >>2 =  0 >>2 =  0
-2/4  = (-2+3) >>2 =  1 >>2 =  0
这里是有公式在里面的,在<<C++反汇编技术揭秘>>一书中有提及证明方法。
00401098  |.  50            push eax                                 ; /<%d>
00401099  |.  68 24204200   push Debugasm.00422024                   ; |format = "04=%d"
0040109E  |.  E8 6D000000   call Debugasm.printf                     ; \printf
004010A3  |.  83C4 08       add esp,0x8
004010A6  |.  8B45 08       mov eax,[arg.1]
004010A9  |.  99            cdq
004010AA  |.  83E2 3F       and edx,0x3F
004010AD  |.  03C2          add eax,edx
004010AF  |.  C1F8 06       sar eax,0x6
004010B2  |.  50            push eax                                 ; /<%d>
004010B3  |.  68 1C204200   push Debugasm.0042201C                   ; |format = "64=%d"
004010B8  |.  E8 53000000   call Debugasm.printf                     ; \printf
004010BD  |.  83C4 08       add esp,0x8
004010C0  |.  5F            pop edi
004010C1  |.  5E            pop esi
004010C2  |.  5B            pop ebx
004010C3  |.  83C4 40       add esp,0x40
004010C6  |.  3BEC          cmp ebp,esp
004010C8  |.  E8 C3000000   call Debugasm._chkesp
004010CD  |.  8BE5          mov esp,ebp
004010CF  |.  5D            pop ebp
004010D0  \.  C3            retn

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Chenxs110 发表于 2012-8-6 09:03
书里提到过  分为有符号和无符号的   公式比较麻烦 但都属于数学公式的范畴
头像被屏蔽
122166 发表于 2013-3-22 08:45
1400212 发表于 2013-4-23 12:00
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 07:14

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表