Wie werden Daten in einer Assemblersprache mithilfe des Befehlssatzes zugewiesen?

Betrachten Sie den folgenden Auszug aus Assembler-Code, der für die Nios II-Embedded-Prozessorarchitektur geschrieben wurde :

    .section .data
    .align 2
va:   .long 0x0
vb:   .long 0x11223344
vc:   .long 0x55667788

Folgendes muss getan werden:

  • Ordnen Sie allen drei Variablen genügend Speicher zu
  • Stellen Sie sicher, dass der zugewiesene Speicher zusammenhängend ist
  • Übersetzen Sie Anweisungen, die den Namen einer Variablen verwenden, in Anweisungen, die die Adresse der Variablen verwenden

Ich sehe nicht, wie dies über den Befehlssatz erfolgen kann, und hoffte auf einen Einblick, wie die Übersetzung des obigen Codes in den Befehlssatz erfolgt.

Der Linker führt die ersten beiden Elemente nicht aus.
@IgnacioVazquez-Abrams Wäre das die Aufgabe des Monteurs?
Nein. Es ist niemandes Aufgabe. Assembler-Direktiven weisen keinen Speicher zu, und der Speicher muss unabhängig davon nicht zusammenhängend sein.
@IgnacioVazquez-Abrams Was meinst du mit "Assembler-Direktiven weisen keinen Speicher zu"? Ich dachte, der gesamte Sinn des obigen Codes bestand darin, Speicher zuzuweisen. Zweitens wurde mir beigebracht, dass Speicher zusammenhängend zugewiesen wird.
Das ist nicht ganz richtig. Diese Anweisungen besagen, dass beliebige Bytes an den aktuellen und folgenden Speicherorten zu platzieren sind; Die "Zuweisung" erfolgt, weil der Assembly weitere Bytes hinzugefügt wurden, nicht weil diese Anweisungen verwendet werden.
Was das Thema "zusammenhängend" betrifft, so gibt zwar jede Direktive einen zusammenhängenden Speicherblock an, es besteht jedoch keine Notwendigkeit, dass der Speicher über alle Direktiven hinweg zusammenhängend ist.

Antworten (2)

Dies ist die Zuweisung des Speichers und hat nichts mit dem Befehlssatz zu tun. Assembler sind unglaublich einfach - die Zeilen in der Assemblerdatei entsprechen fast genau der ausgegebenen Binärdatei, es wird nur sehr wenig neu angeordnet. Die Zeile „.long 0x0“ bedeutet einfach „Gib mir hier vier Bytes und lade sie mit dem Wert 0x0“. Die Daten werden auf dieselbe Weise „zugewiesen“ wie Anweisungen. Eine Zeile „MOV R12, R11“ bedeutet nur „Gib mir hier vier Bytes und lade sie mit der binären Codierung für MOV R12, R11“. Die Daten sind aus dem gleichen Grund zusammenhängend, aus dem Ihre Anweisungen zusammenhängend sind – Sie haben sie in zusammenhängenden Zeilen in der Assemblydatei eingegeben. Das "va:" bedeutet einfach "nennen Sie die Position dieser vier Bytes "va"". Dies wird nur innerhalb des Assemblers verwendet. Wo immer Sie auf 'va' verweisen In den Code fügt der Assembler die Adresse der vier Datenbytes ein, auf die sich 'va' bezieht, was nur eine Zahl ist. Beachten Sie, dass dies möglicherweise nicht vom Assembler, sondern vom Linker ausgeführt wird. Die Zeichenfolge „va“ wird jedoch niemals in der Ausgabebinärdatei erscheinen.

Im Grunde genommen ist die Assemblierung fast eine direkte Darstellung des Speicherinhalts. Aufeinanderfolgende Montagelinien werden in aufeinanderfolgenden Adressen enden. Die einzige Ausnahme ist, wenn Sie Abschnitte ändern (.section). Alle Daten, die sich explizit im Code befinden, sind zusammenhängend, wenn sie in der Assemblydatei zusammenhängend sind. Nun, Abschnitte schrauben ein wenig damit herum. Es ist möglich, dass alle .data in einem Teil des Speichers landen und alle .text in einem anderen Teil. Die Blöcke werden jedoch nicht aufgeteilt – wenn sie in der Assembly-Datei zusammenhängend sind, dann werden sie auch in der Ausgabe zusammenhängend sein.

Solche Daten werden nicht auf die gleiche Weise "zugeordnet".

Wenn Sie ein Programm ausführen, wird dieses Programm in den Speicher geladen. Wenn dieses Programm irgendwo 0x000000001122334455667788 enthält, dann enthalten diese Speicherorte (insgesamt 12, es sei denn, ich habe mich falsch gezählt) diese Werte. Wenn Sie Ihren Code kompilieren, werden alle NAMEN in Speicheradressen übersetzt. Von da an werden keine Anweisungen mehr ausgeführt, um dies zu erreichen - der Speicher ist da, er wird "zugewiesen" (genügend Speicher wird zugewiesen, um das gesamte Programm zu speichern, statische Variablen wie diese und alles), und weil das gesamte Programm platziert wird in diesem Speicher werden die Variablen initialisiert.

Wenn Sie dann sagen "Variable va in Register 'X' laden", erhält der kompilierte Code (der besagt "Adresse 0x84573412 in Register 'X' laden") das richtige Datenbit.

Die Namen der Variablen dienen nur der Bequemlichkeit – ansonsten müssten Sie selbst bestimmte Adressen zuweisen.