Was ist der eigentliche Zweck und die Verwendung der EDI- und ESI-Register im Assembler?
Ich weiß, dass sie zum einen für String-Operationen verwendet werden.
Kann jemand auch ein Beispiel geben?
Was ist der eigentliche Zweck und die Verwendung der EDI- und ESI-Register im Assembler?
Ich weiß, dass sie zum einen für String-Operationen verwendet werden.
Kann jemand auch ein Beispiel geben?
Antworten:
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.
SI
= Quellindex
DI
= Zielindex
Wie andere angegeben haben, haben sie spezielle Verwendungszwecke mit den Zeichenfolgenanweisungen. Für die Real-Mode-Programmierung muss das ES
Segmentregister mit DI
und DS
mit SI
wie in verwendet werden
movsb es:di, ds:si
SI und DI können auch als Allzweckindexregister verwendet werden. Zum Beispiel der C
Quellcode
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+12
enthält argv
, ebx
ist j
und edi
hat srcidx
. Beachten Sie, dass der dritte Befehl edi
multipliziert mit 4 verwendet und einen ebp
Versatz von 0x54 (die Position von srcp
) hinzufügt . Klammern um die Adresse zeigen die Indirektion an.
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.
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!
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.
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.