fb18.de
/ Diplom Informatik
/ Unterbereich Grundstudium
/ Technische Informatik
printf-Befehl in Assembler!
Irgendwie kriege ich immer "Segmentation fault" wenn ich call printf verwende.
Kann mir jemand vielleicht kurz sagen wie ein Programm aussehen muss, dass printf verwendet ??? Vor allem welche direktiven ich brauche wäre interessant zu wissen.
Das Problem hatte ich heute auch:
sethi %hi(.foo),%o0
or %o0,%lo(.foo),%o0
call printf
nop
segfault,
sethi %hi(.foo),%l1
or %l1,%lo(.foo),%l1
call printf
mov %l1,%o0
klappt aber.
Und wo ist der Unterschied? *confused*
Ersteres segfaultet, zweiteres nicht. ;)
Nein, keine Ahnung, ich hatte Fred schon per Mail gefragt, aber bisher noch keine Antwort erhalten.
Irgendwie kriege ich immer "Segmentation fault" wenn ich call printf verwende.
Wie sehen die relevanten Codezeilen aus?
Hast Du am Anfang ein
.global printf
eingebaut?
Ersteres segfaultet, zweiteres nicht. ;)
EDIT: Ihr ruft printf mehrmals in einer Schleife auf. printf verändert aber den Inhalt von %o0, deswegen muss es jedesmal neu reingeladen werden. Ob Ihr das nun vor der Schleife in ein Register packt oder während der Schleife erst umständlich per sethi/or sollte dabei egal sein.
Nein, keine Ahnung, ich hatte Fred schon per Mail gefragt, aber bisher noch keine Antwort erhalten.
Also hier ist keine Mail eingegangen.
EDIT: argh, Du hast die eMail an meine uni-Adresse geschickt, die ich ca. 1x pro Semester abrufe. Ich hatte doch beim ersten Übungstermin meine gmx-Adresse bekannt gegeben.
sethi %hi(.foo),%o0
or %o0,%lo(.foo),%o0
call printf
nop
segfault,
Das muss am umliegenden Code liegen (falls es nicht das ist, was Fred schon meinte):
$ cat foo.s
.section ".text"
.global main
main:
sethi %hi(foo),%o0
or %o0,%lo(foo),%o0
call printf
nop
or %g0, 1, %g1
ta 0
.section ".data"
foo:
.asciz "FOO\n"
$ cc foo.s -o foo
$ ./foo
FOO
Ersteres segfaultet, zweiteres nicht. ;)
EDIT: Ihr ruft printf mehrmals in einer Schleife auf. printf verändert aber den Inhalt von %o0
Ah, ok, das war mir neu.
Dann ist die Lösung wie wir sie jetzt haben ja eh besser. :)
EDIT: argh, Du hast die eMail an meine uni-Adresse geschickt, die ich ca. 1x pro Semester abrufe. Ich hatte doch beim ersten Übungstermin meine gmx-Adresse bekannt gegeben.
GMX-Addies ignoriere ich, es gibt ja bessere Ikum-Adressen… ;)
Wieso richtest du dir kein .forward ein?
Dann ist die Lösung wie wir sie jetzt haben ja eh besser. :)
Ja, was den Punkt betrifft ist sie gut. Sie ist aber nicht perfekt. Von daher ideal zum Präsentieren [img]
http://www.fb18.de/gfx/25.gif[/img]
Wieso richtest du dir kein .forward ein?
Der Spam soll nicht geforwardet werden [img]
http://www.fb18.de/gfx/22.gif[/img]
Ok die Ausgabe von Triphoenix funktioniert, wenn ich allerdings versuche beispielsweise einen Hexadezimalwert auszugeben, dann kriege ich wieder Segmentation Fault. Welche direktiven muss ich denn da setzen?
du kannst als 1. argument keinen hexwert übergeben. das muss ein char[] (bzw char*) sein "%x" oder so. in %o1 kannst du dann den integer wert packen der ausgegeben werden soll..
hex war ein Beispiel, bei mir klappt aufgrund des Fehlers nichtmal die einfach Ausgabe des Integers den ich mit dem Hauptprogramm übergebe.Wie gesagt kein Plan in Sachen direktiven :(
hex war ein Beispiel, bei mir klappt aufgrund des Fehlers nichtmal die einfach Ausgabe des Integers den ich mit dem Hauptprogramm übergebe.Wie gesagt kein Plan in Sachen direktiven :(
Reduzier es mal auf die einfache Ausgabe, also so dass es mit dem abzugebenden nichts mehr zu tun hat uns poste es, dann finden wir das Problemchen schon :>
Wenn du übrigens einen String zum ausgeben in der Datei unterbringen willst muss das in der Section .data oder .rodata liegen, vielleicht wars das ja schon.
.section ".text"
.global blabla
blabla:
sethi %hi(test),%o0
or %o0,%lo(test),%o0
call printf
nop
.section ".rodata"
test:
.asciz "test\n"
———————————————————–
Das wäre ja die Ausgabe eines Textes, das ist ja auch soweit klar. Aber wenn ich bei asciz nun versuche %i0 auszugeben, was ansich der Integer vom Hauptprogramm sein sollte, dann bekomme ich nen negativen ganz hohen Wert. Ich würd aber gerne einfach mal meinen Integer sehen oder hab ich das falsche Register?
%i0 ist schon der Parameter, wie gibst du den dann aus?
Also Format muss "%d" als String vorhanden sein, %o0 bliebt die Adresse des Strings, in %o1 kommt deine Zahl.
.asciz "%i0"
so hab ich das ganz einfach versucht, aber irgendwie scheine ich da etwas grundlegend falsch zu verstehen.
.section ".text"
.global mist
mist:
sethi %hi(test),%o0
or %o0,%lo(test),%o0
mov %i0, %o1
call printf
nop
restore
.section ".rodata"
test:
.asciz "%d\n"
Also wenn ich's richtig verstanden habe, dann so. Allerdings kommt dann als Wert 1, obwohl ich 3 erwartet hätte.
Jetzt hab ich's es fehlte noch
save %sp,-120,%sp
Fügt man die Zeile ein, so bekommt man den richtigen Paramter wieder. Endlich
Jetzt hab ich's es fehlte noch
save %sp,-120,%sp
Fügt man die Zeile ein, so bekommt man den richtigen Paramter wieder. Endlich
Stimmt das hatte ich ja ganz übersehen… Denn ohne save heißt %o0 (wo der Parameter für die Funktion liegt) ja immernoch %o0 und nicht %i0 wie man das gerne in der Unterfunktion hätte.
-64 tuts übrigens auch, wenn du nicht absichtlich speicher nutzen willst, die Zahl gibt den zu reservierenden Speicherplatz für die Funktion an, 64 Byte verlangt das Betriebssystem.
EDIT: Ihr ruft printf mehrmals in einer Schleife auf. printf verändert aber den Inhalt von %o0
Ah, ok, das war mir neu.
Gerade von Lehmann gelernt: in %o0 wird die Anzahl ausgegebener Zeichen zurückgegeben.
Steht auch im Standard, K&R und unter "man printf".
Mo