Я нахожусь в полной нобе на собрании, просто немного заглядывая, чтобы понять, что происходит. Во всяком случае, я написал очень простую функцию:
void multA(double *x,long size)
{
long i;
for(i=0; i<size; ++i){
x[i] = 2.4*x[i];
}
}
Я скомпилировал его с помощью
gcc -S -m64 -O2 fun.c
И я получаю это:
.file "fun.c"
.text
.p2align 4,,15
.globl multA
.type multA, @function
multA:
.LFB34:
.cfi_startproc
testq %rsi, %rsi
jle .L1
movsd .LC0(%rip), %xmm1
xorl %eax, %eax
.p2align 4,,10
.p2align 3
.L3:
movsd (%rdi,%rax,8), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, (%rdi,%rax,8)
addq $1, %rax
cmpq %rsi, %rax
jne .L3
.L1:
rep
ret
.cfi_endproc
.LFE34:
.size multA, .-multA
.section .rodata.cst8,"aM",@progbits,8
.align 8
.LC0:
.long 858993459
.long 1073951539
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
Выход сборки имеет смысл для меня (в основном), за исключением строки xorl %eax, %eax
. Из googling я понимаю, что целью этого является просто установить %eax
в ноль, что в этом случае соответствует моему итератору long i;
.
Однако, если я не ошибаюсь, %eax
- это 32-разрядный регистр. Поэтому мне кажется, что на самом деле это должно быть xorq %rax, %rax
, особенно потому, что это поддерживает 64-битный длинный int. Более того, далее в коде он фактически использует 64-разрядный регистр %rax
для выполнения итерации, который никогда не инициализируется вне xorl %eax %eax
, который, по-видимому, только обнуляет нижние 32 бита регистра.
Я что-то пропустил?
Кроме того, из любопытства, почему существуют две константы .long
внизу? Первый, 858993459
равен двойному плавному представлению 2.4
, но я не могу понять, что такое второе число или почему оно есть.