Sono un noob totale al momento dell'assemblaggio, cerco solo di capire cosa sta succedendo. In ogni caso, ho scritto una funzione molto semplice:xorl% eax,% eax nel codice assembly x86_64 prodotto da gcc
void multA(double *x,long size)
{
long i;
for(i=0; i<size; ++i){
x[i] = 2.4*x[i];
}
}
ho compilato con:
gcc -S -m64 -O2 fun.c
E ottengo questo:
.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
L'uscita assemblea ha senso per me (per lo più) fatta eccezione per la linea xorl %eax, %eax
. Da google, ritengo che lo scopo di questo è semplicemente quello di impostare %eax
su zero, che in questo caso corrisponde al mio iteratore long i;
.
Tuttavia, a meno che non mi sbaglio, %eax
è un registro a 32 bit. Quindi mi sembra che questo dovrebbe essere in realtà xorq %rax, %rax
, soprattutto perché questo contiene un int lungo 64-bit. Inoltre, più avanti nel codice, utilizza effettivamente il registro a 64 bit %rax
per eseguire l'iterazione, che non viene mai inizializzato al di fuori di xorl %eax %eax
, che sembrerebbe azzerare solo i 32 bit inferiori del registro.
Mi manca qualcosa?
Inoltre, per curiosità, perché ci sono due costanti .long
nella parte inferiore? Il primo, 858993459
equivale alla doppia rappresentazione in virgola mobile di 2.4
ma non riesco a capire quale sia il secondo numero o perché sia lì.
Qual è 'sizeof (long)' sulla vostra piattaforma? –
@KerrekSB Ah OK. Vedo, mi dispiace. –
sizeof (long) è 8 – mrip