编译器实现中x ++和++ x之间的区别

SIF*_*IFE 1 c compiler-construction gcc

我搜索了x ++ vs ++ x,我在这里找到了一个很好的答案,所以我决定看看gcc的汇编输出,看看x ++和++ x是如何实现的:

main(){int s = 0; ++ S; 返回0; }

编译示例:

gcc mul.c -masm = intel -o mul.asm

++ s的输出:

    .file   "mul.c"
    .intel_syntax
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
    lea %ecx, [%esp+4]
    and %esp, -16
    push    DWORD PTR [%ecx-4]
    push    %ebp
    mov %ebp, %esp
    push    %ecx
    sub %esp, 16
    mov DWORD PTR [%ebp-8], 0
    add DWORD PTR [%ebp-8], 1
    mov %eax, 0
    add %esp, 16
    pop %ecx
    pop %ebp
    lea %esp, [%ecx-4]
    ret
    .size   main, .-main
    .ident  "GCC: (GNU) 4.2.1 20070719  [FreeBSD]"      
Run Code Online (Sandbox Code Playgroud)

x ++的输出:

    .file   "mul.c"
    .intel_syntax
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
    lea %ecx, [%esp+4]
    and %esp, -16
    push    DWORD PTR [%ecx-4]
    push    %ebp
    mov %ebp, %esp
    push    %ecx
    sub %esp, 16
    mov DWORD PTR [%ebp-8], 0
    add DWORD PTR [%ebp-8], 1
    mov %eax, 0
    add %esp, 16
    pop %ecx
    pop %ebp
    lea %esp, [%ecx-4]
    ret
    .size   main, .-main
    .ident  "GCC: (GNU) 4.2.1 20070719  [FreeBSD]"
Run Code Online (Sandbox Code Playgroud)

那么,我问的是x ++和++ x是否有不同的含义,为什么GCC为它们输出一些组件,不应该有不同的输出?

Zet*_*eta 6

这是一个写得不好的测试用例的例子.表达式的实际结果value++++value永远不会存储,因此编译器可以处理基本类型的等效项.

请改用以下示例:

main() { int s = 0, x; x = ++s; return 0; }

main() { int s = 0, x; x = s++; return 0; }
Run Code Online (Sandbox Code Playgroud)

后递增:

(gdb) disas /m main
Dump of assembler code for function main():
1       int main(){
   0x0040138c :     push   %ebp
   0x0040138d :     mov    %esp,%ebp
   0x0040138f :     and    $0xfffffff0,%esp
   0x00401392 :     sub    $0x10,%esp
   0x00401395 :     call   0x4018d4 

2               int s = 0;
   0x0040139a :    movl   $0x0,0xc(%esp)

3               int x;
4               x = s++;
   0x004013a2 :    mov    0xc(%esp),%eax
   0x004013a6 :    mov    %eax,0x8(%esp)
   0x004013aa :    incl   0xc(%esp)

5               return 0;
   0x004013ae :    mov    $0x0,%eax

6       }   0x004013b3 :   leave
   0x004013b4 :    ret

End of assembler dump.
(gdb)

预增:

(gdb) disas /m main
Dump of assembler code for function main():
1       int main(){
   0x0040138c :     push   %ebp
   0x0040138d :     mov    %esp,%ebp
   0x0040138f :     and    $0xfffffff0,%esp
   0x00401392 :     sub    $0x10,%esp
   0x00401395 :     call   0x4018d4 

2               int s = 0;
   0x0040139a :    movl   $0x0,0xc(%esp)

3               int x;
4               x = ++s;
   0x004013a2 :    incl   0xc(%esp)
   0x004013a6 :    mov    0xc(%esp),%eax
   0x004013aa :    mov    %eax,0x8(%esp)

5               return 0;
   0x004013ae :    mov    $0x0,%eax

6       }   0x004013b3 :   leave
   0x004013b4 :    ret

End of assembler dump.
(gdb)