Kann mir jemand helfen zu verstehen, stmdb, ldmia und wie ich gehen kann, über die Umsetzung dieser C++ - code in arm-Assembler?
Also ich habe dieses Stück code, wobei N die Größe der beiden arrays.
int i;
for (i = 0; i < N; i++)
{
if (listA[i] < listB[i])
{
listA[i] = listB[i];
}
}
Ich versuche, dies umzusetzen, als ARM Assembly Unterroutine, aber ich bin völlig verloren mit Umgang mit arrays. Ich habe diese so weit:
sort1:
stmdb sp!, {v1-v5, lr}
ldmia sp!, {v1-v5, pc}
Ich nehme an, ich muss mit cmp vergleichen Sie die Werte, aber ich bin mir auch nicht sicher, welche Register zu verwenden. Jemand eine Anleitung?
EDIT:
Okay ich habe jetzt diesen code:
sort1:
stmdb sp!, {v1-v5, lr} @ Copy registers to stack
ldr v1, [a1], #0 @ Load a1
str v1, [a2], #0 @ Copy elements of a1 to a2
ldmia sp!, {v1-v5, pc} @ Copy stack back into registers
Diese kopiert die ersten vier Elemente von einer 10-element-array, also würde ich davon ausgehen, wenn ich mich geändert "#0" bis "#4", würde es die nächsten vier Elemente zu ändern, aber es funktioniert nicht. Warum?
- "Ich bin nicht einmal sicher, was Register to use" Lesen Sie die ARM-Prozedur-Aufruf-standard-Dokumentation.
- Danke, das hilft schon etwas.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erstens, wie Sie gezeigt haben, die load/store-multiple-Instruktionen sind in Erster Linie nützlich für die stack-Operationen (obwohl Sie können auch eine effiziente
memcpy
). Einfach gesagt, Sie laden/speichern der angegebenen Register in der Reihenfolge vom/zu einem zusammenhängenden block von Speicher ausbase address
zubase address + (number of registers * 4)
.In dem Beispiel gegeben,
stmdb sp!, {v1-v5, lr}
ist die Speicherung von 6 Registern in der "Dekrementieren, Bevor" Adressierung Modus1, so ist die effektive Basis-Adresse istsp-24
- er speichert den Inhaltv1
beisp-24
,v2
beisp-20
,... bis zulr
beisp-4
. Da die!
syntax für base register writeback vorhanden ist, wird dann subtrahieren 24 vonsp
verlassen, deutete auf den gespeicherten Wert vonv1
. Dieldmia
ist die komplette reverse - "Increment After" heißt die effektive Basis-Adresse istsp
, so wird das laden der Register aussp
bis zusp+20
, fügen Sie dann 24 zusp
. Beachten Sie, dass es lädt die gestapeltenlr
Wert direkt in diepc
- auf diese Weise, die Sie wiederherstellen der Register und führen die Funktion in einer einzigen Instruktion.Als für die normalen load/store-Anweisungen, Sie haben 3 Adressierungsarten - offset, pre-indexed-und post-indexed.
ldr v1, [a1], #0
ist post-indiziert, was bedeutet "Lastv1
von der Adresse ina1
, fügen Sie dann 0, uma1
", daher ändern#0
zu#4
hat keinen Einfluss auf die Adresse verwendet, nur den geschriebenen Wert zurück an die Basis anmelden anschließend. Wenn du hättest, wie weit die Umsetzung der Schleife, dort wäre der Effekt bereits deutlich sichtbar.Kann es hilfreich sein, zu überlegen, wie einige Beispiel C-Ausdrücke Karte, um diese Adressierungsarten:
Beachten Sie den offset-Wert kann ein register statt einer unmittelbaren, zu, so gibt es mehrere Möglichkeiten zur Umsetzung einer Schleife wie die eine.
Für die maßgebende Referenz, würde ich empfehlen, mit dem Lesen der Instruktion Abschnitt der ARM Architecture Reference Manual, oder für eine weniger erschöpfend, sondern mehr zugängliche Einführung, die Cortex-A-Series Programmer ' s Guide.
[1] Dies impliziert einen absteigenden Stapel - entsprechende "Dekrement Nach" und "Inkrement Vor" Adressierung Modi vorhanden sind, die zum ausführen eines aufsteigenden Stapel.