zoukankan      html  css  js  c++  java
  • GCC下宏扩展后的++i

    听讨论的时候,遇到一题是关于++i*++i的——这样的讨论意义不大,却也可以一窥编译器对相关问题的处理。

    原题如下

    相关代码说明如下

    #include <stdio.h>
    #define POWER(X) X*X
    int main()
    {
    int ch = 8;
    int sum = POWER(ch++);
    sum
    = POWER(++ch);
    return 0;
    }

    如果添加printf输出,其第一个sum = 64,第二个sum = 144

    将上面的进行汇编编译得到。

    gcc -S test.c

    程序main的主要汇编代码

    main:
    pushl %ebp
    movl %esp, %ebp
    subl $
    16, %esp
    movl $
    8, -8(%ebp)
    movl -
    8(%ebp), %eax
    imull -
    8(%ebp), %eax
    movl %eax, -
    4(%ebp)
    addl $
    1, -8(%ebp)
    addl $
    1, -8(%ebp)
    addl $
    1, -8(%ebp)
    addl $
    1, -8(%ebp)
    movl -
    8(%ebp), %eax
    imull -
    8(%ebp), %eax
    movl %eax, -
    4(%ebp)
    movl $
    0, %eax
    leave
    ret

    少去进栈出栈的操作,i++*i++产生的汇编代码是

         movl -8(%ebp), %eax
    imull -
    8(%ebp), %eax
    movl %eax, -
    4(%ebp)
    addl $
    1, -8(%ebp)
    addl $
    1, -8(%ebp)

    ++i*++i产生的汇编代码是

    addl $1, -8(%ebp)
    addl $
    1, -8(%ebp)
    movl -
    8(%ebp), %eax
    imull -
    8(%ebp), %eax

    由上面的代码可以看出

    1)i++的自增操作是在整个乘法完成之后才进行的,而++i的操作则是在乘法之前进行。

    2)movl和imull总是连续出现,进行乘法的时候,左右的操作数是从同一块内存取出来的,因此计算结果肯定是完全平方数。

    找到一篇相似的文章《分析gcc下的i++与++i》gfw),在后续讨论三个i++的情况。后面还有总结,先一并摘抄过来。

    ++i*i++*++i的汇编代码为  

    movl $8, -8(%ebp)
    addl $
    1, -8(%ebp)
    movl -
    8(%ebp), %eax
    imull -
    8(%ebp), %eax
    addl $
    1, -8(%ebp)
    imull -
    8(%ebp), %eax
    movl %eax, -
    4(%ebp)
    addl $
    1, -8(%ebp)
    leave
    ret

    摘录

    分析一下上面的代码,结论就很清晰了,所有的i++操作会在整个表达式计算完后才计算,除了最左边的乘法会从同一块内存取操作数外,后续的乘法的作操作数就是直接取的上次计算的结果。

    总结一下:

    1.从左向右计算
    2.最左边的乘法从同一内存取操作数,因此肯定是完全平方数
    3.所有的i
    ++可以替换成i
    4.所有的
    ++i先计算增一,再取增一后的值
    比如计算 i++*++i*++i*i++*++i (i=3): 结果是 4×4×5×5×6=2400.


  • 相关阅读:
    Scrum学习总结
    1330. 翻转子数组得到最大的数组值
    LeetCode 中等题解(4)
    LeetCode 中等题解(3)
    LeetCode 中等题解(2)
    LeetCode 中等题解(1)
    【暑期实习】计算机视觉岗问题整理-腾讯
    【暑期实习】计算机视觉岗问题整理-快手
    【暑期实习】计算机视觉岗问题整理-阿里
    Leetcode 1329. 将矩阵按对角线排序 题解
  • 原文地址:https://www.cnblogs.com/westfly/p/2095474.html
Copyright © 2011-2022 走看看