尝试修改gcc创建的*.s文件,发生了一些奇怪的事情
这是我的源代码a.c:尝试修改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; }
#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.out和a2.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
)。