867 Stimmen

Was ist der Zweck der LEA-Anweisung?

Für mich ist es einfach nur ein komisches MOV. Was ist sein Zweck und wann sollte ich es verwenden?

8 Stimmen

Siehe auch LEA auf Werte anwenden, die keine Adressen/Zeiger sind? : LEA ist nur ein Shift-and-Add-Befehl. Er wurde wahrscheinlich zum 8086 hinzugefügt, weil die Hardware bereits vorhanden ist, um Adressierungsmodi zu dekodieren und zu berechnen, nicht weil er nur für die Verwendung mit Adressen "gedacht" ist. Denken Sie daran, dass Zeiger in Assembler nur ganze Zahlen sind.

4voto

Alle normalen "Rechen"-Befehle wie Addieren, Multiplizieren, Exklusivieren oder Setzen der Statusflags wie Null, Vorzeichen. Wenn Sie eine komplizierte Adresse verwenden, AX xor:= mem[0x333 +BX + 8*CX] Die Flaggen werden entsprechend der xor-Operation gesetzt.

Nun möchten Sie die Adresse vielleicht mehrfach verwenden. Das Laden einer solchen Adresse in ein Register ist nie dazu gedacht, Statusflags zu setzen und tut es zum Glück auch nicht. Die Formulierung "effektive Adresse laden" macht den Programmierer darauf aufmerksam. Daher rührt auch der seltsame Ausdruck.

Es ist klar, dass der Prozessor, sobald er in der Lage ist, die komplizierte Adresse zu verwenden, um ihren Inhalt zu verarbeiten, auch in der Lage ist, sie für andere Zwecke zu berechnen. Sie kann nämlich zur Durchführung einer Transformation verwendet werden x <- 3*x+1 in einer einzigen Anweisung. Dies ist eine allgemeine Regel in der Assembler-Programmierung: Verwenden Sie die Anweisungen, wie es Ihnen gefällt. Das Einzige, was zählt, ist die Frage, ob die in der Anweisung verkörperte Transformation für Sie nützlich ist.

Unterm Strich

MOV, X| T| AX'| R| BX|

y

LEA, AX'| [BX]

haben die gleiche Wirkung auf AX aber nicht bei den Statuskennzeichen. (Dies ist ciasdis Notation).

1 Stimmen

"Dies ist eine allgemeine Regel in der Assembler-Programmierung: Verwende die Anweisungen so, wie es dir gerade in den Kram passt." Ich persönlich würde diesen Ratschlag nicht weitergeben, aufgrund von Dingen wie call lbl lbl: pop rax technisch "arbeiten", um den Wert von rip aber Sie werden die Vorhersage der Branche sehr unglücklich machen. Verwenden Sie die Anweisungen, wie Sie wollen, aber seien Sie nicht überrascht, wenn Sie etwas knifflig machen und es Konsequenzen hat, die Sie nicht vorhergesehen haben

1 Stimmen

@The6P4C Das ist ein nützlicher Vorbehalt. Wenn es jedoch keine andere Möglichkeit gibt, die Zweigvorhersage unglücklich zu machen, muss man sich darauf einlassen. Es gibt eine weitere allgemeine Regel in der Assembler-Programmierung. Es kann alternative Wege geben, etwas zu tun, und man muss weise aus den Alternativen wählen. Es gibt hunderte von Möglichkeiten, den Inhalt des Registers BL in das Register AL zu bekommen. Wenn der Rest von RAX nicht erhalten werden muss, kann LEA eine Option sein. Die Flags nicht zu beeinträchtigen, kann bei einigen der tausenden von x86-Prozessoren eine gute Idee sein. Groetjes Albert

2voto

tzoz Punkte 41

Verzeihen Sie mir, wenn es bereits jemand erwähnt hat, aber falls sich jemand über die schlechten alten Tage von x86 wundert, als die Speichersegmentierung noch relevant war: Sie werden immer die gleichen Ergebnisse mit diesen beiden Anweisungen erhalten:

LEA AX, DS:[0x1234]

y

LEA AX, CS:[0x1234]

Die "effektive Adresse" ist nur der Offset-Teil der logischen Adresse seg:off. In diesem Fall: 0x1234.

LEA tut pas fügen Sie die Segmentbasis hinzu. Das würde einen der ursprünglichen Anwendungsfälle zunichte machen, nämlich die Adressberechnung, um einen Zeiger (Offset) zu erhalten, den man tatsächlich derefenzieren kann. Wie zum Beispiel lea bx, [array + si] . Wenn diese DS-Basis hinzugefügt wird, um eine lineare Adresse zu erhalten, kann eine spätere mov ax, [bx] würde die DS-Basis hinzufügen wieder .
Außerdem würde das 20-Bit-Ergebnis oft nicht in ein 16-Bit-Register passen.

Voir https://www.stevemorse.org/8086/index.html - der Architekt des 8086 hat ein Buch über den Befehlssatz geschrieben, das jetzt kostenlos auf seiner Website zu finden ist. Im Abschnitt über LEA werden einige seiner Designabsichten erwähnt.

3 Stimmen

Die "effektive Adresse" ist nur der "Offset"-Teil einer seg:off Paar. LEA wird nicht von der Segmentbasis beeinflusst; beide Anweisungen setzen (ineffizienterweise) 0x1234 in AX. x86 hat leider keine einfache Möglichkeit, eine volle lineare Adresse (effektiv + Segmentbasis) in ein Register oder Registerpaar zu berechnen.

1 Stimmen

@PeterCordes Sehr nützlich, danke für die Richtigstellung.

1 Stimmen

Da dieser Beitrag vorher falsch war und nie gelöscht wurde (und trotzdem 2 "upvotes" hatte), habe ich ihn umgeschrieben, um das Gegenteil über dieses Beispiel zu sagen und zu erklären, warum. Vielleicht veranschaulicht es jetzt sogar einen der Zwecke von LEA.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X