fb18.de
/ Bachelorstudieng
/ PM Technische Informatik
RS: Beispielaufgaben Assemblerprogramme lesen
Hallo, wie im Tutorium versprochen, hier einmal das Dienstag besprochene Programm sowie ein zweiteres. Die Aufgabe lautet bei beiden "Was tut es?", was gewünscht wurde da das wohl auch gerne in den Klausuren gemacht wird. Wer will, kann sich gerne mal versuchen dranzusetzen und herausfinden, was die beiden machen. Fragen etc. natürlich gerne hier, ich rate allen, die es versuchen, erstmal soviel wie möglich herauszufinden, bevor ihr hier reinguckt und potentiell große Häppchen der Lösung seht [25]
Beispielprogramm aus dem Tutorium
.global printf
.global main
.section ".rodata"
outstr: .asciz "%d\n"
.section ".text"
main:
save %sp, -64, %sp
mov 1, %l0
mov 100, %l1
.loop:
call f
or %l0, %g0, %o0
mov %o0, %o1
sethi %hi(outstr), %o0
call printf
or %o0, %lo(outstr), %o0
subcc %l1, %l0, %g0
bne .loop
add %l0, 1, %l0
ret
restore
f:
save %sp, -64, %sp
subcc %i0, 1, %g0
be .L1
nop
subcc %i0, 2, %g0
be .L1
nop
.L2:
call f
sub %i0, 1, %o0
mov %o0, %l0
call f
sub %i0, 2, %o0
mov %o0, %l1
ba .L3
add %l0, %l1, %i0
.L1:
mov 1, %i0
.L3:
ret
restore
Zweites Übungsprogramm
.global printf
.global main
.section ".rodata"
output: .asciz "%d\n"
.section ".text"
main: save %sp, -64, %sp
mov 100, %l1
mov 2, %l0
.loop: call p
mov %l0, %o0
subcc %o0, 0, %o0
be .jump
nop
sethi %hi(output), %o0
add %l0, 0, %o1
call printf
or %o0, %lo(output), %o0
.jump: cmp %l0, %l1
bne .loop
add %l0, 1, %l0
ret
restore
p: save %sp, -64, %sp
subcc %i0, 2, %g0
be .done2
nop
wr %g0, %g0, %y
nop
nop
nop
or %g0, 2, %l0
sub %i0, 1, %l3
.ploop: udiv %i0, %l0, %l1
umul %l1, %l0, %l2
subcc %l2, %i0, %g0
be .done1
nop
subcc %l0, %l3, %g0
blu .ploop
add %l0, 1, %l0
ba .done2
mov 1, %i0
.done1: mov 0, %i0
.done2: ret
restore
Statt
main:
save %sp, -64, %sp
blahfaselfoobar
ret
restore
verwendet Lehmann ganz gerne
main:
blahfaselfoobar
mov 1, %g1
ta 0
Also davon nicht verwirren lassen.
Hm, also meine erste oberflächliche Analyse ergibt, dass die Labels "f" und "p" recht sprechend gewählt sind… [28]
Kurze Frage: Sind die Assembleraufgaben in der Klausur auch so lang? Oder ist in der Klausur nur ein kleiner Ausschnitt? Kommt mir sonst so vor, als würde man ziemlich unter Zeitdruck stehen…
Kurze Frage: Sind die Assembleraufgaben in der Klausur auch so lang? Oder ist in der Klausur nur ein kleiner Ausschnitt? Kommt mir sonst so vor, als würde man ziemlich unter Zeitdruck stehen…
mh, doch. letztes jahr hatten wir ungefähr eine seite code. wir sollten den wert der am ende in einem bestimmten register oder so war ausgeben.
es ging ganz gut & fix, wenn man an jede zeile kurz geschrieben hat was sich gerade geändert hat.
letztes jahr hatten wir ungefähr eine seite code.
Kamen da auch Unterprogrammaufrufe vor? Und Rekursion?
letztes jahr hatten wir ungefähr eine seite code.
Kamen da auch Unterprogrammaufrufe vor? Und Rekursion?
das weiss ich nicht mehr so genau. aber man hatte konkrete werte für die man das ganze durchgehen konnte. als antwort kam also sowas wie 'in register xy steht 25' und nicht 'in register xy steht das produkt der zahlen aus register a und b'. man musste nicht verstehen warum ein befehl da so steht und nicht anders, sondern einfach ein bischen so tun als wär man ein prozessor.
Hier zwei Programme von mir zum Reverse-Engineering. Was passiert da?
.section ".rodata"
.align 4
ausgabe: .asciz "(%d, %d) -> %d\n"
.section ".text"
.align 4
.global main
machwas:
save %sp, -128, %sp
mov %i0, %o1
mov %i1, %o2
schleife:
cmp %i1, %i0
be fertig
nop
bcc ok
mov %i0, %l7
mov %i1, %i0
mov %l7, %i1
ok:
ba schleife
subcc %i1, %i0, %i1
fertig:
set ausgabe, %o0
call printf
mov %i0, %o3
ret
restore
main:
mov 24, %o0
call machwas
mov 32, %o1
mov 80, %o0
call machwas
mov 70, %o1
mov 55, %o0
call machwas
mov 33, %o1
mov 97, %o0
call machwas
mov 13, %o1
mov 1, %g1
ta 0
.section ".rodata"
.align 4
ausgabe: .asciz "ungerade (%d)\n"
.section ".text"
.align 4
.global main
machwas:
save %sp, -128, %sp
sethi %hi(ausgabe+2), %o0
and %i0, 1, %o1
or %o0, %lo(ausgabe+2), %o0
sll %o1, 1, %l0
call printf
sub %o0, %l0, %o0
ret
restore
main:
call machwas
mov 7, %o0
call machwas
mov 10, %o0
call machwas
mov 12, %o0
call machwas
mov 17, %o0
call machwas
mov 1024, %o0
mov 1, %g1
ta 0
Viel Spaß damit [23]
Ich werde noch drei Beispiele posten: ein unverzweigendes Unterprogramm, ein iteratives und ein rekursives.
Hier das unverzweigende:
.section ".rodata"
.align 4
ausgabe: .asciz "%d -> %d\n"
.section ".text"
.align 4
.global main
machwas:
save %sp, -128, %sp
sethi %hi(1431655766), %l7
sethi %hi(ausgabe), %o0
or %l7, %lo(1431655766), %l7
or %o0, %lo(ausgabe), %o0
umul %i0, %l7, %g0
mov %i0, %o1
call printf
rd %y, %o2
ret
restore
main:
call machwas
mov 10, %o0
call machwas
mov 100, %o0
call machwas
mov 1000, %o0
call machwas
mov 600, %o0
call machwas
mov 601, %o0
call machwas
mov 602, %o0
call machwas
mov 603, %o0
mov 1, %g1
ta 0
Falls ihr den Sinn der Konstanten 1431655766 nicht versteht, dann schaut Euch einfach mal die Ausgabe des Programms an. Dann sollte es klar sein.
Bis jetzt kam ja nicht viel Feedback zu den Aufgaben. Bringen die nix, oder ist einfach alles klar und logisch?
Hier noch ein bischen Iteration und Speicherzugriff:
.section ".rodata"
.align 4
test: .word 1000000000, 0, 1, -1, 1023, 1024, 15, 30, 123456789, 1234567890, 65535, 65536
ausgabe: .asciz "%8x -> %2d\n"
anzahl = (ausgabe-test)/4
.section ".text"
.align 4
.global main
machwas:
save %sp, -128, %sp
mov %i0, %o1
srl %i0, 1, %i0
xor %o2, %o2, %o2
schleife:
orcc %i0, %g0, %i0
add %o2, 1, %o2
bne schleife
srl %i0, 1, %i0
sethi %hi(ausgabe), %o0
call printf
or %o0, %lo(ausgabe), %o0
ret
restore
main:
set test, %l0
mov anzahl, %l1
ml:
call machwas
ld [%l0], %o0
subcc %l1, 1, %l1
bne ml
add %l0, 4, %l0
mov 1, %g1
ta 0
Die Zeile "anzahl = (ausgabe-test)/4" definiert ein Makro namens anzahl, das sich aus der Differenz der beiden angegebenen Speicheradressen (gezählt in Byte) berechnet. Wir teilen noch durch 4, weil jedes Wort vier Byte im Speicher belegt. Dadurch steht anzahl also genau für die Anzahl der Zahlen hinter dem Label ausgabe. Diese Rechnung findet bereits beim Compilieren statt. Der Compiler ersetzt das Makro im Quellcode, so dass aus
mov anzahl, %l1
dann
mov 12, %l1
wird. Ist nur eine kleine Spielerei von mir, damit ich nicht vergesse, die Anzahl manuell zu verändern, wenn ich weitere Zahlen in die Liste mit aufnehme [23]
Die bisherigen rekursiven Programme waren keine guten Beispiele für sinnvolle Rekursion, weil man Fakultät und Fibonacci viel einfacher und effizienter per Iteration lösen konnte. Zur Abwechslung also mal ein echter Anwendungsfall von Rekursion:
.section ".data"
.align 4
test: .word 54, 86, 37, 96, 30, 51, 31, 6, 23, 84, 61, 71, 20, 57, 73, 35, 80, 41, 91, 11, 27, 45, 1, 50, 38
zahl: .asciz "%d "
zeile: .asciz "\n"
.section ".text"
.align 4
.global main
o:
save %sp, -128, %sp
set zahl, %l0
set test, %l1
mov 25, %l7
oloop:
ld [%l1], %o1
call printf
mov %l0, %o0
subcc %l7, 1, %l7
bne oloop
add %l1, 4, %l1
sethi %hi(zeile), %o0
call printf
or %o0, %lo(zeile), %o0
ret
restore
q:
save %sp, -128, %sp
cmp %i0, %i1
mov %i0, %l0
bge done
mov %i1, %l1
ld [%i0], %l7
qloop:
ld [%l0], %l6
cmp %l6, %l7
bl,a qloop
add %l0, 4, %l0
qloop2:
ld [%l1], %l5
cmp %l5, %l7
bg,a qloop2
sub %l1, 4, %l1
cmp %l0, %l1
bg cross
nop
st %l5, [%l0]
add %l0, 4, %l0
st %l6, [%l1]
sub %l1, 4, %l1
cmp %l0, %l1
ble qloop
cross:
mov %i0, %o0
call q
mov %l1, %o1
mov %l0, %o0
call q
mov %i1, %o1
done:
ret
restore
main:
call o
nop
set test, %o0
call q
add %o0, (25-1)*4, %o1
call o
nop
mov 1, %g1
ta 0
"branch,a label" heißt: Falls der Sprung nicht stattfindet, dann annuliere den nachfolgenden Befehl im delay slot (führe ihn nicht aus).
Bonusfrage am Rande: Bisher habe ich meine Daten immer in ".rodata" abgelegt. Warum geht das hier nicht?
So, dann drücke ich Euch die Daumen für die Klausur [14]
@Fred
Danke für den Bsp.code.
Angenommen es würde derart in der Klausur drankommen, meinste man muss dann auch eine Begründung abgeben warum der jeweilige Code etwas berechnet, oder reicht eine Vermutung(bzw. wenn man es mit den Zahlenbsp. durchgeht, und erkennt, "ah der Code berechnet jetzt blabla von zwei Zahlen", muss man dann erklären warum oder reicht es wenn man sagt er tut es).
hat der iterative eine tiefere bedeutung?
ich mein, da kommt ja am ende floor(lb(x)) + 1 bei raus, aber was ist das?
da kommt ja am ende floor(lb(x)) + 1 bei raus, aber was ist das?
Die Anzahl der Bits, die man braucht, um diese Zahl darzustellen?
Kann nicht mal jemand eineinfach es assembler Prog Posten Lehman meinte doch schon das es ehr so in die richtung einer Mathematischen formel geht also nicht so viel getrixe:)
Kann nicht mal jemand eineinfach es assembler Prog Posten
Klar. Was macht das folgende Unterprogramm?
dings:
sll %o0, 5, %o1
retl
add %o1, %o0, %o0
x +32x = %o0 ?
Man sollte die Spezifikationssprache (aus der x stammt) nicht mit der Assemblersprache (aus der %o0 stammt) vermischen. Wenn wir das Unterprogramm als Funktion auffassen, dann wird doch in %o0 das Ergebnis der Funktion abgelegt.
Formulier das doch nochmal als rein mathematische Funktion.
also x + 32x = y oder so :-)
also x + 32x = y oder so :-)
1. Was sagt man denn noch statt y in der Mathematik, wenn man betonen will, dass es sich um eine
Funktion von
x handelt? [25]
2. Kann man den Term x+32x noch vereinfachen?
Das ist die korrekte Antwort [14]
nimmt man den parameter nicht eher aus dem input-register?
Nein, da hier auf save/restore verzichtet wird, weswegen keine Umbenennung der Register stattfindet. Daher auch retl statt ret.
Die "klassische" Variante sähe so aus:
bums:
save %sp, -128, %sp
sll %i0, 5, %l0
add %l0, %i0, %i0
ret
restore
Fred The Assembly God [24]
Ich bin mir ziemlich sicher, dass es Assembler auch schon vor 1979 gab.
gibt es eine lösung zu den beiden beispielprogrammen?
Ey, was ist mit rot13 passiert?
[rot13]
Am 7.2. um 12:55 habe ich zwei Programme gepostet. Das erste berechnet den größten gemeinsamen Teiler (GGT) nach Euklid. Das zweite gibt aus, ob das Argument eine gerade oder ungerade Zahl ist, indem die Adresse des Formatstrings, welche man an prinft übergibt, direkt manipuliert wird.
Das um 18:42 gepostete Programm realisiert die Formel f(x) = x/3, indem man mit (ceil((2^32)/3)) multipliziert und das y-Register als Ergebnis ausliest.
Wie bereits besprochen berechnet das um 19:28 gepostete Programm die Anzahl der Bits, die man mindestens benötigt, um das Argument darstellen zu können.
Und um 20:37 habe ich meinen ersten Versuch gepostet, Quicksort rekursiv in Assembler zu programmieren.
[/rot13]
Und was machen Tris Beispielprogramme nun?
Aus Tris erstem Beispiel:
mov %o0, %o1
sethi %hi(outstr), %o0
call printf
or %o0, %lo(outstr), %o0
Kann mir das bitte jemand erklären, was da genau gemacht wird?
Da wird der Wert aus %o0 ausgegeben, indem er in o1 kopiert wird, in o0 der Formatierungsstring platziert wird (mittels sethi und or) und die printf-Unterroutine aufgerufen wird.
Und was machen Tris Beispielprogramme nun?
Das erste berechnet Fibonaccizahlen, das zweite Primzahlen.
sethi %hi(outstr), %o0
or %o0, %lo(outstr), %o0
Damit wird die Adresse, an der das Label outstr deklariert ist, in %o0 gespeichert. Man braucht dafür zwei Befehle, weil Adressen genau so lang sind wie die Befehle (nämlich 32 Bit).
Es gibt also 4 Milliarden unterschiedliche Adressen und 4 Milliarden unterschiedliche Befehle. Wenn es nun ein Befehlsformat gäbe, das eine komplette Adresse in ein Register schaufelt, dann wären ja keine anderen Befehlsformate mehr übrig für Addieren, Subtrahieren, bedingte Sprünge, Unterprogrammaufrufe etc. [25]
Hat vielleicht jemand Lust alle Beispielprogramme zu kommentieren was wann wo gemacht wird? :D
Und was machen Tris Beispielprogramme nun?
Das erste berechnet Fibonaccizahlen, das zweite Primzahlen.
sethi %hi(outstr), %o0
or %o0, %lo(outstr), %o0
Damit wird die Adresse, an der das Label outstr deklariert ist, in %o0 gespeichert. Man braucht dafür zwei Befehle, weil Adressen genau so lang sind wie die Befehle (nämlich 32 Bit).
Es gibt also 4 Milliarden unterschiedliche Adressen und 4 Milliarden unterschiedliche Befehle. Wenn es nun ein Befehlsformat gäbe, das eine komplette Adresse in ein Register schaufelt, dann wären ja keine anderen Befehlsformate mehr übrig für Addieren, Subtrahieren, bedingte Sprünge, Unterprogrammaufrufe etc. [25]
das hilft mir leider nicht sehr viel weiter, kannst du nicht irgendwie detailiert aufzeigen, was genau passiert bitte?
das hilft mir leider nicht sehr viel weiter, kannst du nicht irgendwie detailiert aufzeigen, was genau passiert bitte?
Klar. Dann besprechen wir die beiden Befehle einzeln. Zunächst die Bestandteile des ersten Befehls:
sethi %hi(outstr), %o0
sethi ist das Mnemonic, das für die Befehlsgruppe sethi steht
outstr ist die Adresse, an der das Label outstr im Datensegment steht
%hi(x) ist ein Makro, das die oberen 22 Bit von x extrahiert
%o0 ist das Zielregister
Ganz allgemein lautet die Syntax der sethi-Befehlsgruppe also
sethi imm22, rd
Die Semantik ist:
rd := imm22 << 10;
Oder auf deutsch: Übernimm den Immediate-Wert in die oberen 22 Bit des Zielregisters (und lösche die unteren 10 Bit).
Nun zum zweiten Befehl:
or %o0, %lo(outstr), %o0
or ist das Mnemonic, das für die Befehlsgruppe Arithmetische Operationen/Bitweise Oder steht
%o0 ist das Quellregister
outstr ist die Adresse, an der das Label outstr im Datensegment steht
%lo(x) ist ein Makro, das die unteren 10 Bit von x extrahiert. Es handelt sich also um einen Immediate Wert!
%o0 ist das Zielregister
Ganz allgemein lautet die Syntax der Befehlsgruppe Arithmetische Operationen/Bitweise Oder/Immediate also
or %rs, imm13, %rd
Die Semantik ist:
%rd := %rs | imm13
Oder auf deutsch: Verknüpfe den Inhalt des Registers %rs bitweise oder mit dem angegebenen Immediate-Wert und speichere das Ergebnis in %rd
Wenn Du nun einen 32 Bit breite Adresse <x31 x30 x29 x28 … x3 x2 x1 x0> hast und diese in ein Register speichern möchtest, dann machst Du das folgendermaßen:
sethi %hi(<x31 ... x0>), %rd
or %rd, %lo(<x31 ... x0>), %rd
%hi und %lo sind wie gesagt nur Makros. Diese werden vom Compiler folgendermaßen ersetzt:
sethi <x31 …
x10>, %rd
or %rd, <
x9 … x0>, %rd
Und zuletzt noch die Semantik als Kommentar:
sethi <x31 ... x10>, %rd ! %rd = <x31 ... x10 0 0 0 0 0 0 0 0 0 0>
or %rd, <x9 ... x0>, %rd ! %rd = <x31 ... x10 x9 x8 x7...x2 x1 x0> = <x31 ... x0>
kann jemand die loop im assembler code erklären?
kann jemand die loop im assembler code erklären?
Welche loop in welchem der Programme?
ich dachte mir aus dem ersten code, aber am besten wäre mal so ein code mit kommentaren an der seite die sagen was er tut.
ich persönlich kann ganz einfache programme verstehen, wenn es um registerzuweisung und einfache rechenarten geht aber wenns dann komplizierter wird mit loops und so dann hilft mir das wissen auch nicht mehr und ich kann dann den ganzen code nicht erklären obwohl ich nicht ganz ahnungslos bin.
Ein Programm wird normalerweise von oben nach unten abgearbeitet. Dazu gibt es zwei Befehlszähler: PC und nPC (nextPC). Zu Beginn steht PC auf dem ersten Befehl und nPC auf dem zweiten. Dann passiert immer folgendes:
Der Befehl, auf den PC zeigt, wird geholt, dekodiert, [… weitere Pipeline-Schritte …] und zuletzt ausgeführt. Anschließend wird der Befehlszähler durch PC := nPC weitergezählt.
Was passiert jetzt mit dem nPC? War der letzte Befehl ein "normaler" Befehl, dann wird nun nPC := nPC + 4 gesetzt. War es dagegen ein wahrgenommener Sprungbefehl, dann wird nPC auf das Sprungziel des Sprungbefehls gesetzt.
Durch den nPC wird die verzögerte Sprungausführung realisiert, welche bewirkt, dass der Befehl nach einem Sprungbefehl noch ausgeführt wird, bevor der erste Befehl des Sprungziels ausgeführt wird. Das heißt aber streng genommen nicht, dass der Befehl noch VOR DEM SPRUNG passiert, was man oft etwas salopp sagt.
So, nun zu den Schleifen. Eine Schleife würde im Pseudocode einer Sprache, die keine höheren Schleifenkonstrukte (while, do while, for) kennt, vielleicht so aussehen:
i := 0
schleife:
(...mach irgendwas mit i...)
i := i + 1
falls i <= 100 gehe zu schleife
Und das kann man fast 1:1 in Assembler umsetzen. Nur die letzte Anweisung muss man in zwei Teile teilen:
vergleiche i mit 100
falls <= gehe zu
Man kann dies auch noch ausführlicher beschreiben:
vergleiche i mit 100 und setzte die Flags entsprechend
falls eine Kombination bestimmter Flags als "kleiner gleich" interpretiert werden kann, dann gehe zu
Und das sieht dann in Assembler ganz konkret so aus:
mov 0, %l0 ! i := 0
schleife:
(...mach irgendwas mit i...)
add %l0, 1, %l0 ! i := i + 1
cmp %l0, 100 ! vergleiche i mit 100 und setzte die Flags entsprechend
bleu schleife ! falls eine Kombination bestimmter Flags als "kleiner gleich"
nop ! interpretiert werden kann, dann gehe zu
Man beachte das nop. Es wird ja der Befehl nach dem Sprungbefehl noch vor dem ersten Befehl des Sprungziels ausgeführt (siehe Erklärung zu PC/nPC oben). Wenn man da nix sinnvolles einsetzen kann, schreibt man halt nop (no operation).
Und das sieht dann in Assembler ganz konkret so aus:
mov 0, %l0 ! i := 0
schleife:
(...mach irgendwas mit i...)
add %l0, 1, %l0 ! i := i + 1
cmp %l0, 100 ! vergleiche i mit 100 und setzte die Flags entsprechend
bleu schleife ! falls eine Kombination bestimmter Flags als "kleiner gleich"
nop ! interpretiert werden kann, dann gehe zu
Man beachte das nop. Es wird ja der Befehl nach dem Sprungbefehl noch vor dem ersten Befehl des Sprungziels ausgeführt (siehe Erklärung zu PC/nPC oben). Wenn man da nix sinnvolles einsetzen kann, schreibt man halt nop (no operation).
also wird
"schleife:
(…mach irgendwas mit i…)"
gar nicht gelesen, es sei denn "bleu" trifft zu?
also wird
"schleife:
(…mach irgendwas mit i…)"
gar nicht gelesen, es sei denn "bleu" trifft zu?
Was? Worauf bezieht sich Dein "also"? Auf die verzögerte Sprungausführung? Verstehe ich jetzt nicht den Zusammenhang. Was meinst Du mit "gelesen"?
Angenommen, die Schleife geht nicht bis 100, sondern bis 2. Dann werden die Befehle in folgender Reihenfolge ausgeführt:
mov 0, %l0
(...mach irgendwas mit i...)
add %l0, 1, %l0
cmp %l0, 2
bleu schleife
nop
(...mach irgendwas mit i...)
add %l0, 1, %l0
cmp %l0, 2
bleu schleife
nop
(...mach irgendwas mit i...)
add %l0, 1, %l0
cmp %l0, 2
bleu schleife
nop
Hilft das weiter?
also wird
"schleife:
(…mach irgendwas mit i…)"
gar nicht gelesen, es sei denn "bleu" trifft zu?
Was? Worauf bezieht sich Dein "also"? Auf die verzögerte Sprungausführung? Verstehe ich jetzt nicht den Zusammenhang. Was meinst Du mit "gelesen"?
Angenommen, die Schleife geht nicht bis 100, sondern bis 2. Dann werden die Befehle in folgender Reihenfolge ausgeführt:
mov 0, %l0
(...mach irgendwas mit i...)
add %l0, 1, %l0
cmp %l0, 2
bleu schleife
nop
(...mach irgendwas mit i...)
add %l0, 1, %l0
cmp %l0, 2
bleu schleife
nop
(...mach irgendwas mit i...)
add %l0, 1, %l0
cmp %l0, 2
bleu schleife
nop
Hilft das weiter?
ja sorry hab grad falsch gedacht. danke für die gute erklärung!
kann mir noch jemand erklären, wie das %y register gehandhabt wird, vor allem bei udiv/sdiv? also inwiefern greifen udiv und sdiv auf das register zu? nur um den rest der division zu speichern, welchen man dann nach belieben abrufen kann (für modulo-rechnungen z.b.)?
also inwiefern greifen udiv und sdiv auf das register zu?
Folgender Befehl
udiv %l0, %l2, %l4
hat folgende Semantik:
%l4 := ((%y << 32) | %l0) / %l2
Es wird also eine 64-Bit-Zahl (Dividend) durch eine 32-Bit-Zahl (Divisor) geteilt. Die unteren 32 Bit des Dividenden gibt man explizit an (hier %l0), die oberen 32 Bit stehen implizit im %y-Register.
ASCII-Art:
------------------- ---------- ----------
| %y | %l0 | / | %l2 | = | %l4 |
------------------- ---------- ----------
Das %y-Register wird durch die Division glaube ich nicht beeinflusst. Es steht also insbesondere nach der Division kein Rest drin oder so, den muss man kompliziert berechnen, falls er einen interessiert.
Bei der Multiplikation ist es übrigens genau umgekehrt: 32 Bit * 32 Bit = 64 Bit. Die oberen 32 Bit des Ergebnisses landen hier im %y-Register.
Also: Multiplikation schreibt ins %y-Register und Division liest aus dem %y-Register, um 64-Bit-Operanden bzw. 64-Bit-Ergebnisse realisieren zu können.
*push*
falls jemand ein paar assembleraufgaben machen möchte :)
Das fragst gerade Du? Du müsstest doch am besten wissen, welche Sprache im aktuellen RS-Durchlauf gelehrt wurde.
welche Sprache im aktuellen RS-Durchlauf gelehrt wurde.
Sparc-Assembler?
und die Aufgaben hier sind: Sparc-Assembler?!
Das fragst gerade Du? Du müsstest doch am besten wissen, welche Sprache im aktuellen RS-Durchlauf gelehrt wurde.
Sparc V8, genau wie letztes Jahr. Was dachtest Du denn?
Intel… aber das ist ja erst wieder nächstes Jahr… oder wann macht Zhang wieder RS?
Bekommt man eigentlich auch Punkte dafür wenn man den ganzen Text toll auskommentiert aber einfach nicht drauf kommt, was das programm letztendlich macht?