FB18 - Das Forum für Informatik

fb18.de / Bachelorstudieng / PM Technische Informatik

Ausführen eines Assemblerprogramms

Ausführen eines Assemblerprogramms 2009-01-11 17:43
Anonymer User
Ich habe Aufgabe 36 Übungsblatt 10 fehlerfrei assembliert.

Wenn ich es jetzt allerdings mit a.out 170 1 4

aufrufen will, bekomme ich die Fehlermeldung: "Segmentation Fault"

Woran liegt das?

RE: Ausführen eines Assemblerprogramms 2009-01-11 17:57
Anonymer User
Danke Problem hat sich schon gelöst. =)

RE: Ausführen eines Assemblerprogramms 2009-01-11 19:19
Fred
a.out 170 1 4
Du parst die Argumente von der Kommandozeile? Ist das auf dem Aufgabenblatt gefordert?

RE: Ausführen eines Assemblerprogramms 2009-01-11 19:52
Anonymer User
Es ist gefordert dass 2 Bits vertauscht werden sollen und ich woltel über Kommandozeilenparameter steuern, welche Zahl und wlech eBits gesteuert werden sollen.

Aber anscheinend habe ich nicht genaz verstandne, wie man die angegebenen Parameter verarbeitet.

RE: Ausführen eines Assemblerprogramms 2009-01-11 19:56
tein
Die Parameter sollen nicht per Kommandozeile, sondern an ein Unterprogramm übergeben werden.

RE: Ausführen eines Assemblerprogramms 2009-01-11 19:59
Anonymer User
Ja schon klar ich wollte ja nur, dass man die per Kommandozeile eingibt und anschließend ans Unterprogramm weitergibt.

RE: Ausführen eines Assemblerprogramms 2009-01-11 23:09
Anonymer User
Mal ne Frage:

Wann genau taucht der Fehler "Segmentation Fault" imemr genau auf und wie kann man ihn vermeiden?

RE: Ausführen eines Assemblerprogramms 2009-01-11 23:16
Anonymer User
! Information für Binder
.global main
.global printf

! Deklaration von Daten
.section ".data"
.align 8
x: .double 0r16.0
fmt:
.ascii "Quadratwurzel von %f\n"
.asciz "mit fsqrtd: %f\n"

! ausführbares Programm
.section ".text"

quadratwurzel:

main:
set fmt, %l0

set x,%l1
ldd [%l1],%f2
fsqrtd %f2, %f4
std %f4, [%l6]

mov %l0, %o0

std %f2, [%l1+8]
ld [%l1+8], %o1
ld [%l1+12], %o2

ld [%l6+8], %o3
ld [%l6+12], %o4

call printf
nop

set 1,%g1
ta 0

Bei dem Programm gibt er mir zum Beispiel so einen Fehler

RE: Ausführen eines Assemblerprogramms 2009-01-11 23:50
Fred
std %f4, [%l6]
Du benutzt %l6 als Adresse, hast aber nie was vernünftiges reingeschrieben. Also versuchst Du an eine zufällige Adresse zu schreiben, was mit hoher Wahrscheinlichkeit schiefgeht.

RE: Ausführen eines Assemblerprogramms 2009-01-12 00:02
Anonymer User
std %f4, [%l6]

Schreibt man damit nicht etwas da rein?

RE: Ausführen eines Assemblerprogramms 2009-01-12 00:15
Fred
Nein. std %f4, [%l6] entspricht folgender Anweisung an den Prozessor:

"Lieber Prozessor! Bitte sei so lieb und lege die aktuellen Werte von %f4 und %f5 hintereinander im Speicher ab. Die Adresse, an der Du 8 freie Bytes dafür finden solltest, findest Du im Register %l6. Vielen Dank und bis bald!"

RE: Ausführen eines Assemblerprogramms 2009-01-12 00:28
Anonymer User
Ich habe jetzt ein
set x, %l6

davor gesetzt.

Jetzt zeigt er diesen Fehler nicht mehr an aber er macht auch keinerlei Ausgabe.
Woran liegt das denn nun schon wieder?

RE: Ausführen eines Assemblerprogramms 2009-01-12 00:45
Fred
set x, %l6
std %f4, [%l6]
Okay, Du legst %f4 und %f5 also ab Adresse x ab. Und was machst Du anschließend mit diesen 8 Bytes, nachdem Du sie in den Speicher geschrieben hast? Dass sie nicht in %l6 stehen, ist Dir klar? Da steht weiterhin die Adresse x drin.

RE: Ausführen eines Assemblerprogramms 2009-01-12 01:18
Anonymer User
Kurzer Update meines Quelltextes:

! Information für Binder
.global main
.global printf

! Deklaration von Daten
.section ".data"
.align 8
x: .double 0r16.0
x2: .double 0r0.0
fmt:
.ascii "Quadratwurzel von %f\n"
.asciz "mit fsqrtd: %f\n"

! ausführbares Programm
.section ".text"

quadratwurzel:

main:
set fmt, %l0

set x,%l1 ! Die gewünschte Zahl ins das Register l1 laden
ldd [%l1],%f2 ! x in %f2, %f3
fsqrtd %f2, %f4 ! Wurzel mit fsqrtd in %f4, %f5
set x2, %l6
std %f4, [%l6] ! (double) wurzel

mov %l0, %o0 ! fmt

std %f2, [%l1+8] ! double x nach l1+8
ld [%l1+8], %o1 ! l1+8 nach o1
ld [%l1+12], %o2 ! l1+12 nach o2

ld [%l6], %o3
ld [%l6+4], %o4

call printf
nop

set 1,%g1
ta 0

Ausgabe:
Quadratwurzel von 16.000000
mit fsqrtd: 16.000000

Das ist schon etwas merkwürdig.^^

RE: Ausführen eines Assemblerprogramms 2009-01-12 02:53
Fred
Ich zitiere mal nur die relevanten Zeilen:
x: .double 0r16.0
x2: .double 0r0.0
!…
set x,%l1
set x2, %l6
!…
std %f4, [%l6]
std %f2, [%l1+8]
Merkst Du was?

RE: Ausführen eines Assemblerprogramms 2009-01-12 03:28
Anonymer User
Vielen Dank hab meine Fehler gefunden.

Wenn man den ganzen Tag davor sitzt, kann das echt schonmal passieren, dass mal so eine Banalität übersieht.^^

RE: Ausführen eines Assemblerprogramms 2009-01-12 09:58
Hannes
Mal ne Frage:

Wann genau taucht der Fehler "Segmentation Fault" imemr genau auf und wie kann man ihn vermeiden?

http://en.wikipedia.org/wiki/Segfault

RE: Ausführen eines Assemblerprogramms 2009-01-12 15:23
Rolf
Weiter oben kam ja eine Frage wegen der direkteingabe von Werten ueber die Konsole, was mich auch durchaus interessieren wuerde.
Kann da jemand einfach ein Beispiel zeigen, wie ich bei/nach(?) dem Kompilieren einen Wert uebergeben und wie ich diesen im Programm aufnehmen kann?

Wuerde das Ausprobieren ja auch vereinfachen, wenn ich nicht fuer jeden Wert erst im Quelltext herumscrollen, aendern, abspeichern, neu kompilieren usw. muss.

RE: Ausführen eines Assemblerprogramms 2009-01-12 15:50
Fred
Die Kommandozeilenargumente werden an den Leerzeichen getrennt und dann irgendwo im Speicher abgelegt. Dann wird ein Array angelegt, dass die Startadressen dieser Argumente speichert. Die Startadresse dieses Arrays wiederum steht innerhalb von main in %o1 bzw. in %i1 (falls Du in ein save verwendest).

RE: Ausführen eines Assemblerprogramms 2009-01-12 18:48
Anonymer User
Nach dem Prinzip hab ich das ja probiert aber hat nicht so ganz funktioniert wie ich wollte aber naja muss ich mri noch mal in RUhe angucken.

Vllt kann mri währenddessen heir jemand weiter helfen, stehe irgendwie gerade auf einem Schlauch und finde den Fehler nicht…

! Information für Binder
.global main
.global printf

! Deklaration von Daten
.section ".data"
.align 8
x: .double 0r16.0
x2: .double 0r0.0
x3: .double 0r0.0
x4: .double 0r2.0
fmt:
.ascii "Quadratwurzel von %f\n"
.ascii "mit fsqrtd: %f\n"
.asciz "mit Newton-Raphson: %f\n"

! ausführbares Programm
.section ".text"

quadratwurzel:
save %sp, -96, %sp

ldd [%i0], %f8 ! x ins f8 und f9

set x4, %l6
ldd [%l6], %f16 ! 2.0 in %f16, %f17

cmp %i0, 0 ! Wenn kleiner denn -1 zurueckgeben
bl kleiner
nop
cmp %i0, 0 ! Wenn 0 denn 0 zurueckgeben
be null
nop
mov %i0, %l0
ldd [%l0], %f10 ! f10 und f11 fuer XALT
fdivd %f10, %f16, %f10 ! XALT = x / 2
mov %l0, %l2
ldd [%l2], %f12 ! f12 und f13 fuer XNEU
mov %i0, %l4 ! XNEU = XALT
ldd[%l4], %f14 ! Hilfsspeicher f14 und f15 fuer x / XALT
fdivd %f14, %f10, %f14 ! h = x / XALT
faddd %f12, %f14, %f12 ! XNEU = (XALT + x/XALT)
fdivd %f12, %f16, %f12 ! XNEU = (XALT + x/XALT) / 2.0

cmp %l0, %l2 ! Wenn die gleich sind gehe zum Ende
be ende
nop

schleife:
mov %l2, %l0 ! XALT = XNEU
mov %l0, %l2 ! XNEU = XALT
mov %i0, %l4 ! x ins HIlfsspeicher
fdivd %f14, %f10, %f14 ! h = x / XALT
faddd %f12, %f14, %f12 ! XNEU = (XALT + x/XALT)
fdivd %f12, %f16, %f12 ! XNEU = (XALT + x/XALT) / 2.0

cmp %l0, %l2 ! Wenn die ungleich sind, wiederhole schleife
bne schleife
nop

ende:
std %f12, [%l4] ! Ergebnis ins o0 und o1
ld [%l4], %o0
ld [%l4+4], %o1
jmp %i7+8
restore

kleiner: ! -1 Wenn x kleiner 0
mov -1, %o0
jmp %i7+8
restore

null: ! 0 wenn x 0 ist
mov 0, %o0
jmp %i7+8
restore

main:
set x,%l1 ! Die gewünschte Zahl ins das Register l1 laden
ldd [%l1],%f2 ! x in %f2, %f3
fsqrtd %f2, %f4 ! Wurzel mit fsqrtd in %f4, %f5
set x2, %l6
std %f4, [%l6] ! (double) wurzel

std %f2, [%l1] ! x ins o0 und o1 Register schreiben
ld [%l1], %o0 ! fuer den Unterprogrammaufruf
ld [%l1+4], %o1

call quadratwurzel
nop

ld [%o0], %o5
ld [%o1], %o6

set fmt, %l0
mov %l0, %o0 ! fmt

std %f2, [%l1] ! double x nach l1+8
ld [%l1], %o1 ! l1+8 nach o1
ld [%l1+4], %o2 ! l1+12 nach o2

ld [%l6], %o3
ld [%l6+4], %o4

call printf
nop

set 1,%g1
ta 0

Schon mal Danke im voraus

RE: Ausführen eines Assemblerprogramms 2009-01-12 18:48
Anonymer User
Achja es ist ein "Segmentation Fehler"

RE: Ausführen eines Assemblerprogramms 2009-01-12 19:09
Fred
Schauen wir uns zuerst mal den Aufrufer an:
main:
set x,%l1 ! Die gewünschte Zahl ins das Register l1 laden
ldd [%l1],%f2 ! x in %f2, %f3

std %f2, [%l1] ! x ins o0 und o1 Register schreiben
ld [%l1], %o0 ! fuer den Unterprogrammaufruf
ld [%l1+4], %o1

call quadratwurzel
nop
Du übergibst in %o0 und %o1 die Zahl, von der Du die Wurzel berechnen möchtest. So weit, so gut. Nun zum Unterprogramm:

quadratwurzel:
save %sp, -96, %sp

ldd [%i0], %f8 ! x ins f8 und f9
Hier interpretierst Du die oberen 32 Bit der übergebenen Zahl (also das Vorzeichenbit, die Charakteristik und einen Teil der Mantisse) als Adresse und versuchst, an dieser Adresse im Speicher 8 Byte zu laden => segfault

RE: Ausführen eines Assemblerprogramms 2009-01-12 20:07
Anonymer User
So das haeb ich nu gelöst mit:

st %i0, [%fp-8]
st %i1, [%fp-4]
ldd [%fp-8], %f8 ! x ins f8 und f9

Bekomme aber imemrnoch einen Seg Fehler…

RE: Ausführen eines Assemblerprogramms 2009-01-12 21:59
Fred
Bekomme aber imemrnoch einen Seg Fehler…
Dann nimmst Du halt solange Speicherbefehle raus, bis sie nicht mehr auftreten. Die hier sehen z.B. sehr gefährlich aus:

mov %i0, %l0
ldd [%l0], %f10 ! f10 und f11 fuer XALT

mov %l0, %l2
ldd [%l2], %f12 ! f12 und f13 fuer XNEU

RE: Ausführen eines Assemblerprogramms 2009-01-12 22:57
Anonymer User
Egal, was ich amche der kack Fehler geht nicht weg.

Wäre echt mal sinnvoll, wenn der Compiler anzeigen würde, WO der Fehler verursacht wird…

RE: Ausführen eines Assemblerprogramms 2009-01-12 23:47
Fred
Egal, was ich amche der kack Fehler geht nicht weg.
Selbst wenn Du alle Speicherzugriffe entfernst? Das kann nicht sein.

RE: Ausführen eines Assemblerprogramms 2009-01-13 02:35
UncleOwen
Wäre echt mal sinnvoll, wenn der Compiler anzeigen würde, WO der Fehler verursacht wird…

Der Compiler soll bei Laufzeitfehlern was anzeigen? Wie stellst Du Dir das denn bitte vor?

RE: Ausführen eines Assemblerprogramms 2009-01-13 02:52
garou
Wäre echt mal sinnvoll, wenn der Compiler anzeigen würde, WO der Fehler verursacht wird…
s/compiler/debugger/

RE: Ausführen eines Assemblerprogramms 2009-01-13 05:20
Anonymer User
Naja C++ oder Java zeigen das ja auch an. ;)

@ Garou: Wie genau meinst du das? Wie soll/kann ich den Debugger anwenden?

RE: Ausführen eines Assemblerprogramms 2009-01-13 11:37
Anonymer User
ld [%o1], %o6

Hier dürfte der Fehler liegen (im main-Programm). Du belegst %o6 mit irgendwas, und da das der stack pointer ist, versucht er beim nächsten st oder ld Befehl von diesem aus zu gehen (in printf) und landet natürlich einfach irgendwo, wo er nicht hin darf. Teste einfach mal kurz, was passiert, wenn du die "call printf" Zeile auskommentierst. Du solltest dann keinen Segfault mehr kriegen (natürlich auch keine Ausgabe, einfach gar nichts).
Bei mir war es das, hab ich auch ewig nach gesucht…

Du kannst printf eben nur max. 5 Register übergeben und darfst o6 davor nicht verändern. Schreib doch einfach deine Rechenzahl als Klartext in den String, dann hast du genug Platz für beide doubles. Oder aber du speicherst den einen in einem lokalen Register und rufst dann printf zweimal auf (einmal für die erste Hälfte der Ausgabe, einmal für die zweite).


Noch eine kleine Verständnisfrage meinerseits:
Was genau machen eigentlich die letzten beiden Zeilen in main:
set     1, %g1
ta       0
Ohne sie gehts scheinbar nicht, aber Lehmanns Kommentar dazu ist etwas mager und im Manual finde ich dazu nichts, aus dem ich schlau werde.

RE: Ausführen eines Assemblerprogramms 2009-01-13 12:19
Anonymer User
Die letzten beiden Zeilen sind einfach dazu da, um ins Betriebssystem zurückzuspringen.
Muss man einfach als "notwendiges Übel" hinnehmen.

Deien Vorschläge werde ich gleich mal ausprobieren.

RE: Ausführen eines Assemblerprogramms 2009-01-13 12:29
Fred
Du belegst %o6 mit irgendwas, und da das der stack pointer ist
Scharf beobachtet!

Noch eine kleine Verständnisfrage meinerseits:
Was genau machen eigentlich die letzten beiden Zeilen in main:
set     1, %g1
ta       0
Schauen wir einfach mal im Manual nach:
Trap - A vectored transfer of control to supervisor software through a table whose address is given by a privileged IU register (the Trap Base Register (TBR)).
Du kannst also aus dem beschränkten Usermodus heraus spezielle Dienstleistungen des Supervisormodus anfordern. Etwas ausführlicher:
A trap is a vectored transfer of control to the operating system through a special trap table that contains the first 4 instructions of each trap handler. The base address of the table is established by software in an IU state register (the trap base register, TBR). The displacement within the table is encoded in the type number of each trap. Half of the table is reserved for hardware traps, and the other half for software traps generated by trap (Ticc) instructions.

A trap causes the current window pointer (CWP) to advance to the next register window and the hardware to write the program counters into two registers of the new window. The trap handler can access the saved PC and nPC and, in general, can freely use the 6 other local registers in the new window.

A trap may be caused by an instruction-induced exception, or by an external interrupt request not directly related to a particular instruction. Before executing each instruction, the IU checks for pending exceptions and interrupt requests. If any are present, the IU selects the one with the highest priority and causes a corresponding trap to occur.
Eine Übersicht über die vorhandenen Dienstleistungen habe ich auf die schnelle nicht gefunden.

RE: Ausführen eines Assemblerprogramms 2009-01-13 12:52
Anonymer User
Brauch schnell eien Antwort:

Wie kann ich von einem Rechner am Informatikum mein Programm ausführen?

RE: Ausführen eines Assemblerprogramms 2009-01-13 12:59
Fred
Übersetzen:
cc deinprogramm.s Ausführen:
./a.out

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:00
Anonymer User
Bin utner Linux angemeldet und wenn ich das in der Konsole eingebe, sagt er mir, dass er die ganzen Befehle und Anweisungen nicht kennt.

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:02
Fred
Bin utner Linux angemeldet und wenn ich das in der Konsole eingebe, sagt er mir, dass er die ganzen Befehle und Anweisungen nicht kennt.
Welche hast Du denn alle ausprobiert?

Hm, Ferndiagnosen sind ja immer schwierig… hast Du es mal mit gcc statt cc versucht?
gcc deinprogramm.s ./a.out
Ansonsten poste doch einfach mal die exakten Fehlermeldungen.

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:07
Anonymer User
Unter die ganzen meine ich:

temp.s:1: Error: junk at end of line, first unrecognized character is `!'
temp.s:5: Error: junk at end of line, first unrecognized character is `!'
temp.s:17: Error: junk at end of line, first unrecognized character is `!'
temp.s:21: Error: no such instruction: `save %sp,-96,%sp'
temp.s:23: Error: no such instruction: `st %i0,[%fp-8]'
temp.s:24: Error: no such instruction: `st %i1,[%fp-4]'
temp.s:25: Error: no such instruction: `ldd [%fp-8],%f8!x ins f8 und f9'
temp.s:27: Error: no such instruction: `set x4,%l6'
temp.s:28: Error: no such instruction: `ldd [%l6],%f16!2.0 in %f16,%f17'
temp.s:30: Error: bad register name `%i0'
temp.s:31: Error: no such instruction: `bl kleiner'
temp.s:33: Error: bad register name `%i0'
temp.s:34: Error: no such instruction: `be null'
temp.s:37: Error: no such instruction: `fmovs %f9,%f11'
temp.s:38: Error: no such instruction: `fmovs %f8,%f10!XALT=x in f10 udn f11'
temp.s:39: Error: no such instruction: `ldd [%l0],%f10'
temp.s:40: Error: no such instruction: `fdivd %f10,%f16,%f10!XALT=x/2'
temp.s:42: Error: no such instruction: `fmovs %f11,%f13'
temp.s:43: Error: no such instruction: `fmovs %f10,%f12!XNEU=XALT'
temp.s:44: Error: junk at end of line, first unrecognized character is `!'
temp.s:45: Error: no such instruction: `ldd [%l2],%f12!f12 und f13 fuer XNEU'
temp.s:46: Error: no such instruction: `fmovs %f9,%f15'
temp.s:47: Error: no such instruction: `fmovs %f8,%f14!h=x'
temp.s:48: Error: junk at end of line, first unrecognized character is `!'
temp.s:49: Error: invalid character '[' in mnemonic
temp.s:50: Error: no such instruction: `fdivd %f14,%f10,%f14!h=x/XALT'
temp.s:51: Error: no such instruction: `faddd %f12,%f14,%f12!XNEU=(XALT+x/XALT)'
temp.s:52: Error: no such instruction: `fdivd %f12,%f16,%f12!XNEU=(XALT+x/XALT)/2.0'
temp.s:54: Error: bad register name `%l0'
temp.s:55: Error: no such instruction: `be ende'
temp.s:59: Error: no such instruction: `fmovs %f13,%f11'
temp.s:60: Error: no such instruction: `fmovs %f12,%f10!XALT=XNEU'
temp.s:62: Error: no such instruction: `fmovs %f11,%f13'
temp.s:63: Error: no such instruction: `fmovs %f10,%f12!XNEU=XALT'
temp.s:65: Error: no such instruction: `fmovs %f9,%f15'
temp.s:66: Error: no such instruction: `fmovs %f8,%f14!x in Hilfsspeicher'
temp.s:68: Error: no such instruction: `fdivd %f14,%f10,%f14!h=x/XALT'
temp.s:69: Error: no such instruction: `faddd %f12,%f14,%f12!XNEU=(XALT+x/XALT)'
temp.s:70: Error: no such instruction: `fdivd %f12,%f16,%f12!XNEU=(XALT+x/XALT)/2.0'
temp.s:72: Error: bad register name `%l0'
temp.s:73: Error: no such instruction: `bne schleife'
temp.s:77: Error: bad register name `%f12'
temp.s:78: Error: no such instruction: `ld [%l4],%o0'
temp.s:79: Error: no such instruction: `ld [%l4+4],%o1'
temp.s:80: Error: bad register name `%i7+8'
temp.s:81: Error: no such instruction: `restore'
temp.s:83: Error: junk at end of line, first unrecognized character is `!'
temp.s:84: Error: bad register name `%o0'
temp.s:85: Error: bad register name `%i7+8'
temp.s:86: Error: no such instruction: `restore'
temp.s:88: Error: junk at end of line, first unrecognized character is `!'
temp.s:89: Error: bad register name `%o0'
temp.s:90: Error: bad register name `%i7+8'
temp.s:91: Error: no such instruction: `restore'
temp.s:94: Error: no such instruction: `set x,%l1!Die gew�nschte Zahl ins das Register l1 laden'
temp.s:95: Error: no such instruction: `ldd [%l1],%f2!x in %f2,%f3'
temp.s:96: Error: no such instruction: `fsqrtd %f2,%f4!Wurzel mit fsqrtd in %f4,%f5'
temp.s:97: Error: no such instruction: `set x2,%l6'
temp.s:98: Error: bad register name `%f4'
temp.s:100: Error: bad register name `%f2'
temp.s:101: Error: no such instruction: `ld [%l1],%o0!fuer den Unterprogrammaufruf'
temp.s:102: Error: no such instruction: `ld [%l1+4],%o1'
temp.s:107: Error: no such instruction: `ld [%o0],%o5'
temp.s:108: Error: no such instruction: `ld [%o1],%o6'
temp.s:110: Error: no such instruction: `set fmt,%l0'
temp.s:111: Error: bad register name `%l0'
temp.s:113: Error: bad register name `%f2'
temp.s:114: Error: no such instruction: `ld [%l1],%o1!l1+8 nach o1'
temp.s:115: Error: no such instruction: `ld [%l1+4],%o2!l1+12 nach o2'
temp.s:117: Error: no such instruction: `ld [%l6],%o3'
temp.s:118: Error: no such instruction: `ld [%l6+4],%o4'
temp.s:123: Error: no such instruction: `set 1,%g1'
temp.s:124: Error: no such instruction: `ta 0'

Ich hatte eingegeben:
cc aufgabe38.s

Habs auch mit:
gcc aufgabe38.s
probiert kamen aber dieselben Fehlermedungen.

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:08
Fred
Und Du bist sicher, dass Du an einer Sparc sitzt?

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:12
Anonymer User
Glaube ich nicht, kA wo die stehen.^^

Ich sitze in D017 und woltle das von heir aus machen.

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:18
Fred
Glaube ich nicht, kA wo die stehen.^^
In den Arbeitsräumen rechts neben dem Druckerraum, wo der d116_hp sich befindet, stehen definitiv Sparc-Rechner. Du kannst die Sparc-Aufgaben (ohne Umwege) nur auf einer Sparc machen. Wenn Du es unbedingt von einem anderen Rechner aus machen musst, verbinde Dich per SSH mit einer Sparc. Für Windows-Benutzer gibt es sogar einen eigenen Thread.

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:25
Anonymer User
Sehr schön mit SSH funktioniert es.^^

RE: Ausführen eines Assemblerprogramms 2009-01-13 13:39
Anonymer User
Ne Frage:

Der Rückgabewert der Funktion mit double, steht das nun im %f0 und %f1 oder im %o0 und %o1?

RE: Ausführen eines Assemblerprogramms 2009-01-13 14:30
Anonymer User
Mein Programm funktioniert jetzt mit dem Wert 0.

Bei allen anderen Werten gibt es einen Seg Fehler. -.-

RE: Ausführen eines Assemblerprogramms 2009-01-13 14:45
Fred
Der Rückgabewert der Funktion mit double, steht das nun im %f0 und %f1 oder im %o0 und %o1?
%f0 und %f1.

RE: Ausführen eines Assemblerprogramms 2009-01-13 15:40
Anonymer User
So jett zeigt er mir keien Seg Fehler mehr an aber dafür die flaschen Wert der Wurzeln, so ist zum Beispiel Wurzel aus 1 anstatt -1 zeigt er 1000 an und bei 0 zeigt er -1 an.

Hier nochmal der Quelltext. Vielleicht kann mir da ja jemand weiterhelfen.

! Information fuer Binder
.global main
.global printf

! Deklaration von Daten
.section ".data"
.align 8
x: .double 0r-1.0
x2: .double 0r0.0
x3: .double 0r0.0
x4: .double 0r2.0
x5: .double 0r-1.0
fmt:
.ascii "Quadratwurzel von %f\n"
.asciz "mit fsqrtd: %f\n"
fmt2: .asciz "mit Newton-Raphson: %f\n"

! ausfuehrbares Programm
.section ".text"

quadratwurzel:
save %sp, -96, %sp

st %i0, [%fp-8]
st %i1, [%fp-4]
ldd [%fp-8], %f8 ! x in f8 und f9

set x4, %l6
ldd [%l6], %f16 ! 2.0 in %f16, %f17

set x5, %l4
ldd [%l4], %f4 ! -1 in f4 und f5

set x3, %l2
ldd [%l2], %f2 ! 0 in f2 und f3

cmp %i0, %l2 ! Wenn 0 denn 0 zurueckgeben
be null
nop

cmp %i0, %l2 ! Wenn kleiner denn -1 zurueckgeben
bl kleiner
nop

fmovs %f9, %f11 ! XALT in f10 und f11
fmovs %f8, %f10 ! XALT = x in f10 udn f11

fmovs %f11, %f13 ! XNEU in f12 und f13
fmovs %f10, %f12 ! XNEU = XALT

fmovs %f9, %f15 ! h in f14 und f15
fmovs %f8, %f14 ! h = x

fdivd %f14, %f10, %f14 ! h = x / XALT
faddd %f12, %f14, %f12 ! XNEU = (XALT + x/XALT)
fdivd %f12, %f16, %f12 ! XNEU = (XALT + x/XALT) / 2.0

fcmpd %f10, %f12 ! Wenn die gleich sind gehe zum Ende
fbe ende
nop

schleife:
fmovs %f13, %f11
fmovs %f12, %f10 ! XALT = XNEU

fmovs %f11, %f13
fmovs %f10, %f12 ! XNEU = XALT

fmovs %f9, %f15
fmovs %f8, %f14 ! x in Hilfsspeicher

fdivd %f14, %f10, %f14 ! h = x / XALT
faddd %f12, %f14, %f12 ! XNEU = (XALT + x/XALT)
fdivd %f12, %f16, %f12 ! XNEU = (XALT + x/XALT) / 2.0

fcmpd %f10, %f12 ! Wenn die ungleich sind, wiederhole schleife
fbne schleife
nop

ende:
fmovs %f12, %f0
fmovs %f13, %f1
jmp %i7+8
restore

kleiner: ! -1 Wenn x kleiner 0
fmovs %f4, %f0
fmovs %f5, %f1
jmp %i7+8
restore

null: ! 0 wenn x 0 ist
fmovs %f2, %f0
fmovs %f3, %f1
jmp %i7+8
restore

main:
set x,%l1 ! Die gewuenschte Zahl ins das Register l1 laden
ldd [%l1],%f2 ! x in %f2, %f3
fsqrtd %f2, %f4 ! Wurzel mit fsqrtd in %f4, %f5
set x2, %l6
std %f4, [%l6] ! (double) wurzel

set fmt, %l0
mov %l0, %o0 ! fmt

std %f2, [%l1] ! double x nach l1+8
ld [%l1], %o1 ! l1+8 nach o1
ld [%l1+4], %o2 ! l1+12 nach o2

ld [%l6], %o3
ld [%l6+4], %o4

call printf
nop

std %f2, [%l1] ! x ins o0 und o1 Register schreiben
ld [%l1], %o0 ! fuer den Unterprogrammaufruf
ld [%l1+4], %o1

call quadratwurzel
nop

std %f0, [%l2]
ld [%l2], %o1
ld [%l2+4], %o2

set fmt2, %l0 ! Zweite Ausgabe
mov %l0, %o0

call printf
nop

set 1,%g1
ta 0

RE: Ausführen eines Assemblerprogramms 2009-01-13 21:04
Anonymer User
Hab das Programm gelöst und funktioniert jetzt. = )

Danke für die vielen Hilfen!

RE: Ausführen eines Assemblerprogramms 2009-01-14 18:14
Rolf
Die Kommandozeilenargumente werden an den Leerzeichen getrennt und dann irgendwo im Speicher abgelegt. Dann wird ein Array angelegt, dass die Startadressen dieser Argumente speichert. Die Startadresse dieses Arrays wiederum steht innerhalb von main in %o1 bzw. in %i1 (falls Du in ein save verwendest).

Wie sieht denn ein Array unter Assembler aus?
Ich kann mir das im Moment nur so vorstellen, dass man eine Startadresse erhaelt, ab der dann in jedem Register ein weiterer Wert des Arrays liegt.
Also, falls z.B. %l1 die Startadresse des Arrays waere, wuerde das erste Elemten in %l1, das Zweite in %l1+8, das Dritte in %l1+16 usw. liegen?

Aber mit dem Gedankengang krieg ich irgendwie nicht den richtigen Wert raus, den ich einlese. [26]

Also, wenn ich z.B. "a.out 5" eingebe, wird die "5" irgendwo im Speicher gespeichert.
Dann wird ein Array mit einem Element angelegt, wo die (Start)Adresse von "5" ist.
Und in %o1 steht dann die (Start)Adresse von dem Array.

Also muss ich den Wert in %o1 als Adresse interpretieren, den Wert auf dieser Adresse wieder als Adresse interpretieren, um dann die "5", die auf der Adresse liegt, abzuspeichern?

Nur leider habe ich gerade keine Ahnung, wie ich das umsetzen soll. [9]

RE: Ausführen eines Assemblerprogramms 2009-01-14 18:21
Fred
Also, falls z.B. %l1 die Startadresse des Arrays waere, wuerde das erste Elemten in %l1, das Zweite in %l1+8, das Dritte in %l1+16 usw. liegen?
Wenn es sich dabei um jeweils 8 Byte große Elemente handelt, ja. (Adressen sind aber z.B. nur 4 Byte groß, und Zeichen nur 1 Byte.)

Also, wenn ich z.B. "a.out 5" eingebe, wird die "5" irgendwo im Speicher gespeichert.
Dann wird ein Array mit einem Element angelegt, wo die (Start)Adresse von "5" ist.
Das Array hat in dem Fall nicht nur einen Eintrag, sondern drei. Der erste Eintrag für "a.out", der zweite Eintrag für "5", und der dritte Eintrag für "" (daran erkennt man, dass keine weiteren Argumente mehr kommen).

Nur leider habe ich gerade keine Ahnung, wie ich das umsetzen soll. [9]
ld [%o1 + 4], %l0          ! %l0 = Adresse des ersten echten Arguments ldub [%l0] , %l1          ! %l1 = Erstes Zeichen davon ldub [%l0 + 1], %l2          ! %l2 = Zweites Zeichen davon ldub [%l0 + 2], %l3          ! %l3 = Drittes Zeichen davon ...

RE: Ausführen eines Assemblerprogramms 2009-01-14 18:49
Rolf
Danke danke!
Es klappt soweit erstmal… denke ich… ausser, dass es mir wahrscheinlich doch zu kompliziert wird…
Ich muss ja anscheinend genau wissen, wie lang meine Zeichenkette ist, um nicht noch irgendwelche willkuerlichen Informationen mit abzugreifen.

Ausserdem gibt er mir den Wert als Ascii-Zeichen raus, wo ich nicht weiss, wie ich das umwandeln soll.

Also, danke erstmal, werd lieber die Hausaufgaben weiter bearbeiten und mich vielleicht ein anderes Mal weiter hiermit beschaeftigen. ^^

RE: Ausführen eines Assemblerprogramms 2009-01-14 19:03
Fred
Ich muss ja anscheinend genau wissen, wie lang meine Zeichenkette ist, um nicht noch irgendwelche willkuerlichen Informationen mit abzugreifen.
Das letzte Zeichen einer Zeichenkette ist immer die 0. Also vergleiche das geladene Byte einfach mit 0, dann weisst Du, ob Du am Ende bist.

Ausserdem gibt er mir den Wert als Ascii-Zeichen raus, wo ich nicht weiss, wie ich das umwandeln soll.
Klar, Argumente sind nichts weiter als Zeichenketten. Wenn Du vom ASCII-Code einer Ziffer wie '5' auf den Wert 5 kommen willst, ziehe einfach 48 ab (ab 48 fangen die Ziffern 0 bis 9 im ASCII-Code an).