Frage zu leal



  • Hallo zusammen,

    mir ist eben klar geworden, dass man mit leal auf konstanten auf ein Register addieren kann.

    z.B.: (AT&T-Syntax)

    movl $5 , %eax
    movl $4, %ebx
    leal (%eax, %ebx, 2), %ecx
    

    Jetzt ist im ecx Register der Wert 13. Nach einigem Ausprobieren habe ich folgendes herausgefunden: Obiger Ausdruck steht für %eax + 2 * %ebx. Doch wie wird das intern berechnet? Warum kann ich die 2 nicht durch eine 3 ersetzen? Und ist solch eine Berechnung wirklich schneller als mit addl und Shifts?

    Vielen Dank
    LG, freakC++



  • LEA kann genau das gleiche, was mit indirekter Adressierung möglich ist. Nur dass danach kein Zugriff auf diese Adresse passiert, sondern die Adresse in ein Register geladen wird. Ich stell mir das so vor, dass die Berechnung nicht von der allgemeinen ALU sondern vom Adressierungswerk vorgenommen wird, welches erstens darauf spezialisiert ist und zweitens parallel zur ALU arbeiten kann.



  • LEA soll bei Shifts um 2, 4 und 8 Bits schneller als SHL/SHR (486+) sein.
    LEA kann auch als Ersatz für ein "inc Register" verwendet werden.
    Besonders effektiv wird es jedoch wenn mehrere mathematische Operationen durch LEA ersetzt und kombiniert werden können.
    Es werden jedoch keine Flags im Flagregister verändert und unser Ergebniss muss eine gültige Adresse ergeben.

    Dirk



  • freecrac schrieb:

    LEA soll bei Shifts um 2, 4 und 8 Bits schneller als SHL/SHR (486+) sein.

    du meinst sicherlich left shifts um 1,2 oder 3 Bits

    freecrac schrieb:

    Es werden jedoch keine Flags im Flagregister verändert

    das ist sehr häufig der Grund, warum man es für Berechnungen zu verwenden.

    freecrac schrieb:

    unser Ergebniss muss eine gültige Adresse ergeben.

    muss es nicht, da kein Speicherzugriff erfolgt.


  • Mod

    freakC++ schrieb:

    Und ist solch eine Berechnung wirklich schneller als mit addl und Shifts?

    Das zu unpräzise gefragt.
    Bezogen auf die einzelne Instruktion ist das eine Frage nach der Latenz (Dauer zwischen Begin der Asuführung und Verfügbarkeit des Ergebnisses). Schon das kann etwas komplizierter sein, weil diese Latenz u.U. von weiteren Faktoren abhängt (z.B. besteht beim Atom eine zusätzliche Latenz von bis zu 2 Takten, wenn das Ergebnis einer Adressberechnung in einer Folgeanweisung für Arithmetische Berechnungen benötigt wird

    lea eax,[eax*3]
    add eax,eax // schlecht beim Atom
    

    , nicht aber wenn es für weitere Adressberechnungen/Speicherzugriffe benötigt wird). Zudem interessiert i.d.R. nicht, wie schnell eine einzelne Instruktion ausgeführt wird, sondern wie lange ein hinreichend langer und algortihmisch abgeschlossener Programmteil ausgeführt wird. Damit sind viele weitere Faktoren (wie z.B. Durchsatz, verwendet Ausführungseinheit, Dekodierungsgeschwindigkeit, Codegröße etc.) relevant.
    Wird das lea z.B. parallel zu einer anderen langsamen Instruktion ausgeführt, und muss im Anschluss sowieso auf diese langsame Instruktion gewartet werden, kommt es auf die Geschwindikeit des lea nicht mehr an.
    Als Faustregel empfielt Intel lea nicht zu verwenden, wenn komplexe Adressierung (base+skale+displacement) verwendet wird, weil das durch 2 µops codiert werden muss und im Endeffekt add+shl genauso schnell sein können. Beim Atom sollte lea verwendet werden, wenn es tatsächlich um eine Adressberechnung geht, oder das Ergebnis nicht sofort benötigt wird.
    lea hat noch andere Eigenschaften/Vorteile: die Tatsäche, dass Flags nicht beeinflusst werden, kann z.B. genutzt werden um die Berechnung der Abbruchbedingung einer Schleife möglichst weit weg vom bedingten Sprung platzieren zu können. Das ist nützlich, falls dieser Sprung schwer vorhersagtbar ist.



  • quasimodule schrieb:

    freecrac schrieb:

    LEA soll bei Shifts um 2, 4 und 8 Bits schneller als SHL/SHR (486+) sein.

    du meinst sicherlich left shifts um 1,2 oder 3 Bits

    Ja genau, so war es gemeint.

    http://en.wikibooks.org/wiki/X86_Disassembly/Code_Obfuscation

    The difference is that lea is quick (because it only adds a register and a small constant), whereas the add and mul instructions are more versatile, but slower. lea is used for arithmetic in this fashion very frequently, even when compilers are not actively optimizing the code.

    http://en.wikibooks.org/wiki/X86_Assembly/Data_Transfer

    lea can be used not only for calculating addresses, but also general-purpose unsigned integer arithmetic (with the caveat and possible advantage that FLAGS are unmodified). This can be quite powerful, since the src operand can take up to 4 parameters: base register, index register, scalar multiplier and displacement, e.g. [eax + edx*4 -4] (Intel syntax) or -4(%eax, %edx, 4) (GAS syntax). The scalar multiplier is limited to constant values 1, 2, 4, or 8 for byte, word, double word or quad word offsets respectively.

    http://www.fermi.mn.it/linux/quarta/x86/lea.htm

    (mit Liste aus dem INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986)

    Operand Size  Address Size  Action Performed
    
        16            16        16-bit effective address is calculated and
                                stored in requested 16-bit register
                                destination.
    
        16            32        32-bit effective address is calculated. The
                                lower 16 bits of the address are stored in
                                the requested 16-bit register destination.
    
        32            16        16-bit effective address is calculated. The
                                16-bit address is zero-extended and stored
                                in the requested 32-bit register destination.
    
        32            32        32-bit effective address is calculated and
                                stored in the requested 32-bit register
                                destination.
    

    freecrac schrieb:

    unser Ergebniss muss eine gültige Adresse ergeben.

    muss es nicht, da kein Speicherzugriff erfolgt.

    Für diese Adressberechnung ist zwar kein Speicherzugriff nötig, aber unsere effektive Adresse die sich daraus errechnen läßt, die muss ja in unser Zielregister auch hinein passen und dort kann deswegen auch keine ungültige Adresse hinein gebracht werden.

    Dirk


Anmelden zum Antworten