2015-04-21 5 views
6

Aktuelle ich mal einen Blick auf Montage IA32 habe, habe ich ein einfaches Spielzeug Beispiel:

#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; 
} 

Ja, ich weiß, dass es nicht sehr empfehlenswert ist, globale Variablen zu verwenden. Ich den obigen Code kompiliert ohne Optimierungen und die Flag -s verwenden, ich habe diese Versammlung:

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 

Nichts Besonderes und einfach zu verstehen, ist es eine normale while-Schleife. Dann kompiliert ich den gleichen Code mit -O2 und bekam die folgende Montage:

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 diesem Fall ist es in einem Do umgewandelt, während Art der Schleife. Von der oben genannten Baugruppe, was ich nicht verstehe, ist warum "Movl $ 1,% EDX" und dann "Movl% eax, Array-4 (,% EDX, 4)".

% edx beginnt mit 1 anstelle von 0 und dann beim Zugriff auf das Array -4 von der ursprünglichen Position (4 Bytes = ganze Zahl). Warum nicht einfach?

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

statt mit 1 zu beginnen, wenn Sie tun müssen, -4 ganze Zeit.

Ich verwende "GCC: (GNU) 3.2.3 20030502 (Red Hat Linux 3.2.3-24)", aus pädagogischen Gründen, um leicht verständliche Assembly zu generieren.

+0

Das '-4' ist frei (es ist in die Verschiebung von' Array' verschmolzen), also wen interessiert das? :) Kommt auch auf den Compiler an, meins (Debian 4.7.2-5) macht das nicht. Sie sollten wahrscheinlich die Versionsnummer angeben. – Jester

+1

: D vielleicht bin ich zu pingelig, aber ich bin nur neugierig geworden auf die Logik hinter der dort verwendeten Heuristik. – dreamcrash

+3

Das ist eine alte Version ... von 2003? "Ja wirklich?" LOL. – Jester

Antwort

1

Ich glaube, ich schließlich den Punkt, ich teste mit:

...

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

und bekam:

movl $2, %edx 

und mit for (i = 0; i < 10; i + = 3) und erhielt:

movl $3, %edx 

und schließlich mit (i = 1; i < 10; i + = 3) und erhielt:

movl $4, %edx 

Daher wird der Compiler initialisiert% EDX = i (Anfangswert von i) + incrementStep;

Verwandte Themen