尝试修改gcc创建的*.s文件,发生了一些奇怪的事情

尝试修改gcc创建的*.s文件,发生了一些奇怪的事情,gcc,compiler-construction,stack,Gcc,Compiler Construction,Stack,这是我的源代码a.c: #include <stdio.h> #include <time.h> #define N 1000 int p[N] = {0}; int a[N] = {0}; void main(){ long int i; int acc; time_t t_start, t_end; for(i = 0; i < N; ++i){ a[i] = i; }

这是我的源代码a.c

#include <stdio.h>
#include <time.h>

#define N 1000 

int p[N] = {0};
int a[N] = {0};

void main(){
    long int i;
    int acc;
    time_t t_start, t_end;

    for(i = 0; i < N; ++i){
        a[i] = i;        
    }

    t_start = clock();

    acc = p[0] = a[0];
    for(i = 1; i < N; ++i){
        acc = acc + a[i];
        p[i] = acc;
    }

    t_end = clock();

    printf("%d\ntime: %f ms\n", p[N - 1], ((double)t_end - t_start) * 1000 / CLOCKS_PER_SEC);//output the result of p[999] and the execution time
    return;
}
    .file   "a.c"
    .globl  p
    .bss
    .align 32
    .type   p, @object
    .size   p, 4000
p:
    .zero   4000
    .globl  a
    .align 32
    .type   a, @object
    .size   a, 4000
a:
    .zero   4000
    .section    .rodata
.LC2:
    .string "%d\ntime: %f ms\n"
    .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    $32, %rsp
    movq    $0, -24(%rbp)
    jmp .L2
.L3:
    movq    -24(%rbp), %rax
    movl    %eax, %edx
    movq    -24(%rbp), %rax
    movl    %edx, a(,%rax,4)
    addq    $1, -24(%rbp)
.L2:
    cmpq    $999, -24(%rbp)
    jle .L3
    call    clock
    movq    %rax, -16(%rbp)
    movl    a(%rip), %eax
    movl    %eax, p(%rip)
    movl    p(%rip), %eax
    movl    %eax, -28(%rbp)
    movq    $1, -24(%rbp)
    jmp .L4
.L5:
    movq    -24(%rbp), %rax
    movl    a(,%rax,4), %eax
    addl    %eax, -28(%rbp)
    movq    -24(%rbp), %rax
    movl    -28(%rbp), %edx
    movl    %edx, p(,%rax,4)
    addq    $1, -24(%rbp)
.L4:
    cmpq    $999, -24(%rbp)
    jle .L5
    call    clock
    movq    %rax, -8(%rbp)
    cvtsi2sdq   -8(%rbp), %xmm0
    cvtsi2sdq   -16(%rbp), %xmm1
    subsd   %xmm1, %xmm0
    movsd   .LC0(%rip), %xmm1
    mulsd   %xmm1, %xmm0
    movsd   .LC1(%rip), %xmm1
    divsd   %xmm1, %xmm0
    movl    p+3996(%rip), %eax
    movl    %eax, %esi
    movl    $.LC2, %edi
    movl    $1, %eax
    call    printf
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .section    .rodata
    .align 8
.LC0:
    .long   0
    .long   1083129856
    .align 8
.LC1:
    .long   0
    .long   1093567616
    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits
.L5:
    movq    -24(%rbp), %rax
    movl    a(,%rax,4), %eax
    addl    %eax, -28(%rbp)
    movq    -24(%rbp), %rax
    movl    -28(%rbp), %edx
    movl    %edx, p(,%rax,4)
    addq    $1, -24(%rbp)
我注意到一些有趣的代码行是从.L5开始的:

#include <stdio.h>
#include <time.h>

#define N 1000 

int p[N] = {0};
int a[N] = {0};

void main(){
    long int i;
    int acc;
    time_t t_start, t_end;

    for(i = 0; i < N; ++i){
        a[i] = i;        
    }

    t_start = clock();

    acc = p[0] = a[0];
    for(i = 1; i < N; ++i){
        acc = acc + a[i];
        p[i] = acc;
    }

    t_end = clock();

    printf("%d\ntime: %f ms\n", p[N - 1], ((double)t_end - t_start) * 1000 / CLOCKS_PER_SEC);//output the result of p[999] and the execution time
    return;
}
    .file   "a.c"
    .globl  p
    .bss
    .align 32
    .type   p, @object
    .size   p, 4000
p:
    .zero   4000
    .globl  a
    .align 32
    .type   a, @object
    .size   a, 4000
a:
    .zero   4000
    .section    .rodata
.LC2:
    .string "%d\ntime: %f ms\n"
    .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    $32, %rsp
    movq    $0, -24(%rbp)
    jmp .L2
.L3:
    movq    -24(%rbp), %rax
    movl    %eax, %edx
    movq    -24(%rbp), %rax
    movl    %edx, a(,%rax,4)
    addq    $1, -24(%rbp)
.L2:
    cmpq    $999, -24(%rbp)
    jle .L3
    call    clock
    movq    %rax, -16(%rbp)
    movl    a(%rip), %eax
    movl    %eax, p(%rip)
    movl    p(%rip), %eax
    movl    %eax, -28(%rbp)
    movq    $1, -24(%rbp)
    jmp .L4
.L5:
    movq    -24(%rbp), %rax
    movl    a(,%rax,4), %eax
    addl    %eax, -28(%rbp)
    movq    -24(%rbp), %rax
    movl    -28(%rbp), %edx
    movl    %edx, p(,%rax,4)
    addq    $1, -24(%rbp)
.L4:
    cmpq    $999, -24(%rbp)
    jle .L5
    call    clock
    movq    %rax, -8(%rbp)
    cvtsi2sdq   -8(%rbp), %xmm0
    cvtsi2sdq   -16(%rbp), %xmm1
    subsd   %xmm1, %xmm0
    movsd   .LC0(%rip), %xmm1
    mulsd   %xmm1, %xmm0
    movsd   .LC1(%rip), %xmm1
    divsd   %xmm1, %xmm0
    movl    p+3996(%rip), %eax
    movl    %eax, %esi
    movl    $.LC2, %edi
    movl    $1, %eax
    call    printf
    nop
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .section    .rodata
    .align 8
.LC0:
    .long   0
    .long   1083129856
    .align 8
.LC1:
    .long   0
    .long   1093567616
    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits
.L5:
    movq    -24(%rbp), %rax
    movl    a(,%rax,4), %eax
    addl    %eax, -28(%rbp)
    movq    -24(%rbp), %rax
    movl    -28(%rbp), %edx
    movl    %edx, p(,%rax,4)
    addq    $1, -24(%rbp)
看起来-28(%rbp)是无用的

所以,我做了如下调整:

.L5:
    movq    -24(%rbp), %rax
    movl    a(,%rax,4), %eax
    addl    %eax, %edx
    movq    -24(%rbp), %rax
    movl    %edx, p(,%rax,4)
    addq    $1, -24(%rbp)    
我使用原始的a.s创建的a1.out,并使用修改后的a.s文件创建的a2.out

然后我执行了a1.outa2.out

让我惊讶的是,我得到了与p[999]完全不同的结果

我错过什么了吗


感谢您的帮助。

是-前面的一些说明:
movl%eax,-28(%rbp)
欢迎使用StackOverflow!您对您试图实现的目标有何评论?回答harper,先生,我只是试图通过减少存储/加载操作来实现更好的性能。回答Brett Hale,先生,似乎-28(%rbp)仅用于.L5循环,其唯一功能是存储%edx。由于我使用了
movl%edx,p(,%rax,4)
替换了
movl-28(%rbp),%edx
movl%edx,p(,%rax,4)
,这个指令
movl%eax,-28(%rbp)
似乎没有任何用处。与其花那么多时间分析程序集输出,不如让gcc优化一下?(
gcc-O2
甚至
gcc-O3
)。