Zweck von ESI & EDI Registern?


Antworten:


77

Es gibt einige Operationen, die Sie nur mit DI / SI ausführen können (oder deren erweiterten Gegenstücken, wenn Sie 1985 kein ASM gelernt haben). Unter diesen sind

REP STOSB
REP MOVSB
REP SCASB

Dies sind Operationen zum wiederholten (= Massen-) Speichern, Laden und Scannen. Was Sie tun, ist, SI und / oder DI so einzurichten, dass sie auf einen oder beide Operanden zeigen, vielleicht eine Zählung in CX eingeben und dann rippen lassen. Dies sind Vorgänge, die mit einer Reihe von Bytes gleichzeitig arbeiten und die CPU automatisch aktivieren. Da Sie Schleifen nicht explizit codieren, erledigen sie ihre Sache (normalerweise) effizienter als eine handcodierte Schleife.

Nur für den Fall, dass Sie sich fragen: Je nachdem, wie Sie den Vorgang eingerichtet haben, kann das wiederholte Speichern so einfach sein, dass Sie den Wert 0 in einen großen zusammenhängenden Speicherblock eingeben. Ich denke, MOVSB ​​wird verwendet, um Daten von einem Puffer (also einer beliebigen Anzahl von Bytes) in einen anderen zu kopieren. und SCASB wird verwendet, um nach einem Byte zu suchen, das einem Suchkriterium entspricht (ich bin nicht sicher, ob es nur nach Gleichheit sucht oder was - Sie können es nachschlagen :))

Das ist das meiste, wofür diese Regs sind.


7
Optimierungstipp aus der Vergangenheit: rep stosw ist viel schneller als rep stosb . Wenn also das Kopieren von zwei und zwei Bytes zu dem passt, was Sie versuchen, verwenden Sie dies stattdessen in Ihrem handoptimierten 16-Bit-x86-Assemblycode ...
Alexander

88

SI= Quellindex
DI= Zielindex

Wie andere angegeben haben, haben sie spezielle Verwendungszwecke mit den Zeichenfolgenanweisungen. Für die Real-Mode-Programmierung muss das ESSegmentregister mit DIund DSmit SIwie in verwendet werden

movsb  es:di, ds:si

SI und DI können auch als Allzweckindexregister verwendet werden. Zum Beispiel der CQuellcode

srcp [srcidx++] = argv [j];

kompiliert in

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

wo ebp+12enthält argv, ebxist jund edihat srcidx. Beachten Sie, dass der dritte Befehl edimultipliziert mit 4 verwendet und einen ebpVersatz von 0x54 (die Position von srcp) hinzufügt . Klammern um die Adresse zeigen die Indirektion an.


Ich kann mich zwar nicht erinnern, wo ich es gesehen habe, aber dies bestätigt das meiste davon und dies (Folie 17) andere:

AX= Akkumulator
DX= Doppelwortakkumulator
CX= Zähler
BX= Basisregister

Sie sehen aus wie Allzweckregister, aber es gibt eine Reihe von Anweisungen, die (unerwartet?) Eine von ihnen - aber welche? - implizit verwenden.


37

Opcodes wie MOVSB ​​und MOVSW, die Daten aus dem von ESI angegebenen Speicher effizient in den von EDI angegebenen Speicher kopieren. So,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

12

Zusätzlich zu den in den anderen Antworten erwähnten Zeichenfolgenoperationen (MOVS / INS / STOS / CMPS / SCASB / W / D / Q usw.) wollte ich hinzufügen, dass es auch "modernere" x86-Montageanweisungen gibt, die implizit bei verwendet werden mindestens EDI / RDI:

Der Befehl SSE2 MASKMOVDQU(und der kommende AVX VMASKMOVDQU) schreiben selektiv Bytes aus einem XMM-Register in den Speicher, auf den EDI / RDI zeigt.


6

Zusätzlich zu den Registern, die für Massenoperationen verwendet werden, sind sie nützlich für ihre Eigenschaft, durch einen Funktionsaufruf (aufruferhalten) in einer 32-Bit-Aufrufkonvention erhalten zu werden. ESI, EDI, EBX, EBP, ESP bleiben anruferhalten, während EAX, ECX und EDX nicht anruferhalten sind. Aufruferhaltene Register werden von der C-Bibliotheksfunktion respektiert und ihre Werte bleiben während der C-Bibliotheksfunktionsaufrufe erhalten.

Jeff Duntemann hat in seinem Assembler-Buch einen Beispiel-Assembler-Code zum Drucken der Befehlszeilenargumente. Der Code verwendet esi und edi, um Zähler zu speichern, da diese von der C-Bibliotheksfunktion printf unverändert bleiben. Für andere Register wie eax, ecx, edx gibt es keine Garantie dafür, dass sie nicht von den Funktionen der C-Bibliothek verwendet werden.

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

Siehe Abschnitt 12.8 Wie C Befehlszeilenargumente sieht.

Beachten Sie, dass sich 64-Bit-Aufrufkonventionen von 32-Bit-Aufrufkonventionen unterscheiden und ich nicht sicher bin, ob diese Register aufruferhalten sind oder nicht.


Ich habe noch nie gehört, dass "heilig" verwendet wird, um zu beschreiben, was die meisten Leute als "flüchtig" / "nicht flüchtig" oder "von Angerufenen gerettet" oder "von Anrufen gerettet" bezeichnen. Ich mag "anruferhalten" / "anrufüberwacht", da dies nicht bedeutet, dass sie tatsächlich irgendwo gespeichert werden. Auf jeden Fall werden ESI / RSI und EDI / RDI im x86-64 System V ABI nicht aufgerufen.
Peter Cordes

Außerdem haben Sie vergessen, EBP und ESP in den allgemeinen 32-Bit-Aufrufkonventionen als aufruferhalten aufzulisten.
Peter Cordes

1
Jedenfalls ist das ein ziemlich guter Punkt. Im eigentlichen Code entscheiden Sie sich eher für EDI / ESI aus Gründen der Aufrufkonvention als dafür, dass sie für Anweisungen speziell sind.
Peter Cordes

Ich mag Anrufe erhalten. Ich habe die Antwort mit der gleichen aktualisiert. Danke für die Bewertung.
Jay Rajput
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.