LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1376|回复: 9

i++在gcc中的问题

[复制链接]
发表于 2007-10-7 14:26:30 | 显示全部楼层 |阅读模式

  1. #include <stdlib.h>
  2. #include <stdio.h>

  3. int main()
  4. {
  5.     int i=0;
  6.     scanf("%d",&i);
  7.     ++i;
  8.     printf("%d\n",i);
  9.     return 0;
  10. }
复制代码


原来想编译成的汇编代码中i++应该转换成inc指令的,却没想到是addl,这是怎么回事呢?


  1. .file   "test.c"
  2.     .section    .rodata.str1.1,"aMS",@progbits,1
  3. .LC0:
  4.     .string "%d"
  5. .LC1:
  6.     .string "%d\n"
  7.     .text
  8.     .p2align 4,,15
  9. .globl main
  10.     .type   main, @function
  11. main:
  12.     leal    4(%esp), %ecx
  13.     andl    $-16, %esp
  14.     pushl   -4(%ecx)
  15.     pushl   %ebp
  16.     movl    %esp, %ebp
  17.     pushl   %ecx
  18.     subl    $36, %esp
  19.     leal    -8(%ebp), %eax
  20.     movl    $0, -8(%ebp)
  21.     movl    %eax, 4(%esp)
  22.     movl    $.LC0, (%esp)
  23.     call    scanf
  24.     movl    -8(%ebp), %eax
  25.     addl    $1, %eax
  26.     movl    %eax, -8(%ebp)
  27.     movl    %eax, 4(%esp)
  28.     movl    $.LC1, (%esp)
  29.     call    printf
  30.     addl    $36, %esp
  31.     xorl    %eax, %eax
  32.     popl    %ecx
  33.     popl    %ebp
  34.     leal    -4(%ecx), %esp
  35.     ret
  36.     .size   main, .-main
  37.     .ident  "GCC: (GNU) 4.2.1 (Debian 4.2.1-6)"
  38.     .section    .note.GNU-stack,"",@progbits
复制代码

编译选项是
gcc -S -O0 test.c
不过好像O4也是这个效果
发表于 2007-10-7 15:56:56 | 显示全部楼层
  1.         .file        "a2.c"
  2.         .section        .rodata
  3. .LC0:
  4.         .string        "%d"
  5. .LC1:
  6.         .string        "%d\n"
  7.         .text
  8. .globl main
  9.         .type        main, @function
  10. main:
  11.         leal        4(%esp), %ecx
  12.         andl        $-16, %esp
  13.         pushl        -4(%ecx)
  14.         pushl        %ebp
  15.         movl        %esp, %ebp
  16.         pushl        %ecx
  17.         subl        $36, %esp
  18.         movl        $0, -8(%ebp)
  19.         leal        -8(%ebp), %eax
  20.         movl        %eax, 4(%esp)
  21.         movl        $.LC0, (%esp)
  22.         call        scanf
  23.         movl        -8(%ebp), %eax
  24.         incl        %eax
  25.         movl        %eax, -8(%ebp)
  26.         movl        -8(%ebp), %eax
  27.         movl        %eax, 4(%esp)
  28.         movl        $.LC1, (%esp)
  29.         call        printf
  30.         movl        $0, %eax
  31.         addl        $36, %esp
  32.         popl        %ecx
  33.         popl        %ebp
  34.         leal        -4(%ecx), %esp
  35.         ret
  36.         .size        main, .-main
  37.         .ident        "GCC: (GNU) 4.1.2 (Gentoo 4.1.2)"
  38.         .section        .note.GNU-stack,"",@progbits
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-10-7 17:49:08 | 显示全部楼层
gcc 3.4生成了incl
gcc 4.1生成了addl
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-10-7 21:01:41 | 显示全部楼层
这是为什么,放着inc不用为什么用add呢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-10-7 21:08:14 | 显示全部楼层
2楼的gcc-4.1.2还是inc,但是我的gcc-4.1.3却是addl了:
  1.     .file   "test.c"
  2.     .section    .rodata.str1.1,"aMS",@progbits,1
  3. .LC0:
  4.     .string "%d"
  5. .LC1:
  6.     .string "%d\n"
  7.     .text
  8.     .p2align 4,,15
  9. .globl main
  10.     .type   main, @function
  11. main:
  12.     leal    4(%esp), %ecx
  13.     andl    $-16, %esp
  14.     pushl   -4(%ecx)
  15.     pushl   %ebp
  16.     movl    %esp, %ebp
  17.     pushl   %ecx
  18.     subl    $36, %esp
  19.     leal    -8(%ebp), %eax
  20.     movl    $0, -8(%ebp)
  21.     movl    %eax, 4(%esp)
  22.     movl    $.LC0, (%esp)
  23.     call    scanf
  24.     movl    -8(%ebp), %eax
  25.     addl    $1, %eax
  26.     movl    %eax, -8(%ebp)
  27.     movl    %eax, 4(%esp)
  28.     movl    $.LC1, (%esp)
  29.     call    printf
  30.     addl    $36, %esp
  31.     xorl    %eax, %eax
  32.     popl    %ecx
  33.     popl    %ebp
  34.     leal    -4(%ecx), %esp
  35.     ret
  36.     .size   main, .-main
  37.     .ident  "GCC: (GNU) 4.1.3 20070831 (prerelease) (Debian 4.1.2-16)"
  38.     .section    .note.GNU-stack,"",@progbits
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-10-8 08:53:45 | 显示全部楼层
查了一下,inc和add的指令长度和执行周期都是一样的,应该用那个都可以。
回复 支持 反对

使用道具 举报

发表于 2007-10-8 08:57:58 | 显示全部楼层
会不会是 gcc-4.1 开始考虑 CPU 流水线特性等问题了?

尽管单条指令的效率是可以比较的,但是在当前复杂的 CPU 流水线等特性下,究竟什么样的代码更快也许只有实验才可以得到结论
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-10-8 09:13:27 | 显示全部楼层
这个是在那里查到的呢?
如果这样的话inc指令不是没有用了?呵呵
Post by marvel
2楼的gcc-4.1.2还是inc,但是我的gcc-4.1.3却是addl了:

  1.     .file   "test.c"
  2.     .section    .rodata.str1.1,"aMS",@progbits,1
  3. .LC0:
  4.     .string "%d"
  5. .LC1:
  6.     .string "%d\n"
  7.     .text
  8.     .p2align 4,,15
  9. .globl main
  10.     .type   main, @function
  11. main:
  12.     leal    4(%esp), %ecx
  13.     andl    $-16, %esp
  14.     pushl   -4(%ecx)
  15.     pushl   %ebp
  16.     movl    %esp, %ebp
  17.     pushl   %ecx
  18.     subl    $36, %esp
  19.     leal    -8(%ebp), %eax
  20.     movl    $0, -8(%ebp)
  21.     movl    %eax, 4(%esp)
  22.     movl    $.LC0, (%esp)
  23.     call    scanf
  24.     movl    -8(%ebp), %eax
  25.     addl    $1, %eax
  26.     movl    %eax, -8(%ebp)
  27.     movl    %eax, 4(%esp)
  28.     movl    $.LC1, (%esp)
  29.     call    printf
  30.     addl    $36, %esp
  31.     xorl    %eax, %eax
  32.     popl    %ecx
  33.     popl    %ebp
  34.     leal    -4(%ecx), %esp
  35.     ret
  36.     .size   main, .-main
  37.     .ident  "GCC: (GNU) 4.1.3 20070831 (prerelease) (Debian 4.1.2-16)"
  38.     .section    .note.GNU-stack,"",@progbits
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-10-8 12:08:04 | 显示全部楼层
可以做一个测试。我的 gcc

  1. Using built-in specs.
  2. Target: i386-redhat-linux
  3. Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --host=i386-redhat-linux
  4. Thread model: posix
  5. gcc version 4.0.0 20050519 (Red Hat 4.0.0-8)
复制代码

在 -mtune=i386 的选项下产生的代码是 incl,而在 -mtune=pentium4 的选项下产生的代码是 addl
回复 支持 反对

使用道具 举报

发表于 2007-10-8 15:07:53 | 显示全部楼层
incl 指令不会改变进位标置, 但addl会
这一点在循环里或有很多加减法的上下文里很有用
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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