FB18 - Das Forum für Informatik

fb18.de / Diplom Informatik / Unterbereich Grundstudium / Technische Informatik

Ende eines guten Assemblerprogramms ?

Ende eines guten Assemblerprogramms ? 2005-12-17 16:52
Anonymer User
Wie endet ein Assemblerprog für die sparcs ?
Muss da ein Befehl à la: end: ta 0
folgen? Wenn ja, warum?

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 16:59
Anonymer User
+weitere Frage (tut mir leid, ich versteh Assembler einfach nicht(Sun Dokus finde ich nicht wirklich hilfreich))

Oft sehe die zwei aufeinander folgenden Befehle set und load in einer solchen Zusammenstellung:
set a, %r1 ld [%r1], %r2
aber warum - mit set wird a in register r1 gespeichert, warujm nochmal
aus r1 zu r2?

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 17:46
Fred
Wie endet ein Assemblerprog für die sparcs ?
Muss da ein Befehl à la: end: ta 0
folgen? Wenn ja, warum?
Über ta 0 wird ein Programm beendet, richtig.
Jeder Prozessor holt sich im Normalfall einen Befehl nach dem anderen aus dem Speicher und führt diese aus. Dass Dein Programm irgendwo aufhört steht ja nirgendwo im Speicher, also würde ohne das ta 0 irgendein Unsinn als Befehle interpretiert werden.

Oft sehe die zwei aufeinander folgenden Befehle set und load in einer solchen Zusammenstellung:
set a, %r1 ld [%r1], %r2 aber warum - mit set wird a in register r1 gespeichert, warujm nochmal aus r1 zu r2?
"set a, %r1" setzt das Register %r1 auf den Wert a.
"ld [%r1], %r2" lädt das Wort, welches an der Adresse steht, die in %r1 gespeichert ist, und speichert dieses geladene Wort in %r2.
Dieser "Umweg" ist notwendig, weil es bei Sparc Assembler keine Möglichkeit gibt, direkt aus einer 32-Bit-Adresse zu laden (gleiche Argumentation wie bei der Notwendigkeit von sethi/or für 32-Bit-Werte).

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 18:31
Anonymer User
Dieser "Umweg" ist notwendig, weil es bei Sparc Assembler keine Möglichkeit gibt, direkt aus einer 32-Bit-Adresse zu laden (gleiche Argumentation wie bei der Notwendigkeit von sethi/or für 32-Bit-Werte).

Eben das versteh ich nicht, weder hier noch bei sethi oder or.. [img]http://www.fb18.de/gfx/26.gif[/img]

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 18:38
Fred
Eine 32-Bit-Adresse ist 32 Bit breit. Soweit klar?

Wenn man also einen Befehlssatz baut, in welchem es möglich sein soll, eine Adresse direkt anzugeben, dann muss es Befehle geben, die grösser sind als 32 Bit (denn die Information, um was für einen Befehl es sich überhaupt handelt, muss ja auch irgendwie gespeichert werden). Beispiel intel: dort kann man einen 32-Bit-Wert direkt in ein Register laden, und man kann auch direkt aus einer 32-Bit-Adresse laden.

Die Sparc Architektur ist eine RISC-Architektur, in der JEDER Befehl 32 Bit breit ist. Es gibt nur sehr wenige Befehlsformate (siehe Sparc Heft aus der Übung, Seite 20). Wenn man schon einige Bits verbraucht um zu entscheiden, was für ein Befehl es überhaupt ist (Sprung? Addition? Subtraktion? etc.), dann bleiben eben nur noch weniger als 32 Bit für die Parameter übrig (um welche Register oder welche Immediate Werte handelt es sich?).

Von daher ist es nicht möglich, einen 32-Bit-Wert in einem Rutsch in ein Register zu laden.

Klar?

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 18:49
Anonymer User
deine Erläuterungen klingen grundsätzlich einleutend…
..,jedoch bei den schon erwähnten

set a, %r1 ld [%r1], %r2
wird doch r1 mit einem rutsch auf den wert a gesetzt
und das wort, das mit der adresse in r1 erreicht wird, wird auch mit einen rutsch in r2 gespeichert - wie stehen diese Befehle in relation, warum geht nicht set a, %r2 ?

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 18:51
UncleOwen
deine Erläuterungen klingen grundsätzlich einleutend…
..,jedoch bei den schon erwähnten

set a, %r1 ld [%r1], %r2
wird doch r1 mit einem rutsch auf den wert a gesetzt
set muesste ein Makro sein, sprich eigentlich sind das 2 Befehle.

und das wort, das mit der adresse in r1 erreicht wird, wird auch mit einen rutsch in r2 gespeichert
Dazu muss man ja auch nicht den Wert selber im Befehl codieren, sondern nur das Register - und das geht mit weit weniger Bits.

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 18:59
Fred
Nochmal eine tiefergehende Darstellung anhand des sethi-Befehls.

2 5 3 22 ------------------------------------- |op| rd |op2| imm22 | -------------------------------------
Nachdem der Prozessor sich diesen Befehl aus dem Speicher geholt hat, schaut er sich zunächst die beiden höchstwertigen Bits (op) an. Wenn diese 01 sind, dann handelt es sich um einen Call (hier nicht abgebildet). Wenn sie 10 oder 11 sind, dann handelt es sich um andere Befehle. Wenn sie 00 sind, dann handelt es sich um den sethi Befehl oder einen Sprungbefehl.

Um nun zwischen diesen beiden Möglichkeiten zu entscheiden gibt es die drei op2 Bits. Eine von den acht Kombinationen ist der sethi-Befehl (welche steht nicht im Buch und ist auch nicht relevant, ich vermute 000). Alle anderen sieben Kombinationen stellen verschiedene Sprungbefehle dar (hier nicht dargestellt).

Jetzt haben wir also bereits 2+3 = 5 Bits dafür "geopfert" um überhaupt zu sehen, um was für einen Befehl es sich handelt. Wir wissen aber noch nicht, in welchem Register der Wert überhaupt gespeichert werden soll. Da es 32 verschiedene Register gibt, müssen wir dafür weitere 5 Bits opfern (die fünf Bits zwischen op und op2) und haben damit bereits 10 Bits der insgesamt 32 belegt. Jetzt bleiben nur noch 22 Bit übrig, um den Immediate-Wert anzugeben.

Die Syntax des sethi-Befehls lautet:
sethi imm22, %rd

Die Semantik davon ist:
%rd = imm22 << 10

Auf deutsch: schiebe den Immediate-Wert um 10 Bit nach links und speichere das Ergebnis anschliessend in %rd

Wir können mit diesem Befehl also immerhin schon einmal 22 Bits in einem Register speichern und die unteren 10 Bits auf null setzen. Um jetzt noch die fehlenden eigentlichen unteren 10 Bits zu ergänzen verwenden wir einen gewöhnliche bitweise-oder-Verknüpfung.

Damit man die oberen 22 und unteren 10 Bit von einem 32-Bit-Wert nicht umständlich im Kopf oder auf Papier ausrechnen muss gibt es zwei nette Makros: %hi(imm32) liefert die oberen 22 Bit, %lo(imm32) liefert die unteren 10. Diese Makros werden vor der eigentlichen Übersetzung in die entsprechenden, eigentlichen Zahlen übersetzt.

sethi %hi(0x12345678), %rd
or %rd, %lo(0x12345678), %rd

ist also äquivalent zu

sethi 0x4d815, %rd
or %rd, 0x278, %rd

Wobei die erste Variante für den Menschen verständlicher ausdrückt, worum es überhaupt geht.

Noch Fragen, Kienzle?

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 19:07
Fred
deine Erläuterungen klingen grundsätzlich einleutend…
..,jedoch bei den schon erwähnten

set a, %r1
ld [%r1], %r2

wird doch r1 mit einem rutsch auf den wert a gesetzt
Nein. Wie Uncle Owen schon meinte ist set ein synthetischer Befehl/ein Makro, welcher vor der eigentlichen Übersetzung in die entsprechenden sethi/or Befehle aufgesplittet wird.

Aus "set a, %rd" wird also:

a) sethi %hi(a), %rd und anschliessend or %rd, %lo(a), %rd
falls sowohl in den oberen 22 Bits als auch in den unteren 10 Bits mindestens eine 1 auftaucht

b) sethi %hi(a), %rd
falls die unteren 10 Bits von a auf 0 gesetzt sind (dann ist ein zusätzliches or überflüssig)

c) or %g0, a, %rd
Wenn der Wert so klein ist, dass die oberen 20 (ja, 20 nicht 22!) Bit gleich sind.

warum geht nicht set a, %r2 ?
Das geht, bedeutet aber etwas anderes: speichere den Wert a in %r2. Du möchtest aber das Wort, welches an der Adresse a steht, in %r2 haben.

Eigentlich möchest Du also ld [a], %r2 stimmts? dieses Befehlsformat ist auf der Sparc aber wie gesagt nicht vorgesehen, mann kann nur aus Adressen laden, welche in einem Register stehen.

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 19:10
UncleOwen
Noch Fragen, Kienzle?

Ja, Hauser.

Nur zu meinem eigenen Verstaendnis:
set 0x12345678ist dann die Kurzform fuer
sethi %hi(0x12345678), %rd or %rd, %lo(0x12345678), %rd?

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 19:12
Fred
Wenn Du Dir Deinen Hauptspeicher als ein sehr grosses Array vorstellst:

unsigned char speicher[ 4294967296 ];

Und Deine Register als integer-Variablen:

int l0;
int l1;

Dann kann man sich die Assemblerbefehle folgendermassen vorstellen:

mov %l0, %l1
l1 = l0;

ld [%l0], %l1
l1 = speicher[l0];

Der Unterschied sollte einem klar sein.

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 19:16
Fred
set 0x12345678, %rd

ist dann die Kurzform fuer

sethi %hi(0x12345678), %rd
or %rd, %lo(0x12345678), %rd
?
Wenn man das von mir fett gedruckte noch einfügt: richtig!

Ein anderes Beispiel:
set 0xff000000, %rd

ist die Kurzform für:
sethi %hi(0xff000000), %rd

und zwar ohne ein zusätzliches or, weil die unteren 10 Bits 0 sind.

Und noch ein Beispiel:
set 4095, %rd

ist die Kurzform für:
or %g0, 4095, %rd

ohne ein vorhergehendes sethi, weil die Zahl klein genug ist (die oberen 20 Bit sind alle gleich, nämlich 0 in diesem Fall).

EDIT: Lustig, mein letzter Beitrag ist auf der Übersicht von 19:15 Uhr, hier steht allerdings 19:16 Uhr.

EDIT: vielleicht könnte ein Mod mal den Titel des Threads ändern? Dann finden andere sethi/or Verzweifler [img]http://www.fb18.de/gfx/25.gif[/img] vielleicht schneller Hilfe. Das "ta 0" hatten wir ja schnell abgehakt.

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 19:26
Anonymer User
klasse, thx [img]http://www.fb18.de/gfx/23.gif[/img]

Re: Ende eines guten Assemblerprogramms ? 2005-12-17 20:10
UncleOwen
Wenn man das von mir fett gedruckte noch einfügt:
oops, ja, natuerlich. Auch c&p will gelernt sein [img]http://www.fb18.de/gfx/7.gif[/img]