为什么X86_64 GCC编译器需要先进行算术运算?

时间:2019-05-12 08:27:14

标签: c gcc x86-64

当我尝试编译并执行以下代码时

#include <stdio.h>

int main()
{
    int a = 5;
    printf("%d %d",--a,++a);
    return 0;
}

我得到的输出是5 5

根据一般理解,输出应为5 6。所以我在编译器中有一个可疑之处,并使用以下命令生成了程序集

gcc -S <my program>

当我分析装配时,发现我的嫌疑犯是正确的。请参见下面的汇编代码。

    .file   "inc_dec.c"
    .section    .rodata
.LC0:
    .string "%d %d"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $5, -4(%rbp)
    addl    $1, -4(%rbp)
    subl    $1, -4(%rbp)
    movl    -4(%rbp), %edx
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
    .section    .note.GNU-stack,"",@progbits

编译器的实际作用是。首先将value(5)推送到寄存器地址(rbp-4)。然后,它先执行减法和加法指令,然后将值作为参数推入printf。所有这些之后,它称为printf。

因此,变量a变为5,递增时变为6,递减时变为5,然后为printf的两个参数推送a的值。 因此,产生的是5 5而不是6 55 6

即使我尝试通过-o0禁用优化,并将变量命名为volatile。结果还是一样。

我的问题是为什么会这样发生?如何避免这种情况?

0 个答案:

没有答案