《C++反汇编与逆向分析》学习
萧禾财 Lv4

第四章 观察各种表达式的求值过程

4.1、算数运算和赋值

4.1.1 各种算术运算的工作形式

  1. 加法
    加法运算对应的汇编语言是ADD。
    但在实际运用中编译器会考虑转化效率,优化代码。
    优化方案有:常量传播,常量折叠。
    常量传播:将编译期间可计算出结果的变量转换成变量,这样就减少了变量的使用。

    例如:

    1
    2
    3
    4
    int n=1;
    printf("%d",n);
    //变量n在编译期间就可以计算出结果,因此,在程序中在引用n的地方会直接使用常量1代替
    printf("%d",1);

    常量折叠:当出现多个常量进行计算,且编译器可以在编译期间计算出结构时,源码中的所有的常量计算都将被计算结果代替。

    1
    2
    3
    4
    5
    6
    7
    int n =5+3*4+1;
    printf("%d",n);
    //当多个常量进行运算时,编译器会在编译期间计算出结果,源码中的所有的常量计算都会被计算结果替代
    int n =18;
    printf("%d",n);
    //在因为n是个常量,编译时会产生常量传播
    printf("%d",18);
  2. 减法
    减法运算对应的汇编指令SUB
    减法操作一般通过补码的方式将减法转变位加法。当加数为负数时,执行的并非为加法而是减法

    1
    2
    3
    4
    ;n1=n1-100
    mov edx,[ebp-4]
    sub edx,64h
    mov [ebp-4],edx
  3. 乘法
    乘法运算对应的汇编指令分为有符号imul和无符号mul
    由于乘法指令执行周期较长,编译器在编译期间会先尝试将其转化成加法,或使用位移等周期较短的指令。
    有符号数乘以常量值,且常量非2的时,会直接使用有符号数乘法imul指令或者左移加减进行优化。

    当常量为2的幂时,编译器会采用执行周期较短的左移运算代替乘法指令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ;n1*15 变量乘常量(常量值非2的幂
    imul edx,[ebp-4],0Fh ;edx=n1*15
    ;n1*16 变量乘常量(常量值为2的幂
    shl eax,4
    ;n2*4+5 混合运算
    lea edx,ds:5[ecx*4] ;lea指令是取内存地址index,'ds:[index]'表示index地址上的数据
    ;n1*n2 变量相乘
    mov eax [ebp-4]
    imul eax,[ebp-8]
  4. 除法
    除法运算对应的指令分为有符号的idiv和无符号div
    除法指令执行周期长,效率低,编译器会先想办法转化为其他指令代替
    a、除数为无符号2的幂

    1
    2
    ;(unsigned)n/4
    shr eax,4 ;eax=eax>>4

    b、除数为无符号非2的幂(上)

    1
    2
    3
    4
    ;(unsigned)n/3
    mov eax,0AAAAAAABH ;eax=M
    mul dword ptr [esp+4] ;无符号乘法 (edx*16+eax)*n
    shr edx,1 ;无符号右移 edx=n*M>>32>>1
  • 本文标题:《C++反汇编与逆向分析》学习
  • 本文作者:萧禾财
  • 创建时间:2022-10-25 13:29:12
  • 本文链接:https://ipartmentxhc.github.io/2022/10/25/《C-反汇编与逆向分析》学习/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!