2013-09-29 3 views
6

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ì.

+0

Qual è 'sizeof (long)' sulla vostra piattaforma? –

+0

@KerrekSB Ah OK. Vedo, mi dispiace. –

+0

sizeof (long) è 8 – mrip

risposta

8

ho capito che lo scopo di questo è semplicemente quello di impostare% eax a zero

Sì.

che in questo caso corrisponde al mio iteratore lungo i ;.

No. Il tuo i non è inizializzato nella dichiarazione. A rigor di termini, tale operazione corrisponde all'espressione i = 0 nel ciclo for.

Tuttavia, a meno che non mi sbaglio,% eax è un registro a 32 bit. Quindi mi sembra che questo dovrebbe effettivamente essere xorq% rax,% rax, in particolare dal momento che questo contiene un int lungo 64-bit.

Ma cancellare la parola doppia inferiore del registro cancella l'intero registro. Questo non è intuitivo, ma è implicito.

+1

Grazie. Ho pensato che fosse il caso, ma non sono riuscito a trovarlo documentato da nessuna parte. Come ho detto, sono un totale noob. – mrip

+1

Ho imparato qualcosa di nuovo oggi, non sapevo che la compensazione EAX avrebbe cancellato RAX. Tuttavia, mi chiedo se "cancellare la parola più bassa" sia il modo giusto per dirla, non è la dimensione della parola 64 bit su un'architettura AMD64? – us2012

+2

@ us2012 la normale definizione di "word size" viene semplicemente ignorata da Intel. Una parola è 16 bit, sempre. 32 = dword, 64 = qword. – harold

2

Proprio per rispondere alla seconda parte: .long mezzi 32 bit, e le due costanti integrale side-by-side formano la rappresentazione IEEE-754 della doppia 2.4:

Dec: 1073951539 858993459 
Hex: 0x40033333 0x33333333 

    400 3333333333333 
    S+E Mantissa 

L'esponente è compensata da 1023 , così l'esponente reale è 0x400   − =   1. il principale "uno" nella mantissa è implicito, quindi è 2   ×   0b1.001100110011 ... (si riconosce questa espansione periodica come 3/15, vale a dire 0,2. Abbastanza sicuro, 2   ×   1,2   =   2,4.)

+0

Aha. Grazie. Questo ha perfettamente senso. – mrip

+1

Um okay. Perché non presta attenzione al tipo di 'double', che è lungo 64 bit. +1. –

+1

@ H2CO3: hai capito bene, ma la dimensione dell'esponente dovrebbe averti dato la mancia :-) –