2015-04-21 13 views
6

volte recenti Sto avendo un aspetto in fase di montaggio IA32, ho fatto un semplice esempio giocattolo:

#include <stdio.h> 

int array[10]; 
int i = 0; 
int sum = 0; 

int main(void) 
{ 
    for (i = 0; i < 10; i++) 
    { 
     array[i] = i; 
     sum += array[i]; 
    } 

    printf("SUM = %d\n",sum); 
    return 0; 
} 

Sì, so che non è consigliabile usare le variabili globali. Ho compilato il codice di cui sopra, senza ottimizzazioni e utilizzando le -s bandiera, ho ricevuto questa assemblea:

main: 
     ... 
     movl $0, %eax 
     subl %eax, %esp 
     movl $0, i 
    .L2: 
     cmpl $9, i 
     jle .L5 
     jmp .L3 
    .L5: 
     movl i, %edx 
     movl i, %eax 
     movl %eax, array(,%edx,4) 
     movl i, %eax 
     movl array(,%eax,4), %eax 
     addl %eax, sum 
     incl i 
     jmp .L2 

Niente di stratosferico e facile da capire, si tratta di un normale ciclo while. Poi ho compilato lo stesso codice con -O2 ed ha ottenuto la seguente assemblea:

main: 
    ... 
    xorl %eax, %eax 
    movl $0, i 
    movl $1, %edx 
    .p2align 2,,3 
.L6: 
    movl sum, %ecx 
    addl %eax, %ecx 
    movl %eax, array-4(,%edx,4) 
    movl %edx, %eax 
    incl %edx 
    cmpl $9, %eax 
    movl %ecx, sum 
    movl %eax, i 
    jle .L6 
    subl $8, %esp 
    pushl %ecx 
    pushl $.LC0 
    call printf 
    xorl %eax, %eax 
    leave 
    ret 

In questo caso si trasforma in un fai mentre il tipo di ciclo. Dall'assemblea di cui sopra non riesco a capire perché "movl $ 1,% edx" e poi "movl% eax, array-4 (,% edx, 4)".

% edx inizia con 1 invece di 0 e quindi quando accede all'array fa -4 dalla posizione iniziale (4 byte = numero intero). Perché non semplicemente?

movl $0, %edx 
... 
array (,%edx,4) 

invece di iniziare con 1 se è necessario fare -4 tutto il tempo.

Sto usando "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-24)", per motivi didattici per generare assembly facilmente comprensibili.

+0

Il '-4' è gratuito (è fuso nello spostamento di' array'), quindi a chi importa? :) Dipende anche dal compilatore, il mio (Debian 4.7.2-5) non lo fa. Probabilmente dovresti specificare il numero di versione. – Jester

+1

: D forse sono troppo pignolo, ma mi sono solo incuriosito dalla logica dietro l'euristica usata lì. – dreamcrash

+3

Questa è una versione antica ... del 2003? Veramente? LOL. – Jester

risposta

1

Penso finalmente arrivare al punto, ho prova con:

...

int main(void) 
{ 
     for (i = 0; i < 10; i+=2) 
     { 
     ... 
     } 
} 

e ottenuto:

movl $2, %edx 

e con for (i = 0; i < 10; i + = 3) e ottenuto:

movl $3, %edx 

e infine con (i = 1; i < 10; i + = 3) e ottenuto:

movl $4, %edx 

Pertanto, il compilatore inizializzazione% edx = i (valore iniziale di i) + incrementStep;

Problemi correlati