FB18 - Das Forum für Informatik

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

T3 Blatt 4

T3 Blatt 4 2003-11-12 14:17
Fred
Hi,

hier der offizielle Thread zum Aufgabenblatt 4, welches ab heute abend zum Download bereit stehen sollte.

Re: T3 Blatt 4 2003-11-16 13:52
Fred
Hier wie versprochen noch mal ein Kommentar zum Code von Skript S. 174. Da es gut zum Aufgabenblatt 4 passt, poste ich es hier und mache keinen Extra Thread auf.

Kommentare in der Form (a) > (b) © zeigen den Momentanen Zustand des Stacks an - zuletzt wurde c gepusht, davor b, davor a. Der TOS (Top Of Stack) ist also rechts. Das ">" Zeichen zeigt an, wohin %ebp zeigt. ra ist die return adress.

rfact: ; (x) (ra) Beim Eintritt in die Funktion liegen x und die rae auf dem Stack (das hat der Caller besorgt). ebp zeigt noch auf nichts definiertes.

pushl %ebp ; (x) (ra) (old %ebp) Der erste Befehl sichert den alten Inhalt von %ebp auf den Stack.

movl %esp, %ebp ; (x) (ra) > (old %ebp) Dann wird %ebp = %esp zugewiesen, womit %ebp auf dan zuletzt gepushten Wert zeigt (nämlich das alte %ebp), symbolisiert durch das ">" Zeichen. Da jeder Stackeintrag 4 Byte gross ist, lässt sich folgendermassen auf die Elemente zugreifen:

(%ebp) -> old %ebp
4(%ebp) -> ra
8(%ebp) -> x

pushl %ebx ; (x) (ra) > (old %ebp) (old %ebx) Nun sichern wir das Register %ebx, weil wir es im Verlauf der Funktion benutzen wollen und der Callee laut Konvention für das Sichern von %ebx verantwortlich ist. Der Zugriff wäre nun:

-4(%ebp) -> old %ebx
(%ebp) -> old %ebp
4(%ebp) -> ra
8(%ebp) -> x

movl 8(%ebp), %ebx ; das Argument der Funktion nach %ebx laden cmpl $1, %ebx ; ist die übergebene Zahl <=1 ? jle .L78 ; ...dann springe zu L78 Warum der Vergleich mit 1? Weil wir die Fakultät von x<=1 kennen, sie ist 1. Ich glaube, das nennt man Rekursionsverankerung…?

leal -1(%ebx), %eax ; neues x ist altes x-1 pushl %eax ; (x) (ra) > (old %ebp) (old %ebx) (new x) call rfact ; (x) (ra) > (old %ebp) (old %ebx) (new x) (new ra) imull %ebx, %eax ; x! = (x-1)! * x jmp .L79 Dies ist der rekursive Aufruf: Wir berechnen die Fakultät von x, indem wir die Fakultät von x-1 ausrechnen und mit x multiplizieren.

.align 4 ; an durch 4 teilbaren Adressen ausgerichtete Labels ; ...bringen Performancevorteile beim Springen .L78: ; hier wird hingesprungen, falls x<=1 war movl $1, %eax ; x! = 1 für x<=1 .L79: ; (x) (ra) > (old %ebp) (old %ebx) (new x) movl -4(%ebp), %ebx ; altes %ebx wieder herstellen movl %ebp, %esp ; (x) (ra) > (old %ebp) popl %ebp ; (x) > (ra) ret ; (x)
Die Zeilen ab .L79 hätte man imho auch durch

.L79 ; (x) (ra) > (old %ebp) (old %ebx) (new x) popl %ebx ; (x) (ra) > (old %ebp) (old %ebx) popl %ebx ; (x) (ra) > (old %ebp) popl %ebp ; (x) (ra) ret ersetzen können. Any comments?

Re: T3 Blatt 4 2003-11-16 19:22
GroßerSchöpfer
ganz hilfreich, aber leider Intel Syntax:

http://www.jegerlehner.ch/intel/index.html

Re: T3 Blatt 4 2003-11-17 14:38
Anonymer User
kann mir jemand folgendes erklären:

Da im bisher eingef¨uhrten Befehlssatz f ¨ ur unseren x86-Prozessor noch kein Befehl f ¨ ur die Division
enthalten ist, n¨ahern wie den Umrechnungsfaktor 5/9 durch den Wert 5/9  142/256 an, der
sich zum Beispiel mit einer Multiplikation und einem Rechts-Shift effizient umsetzen l asst.

was genau is da mit der Multiplikation und einem Rechts-Shift gemeint? kann mir das bitte wer erklären wie ich das umsetzen soll?
danke

Re: T3 Blatt 4 2003-11-17 15:03
Anonymer User
kann mir noch mal jemand

pushl %ebx ; (x) (ra) > (old %ebp) (old %ebx)

Nun sichern wir das Register %ebx, weil wir es im Verlauf der Funktion benutzen wollen und der Callee laut Konvention für das Sichern von %ebx verantwortlich ist. Der Zugriff wäre nun: -4(%ebp) -> old %ebx (%ebp) -> old %ebp 4(%ebp) -> ra 8(%ebp) -> x
movl 8(%ebp), %ebx ; das Argument der Funktion nach %ebx laden
cmpl $1, %ebx ; ist die übergebene Zahl <=1 ?
jle .L78 ; …dann springe zu L78

Warum der Vergleich mit 1? Weil wir die Fakultät von x<=1 kennen, sie ist 1. Ich glaube, das nennt man Rekursionsverankerung…?

erklären? warum genau bzw wie kommt man auf movl 8(%ebp), %ebx

Re: T3 Blatt 4 2003-11-17 16:18
Fred
was genau is da mit der Multiplikation und einem Rechts-Shift gemeint?

Die Division ist bei den meisten Prozessoren entweder deutlich langsamer als Multiplikation (und erst recht als einfache Operationen wie Addition oder Bitshifts), oder sogar gar nicht erst vorhanden.
Deshalb bedient man sich eines Tricks: wenn man durch eine Zahl dividieren will, multipliziert man mit dem Kehrbruch (kennt Ihr aus der Schule). Den Kehrbruch richten wir jetzt so ein, dass der Nenner eine Zweierpotenz ist, weil das Teilen durch Zweierpotenzen mit Shiften nach rechts sehr effizient realisiert werden kann (T1 Stoff?).
Wenn Du also konkrekt a * (142/256) rechnen sollst, dann sagst Du der CPU, dass sie a mit 142 multiplizieren soll (dafür gibts den imull Befehl), und anschliessend shiftest Du das Ergebnis um 8 nach rechts (sarl $8, reg), denn 2^8 = 256. Klar?

warum genau bzw wie kommt man auf movl 8(%ebp), %ebx
Der Caller übergibt dem Callee die Argumente auf dem Stack. Das erste (und in diesem Fall das einzige) Argument wird zuletzt gepusht und hätte sofort danach die Adresse (%esp). Der anschliessende call-Befehl pusht aber noch die Rücksprungadresse auf den Stack, deswegen zeigt (%esp) jetzt auf die Rücksprungadresse und 4(%esp) auf das erste Argument. Der Callee selbst pusht nochmal %ebp auf den Stack, weswegen (%esp) jetzt %ebp enthält, 4(%esp) die Rücksprungadresse und 8(%esp) das erste Argument. Danach wird %ebp = %esp zugewiesen, so dass wir mit 8(%ebp) auf das erste Argument zugreifen können. Jeder weitere push ändert jetzt nichts mehr an dieser Adressierung, weil %ebp ja nicht von push beeinflusst wird.

Re: T3 Blatt 4 2003-11-17 17:31
Anonymer User
danke :-)

Re: T3 Blatt 4 2003-11-17 19:39
UncleOwen
http://tams-www.informatik.uni-hamburg.de/lehre/ws2003/vorlesungen/t3/aufgaben/Aufgabenblatt_04.pdf

Ich hab so meine Probleme mit Aufgabe 2:

"Schreiben Sie x86-Assemblercode fuer eine Funktion […], die […] ihren Rueckgabewert wie in der Vorlesung erlaeutert auf dem Stack uebergibt."

Ich mag mich taeuschen, aber haben wir in der Vorlesung was anderes als Ruckgabe ueber eax besprochen? Wie soll das ablaufen?

"Nach Ausfuehrung der Funktion sollen alle Datenregister (eax, ebx, …) wieder ihren vorherigen Wert enthalten"

Warum soll ich auch die Register, die eindeutig als caller-save festgelegt sind (eax, edx, ecx), sichern? Wenn der Aufrufer sie noch braucht, hat er sie selber zu sichern, wenn er das nicht tut, ist das nicht meine Schuld…

Re: T3 Blatt 4 2003-11-17 20:03
low_level
"Schreiben Sie x86-Assemblercode fuer eine Funktion […], die […] ihren Rueckgabewert wie in der Vorlesung erlaeutert auf dem Stack uebergibt."

pushaddr "%d\n" pushl grad_fahrenheit pushl 0 ; Hier kommt der Rückgabewert rein call celsius nop ; branch delay ;-) Es lebe die SPARC! call printf
Hmmm, der Code erinnert mich ein wenig an Postscript. Aber ich glaube, in Turbo Pascal wurde das so gemacht, wenigstens für Records als Rückgabewerte.

low_level

Re: T3 Blatt 4 2003-11-17 20:09
UncleOwen
Ne, der Prototyp der Funktion ist ja vorgegeben. Und das waere dann ja void celsius(int*, int) statt int celsius(int).

Re: T3 Blatt 4 2003-11-17 20:18
TriPhoenix
Ne, der Prototyp der Funktion ist ja vorgegeben. Und das waere dann ja void celsius(int*, int) statt int celsius(int).

Nein, int * auch nciht, denn dann wäre aufm Stack ein Pointer auf die Speicheradresse. Ich galube C hat keine notation dafür [img]http://unimatix.sternenvolk.de/gfx/28.gif[/img]

Re: T3 Blatt 4 2003-11-17 20:38
UncleOwen
jo, hast Recht.

Re: T3 Blatt 4 2003-11-17 20:42
Fred
Ich mag mich taeuschen, aber haben wir in der Vorlesung was anderes als Ruckgabe ueber eax besprochen?
Nein. Und die gängigen Calling Conventions (cdecl, stdcall, fastcall) arbeiten auch alle mit eax als Rückgabewert.

Warum soll ich auch die Register, die eindeutig als caller-save festgelegt sind (eax, edx, ecx), sichern?
Schreib 1-2 Sätze diesbezüglich zu Deiner Lösung. Studenten, die sich Gedanken machen, sind immer gern gesehen ;-)

Re: T3 Blatt 4 2003-11-17 21:01
low_level
Ne, der Prototyp der Funktion ist ja vorgegeben. Und das waere dann ja void celsius(int*, int) statt int celsius(int).

Ja und? Was sagt der Prototyp über die Implementation aus? garnichts.

Gegenbeweise mit Zitat aus dem C-Standard nehme ich gerne entgegen.

Außerdem: Das soll keine C-Funktion sein, sondern eine Assemblerfunktion. Und da ist das mit den Calling Conventions ja nicht ganz so standardisiert …

low_level

Re: T3 Blatt 4 2003-11-17 21:04
Fred
Für alle Studenten, die bei mir abgeben: ich akzeptiere auf jeden Fall Lösungen, die sich an das Skript halten, sprich: Rückgabewert in eax, Sichern nur von ebx, esi und edi.

Re: T3 Blatt 4 2003-11-18 16:20
Antje
Hallo!

Kann mir mal einer nen Tipp zu Aufgabe 1 geben???
Kann man denn den %eip aufm Stack zwischenspeichern?
Oder was gibt es sonst für Möglichkeiten an den ranzukommen?

Antje

Re: T3 Blatt 4 2003-11-18 16:30
UncleOwen
Bei uns in der Uebungsgruppe gabs den Tip, sich mal zu ueberlegen, welche Befehle ueberhaupt irgendwas mit eip machen:
CALL, RET, JMP, Jcc (also die conditional jumps) - mehr hatten wir noch gar nicht, oder?

Re: T3 Blatt 4 2003-11-18 17:09
Antje
War dir das ne große Hilfe? Hab jedenfalls noch nicht die zündende Idee…

Re: T3 Blatt 4 2003-11-18 17:34
UncleOwen
War dir das ne große Hilfe?

Kann ich nicht sein, ich wusste es vorher schon [img]http://unimatix.sternenvolk.de/gfx/22.gif[/img]

Aber ueberleg Dir mal, was _genau_ die 4 Befehle unten machen. Einer davon kopiert eip irgendwo anders hin, wo man dann drauf zugreifen kann.

Re: T3 Blatt 4 2003-11-18 18:15
Anonymer User
bei Aufgabe 4.3.1
welche C-syntax is dort gemeint?
da steht zwar C-Bibliothek <string.h>
aber wo soll die stehen??

Re: T3 Blatt 4 2003-11-18 18:21
TriPhoenix
Das braucht nirgends stehen. Das soll nur verdeutlichen, um was für eine Funktion für C-Kenner sich es handelt. Was da von Syntax-gesprochen wird, heißt, dass sobald die Zeichenkette vorbei ist, steht einfach eine dicke fette 0 im Speicher. Daran kann den Code dann erkennen, wo die Zeichenkette vorbei ist.

Re: T3 Blatt 4 2003-11-18 19:01
Anonymer User
kann mir noch mal wer folgende zeilen genauer erklären?
so zeile für zeile.

.L79: ; (x) (ra) > (old %ebp) (old %ebx) (new x)
movl -4(%ebp), %ebx ; altes %ebx wieder herstellen
movl %ebp, %esp ; (x) (ra) > (old %ebp)
popl %ebp ; (x) > (ra)
ret ; (x)

Re: T3 Blatt 4 2003-11-18 19:17
Anonymer User
Bei uns in der Uebungsgruppe gabs den Tip, sich mal zu ueberlegen, welche Befehle ueberhaupt irgendwas mit eip machen:
CALL, RET, JMP, Jcc (also die conditional jumps) - mehr hatten wir noch gar nicht, oder?

Entschuldigt, aber weiss jemand, wo Befehle wie CALL, RET, JMP, Jcc näher beschrieben werden? Ich meine in Bezug auf %eip finde ich nicht viel.

Im Skript ist das ja (wenn überhaupt) alles mehr schlecht als recht dargestellt, und irgendwie fehlt mir da gerade was, wo das ein bischen exakter erklärt wird.

Gab es vielleicht in der Vorlesung noch Material, was ich irgendwie verpennt habe? Ich meine nur Anhand des Skriptes finde ich das ziemlich schwierig…

Gruß Dosenwein

Re: T3 Blatt 4 2003-11-18 19:27
TriPhoenix
Entschuldigt, aber weiss jemand, wo Befehle wie CALL, RET, JMP, Jcc näher beschrieben werden? Ich meine in Bezug auf %eip finde ich nicht viel.

Im Skript ist das ja (wenn überhaupt) alles mehr schlecht als recht dargestellt, und irgendwie fehlt mir da gerade was, wo das ein bischen exakter erklärt wird.

Gab es vielleicht in der Vorlesung noch Material, was ich irgendwie verpennt habe? Ich meine nur Anhand des Skriptes finde ich das ziemlich schwierig…

Im zweiten Intel-Manual:
http://www.intel.com/design/pentium4/manuals/

stehts ganz genau drin [img]http://unimatix.sternenvolk.de/gfx/28.gif[/img]

Re: T3 Blatt 4 2003-11-18 19:29
UncleOwen
Im zweiten Intel-Manual:
http://www.intel.com/design/pentium4/manuals/

stehts ganz genau drin [img]http://unimatix.sternenvolk.de/gfx/28.gif[/img]

Und Du meinst wirklich, das versteht jemand?

Re: T3 Blatt 4 2003-11-18 19:39
TriPhoenix
Im zweiten Intel-Manual:
http://www.intel.com/design/pentium4/manuals/

stehts ganz genau drin [img]http://unimatix.sternenvolk.de/gfx/28.gif[/img]

Und Du meinst wirklich, das versteht jemand?

Wenn man sich auf den in der Vorlesung behandelte near jumps/calls/rets beschränkt, ja.

Re: T3 Blatt 4 2003-11-18 19:39
Anonymer User
hallo,
kann mir wer noch mal genauer erklären wie ich aufgabe 4.3.1
angehen soll?

Re: T3 Blatt 4 2003-11-18 19:44
UncleOwen
Man nehme einen Zeiger, geht mit dem Zeichen fuer Zeichen durch den String, bis man das Stringende (=0) findet. Waehrenddessen zaehlt man mit, oder man bestimmt am Ende den Abstand zwischen Stringende und Stringanfang.

Re: T3 Blatt 4 2003-11-18 20:13
Dosenwein
Im zweiten Intel-Manual:
http://www.intel.com/design/pentium4/manuals/

Naja, ich denke das ist wirklich SEHR ausführlich. Aber bestimmt für manche Dinge nützlicher als dieses tolle Skript.

Da stehen die Sachen manchmal so komprimert drauf, das man sich das Skript auch sparen könnte. Mal ganz zu schweigen davon, das die Skript-Sprache so gehackt ist, das man manchmal 10 Minuten nachdenken muss, bis man darauf kommt, was der Autor vielleicht damit gemeint hat. [img]http://unimatix.sternenvolk.de/gfx/17.gif[/img]


Re: T3 Blatt 4 2003-11-18 20:17
Anonymer User
Man nehme einen Zeiger, geht mit dem Zeichen fuer Zeichen durch den String, bis man das Stringende (=0) findet. Waehrenddessen zaehlt man mit, oder man bestimmt am Ende den Abstand zwischen Stringende und Stringanfang.

Wie man nehme einen Zeiger? Sollen wir das Programm etwa in C schreiben, und das dann mit gcc in einen Assembler-Code umwandeln?? Dann könnte ich mit nem Zeiger auch was anfangen…


Re: T3 Blatt 4 2003-11-18 20:22
TriPhoenix
Man nehme einen Zeiger, geht mit dem Zeichen fuer Zeichen durch den String, bis man das Stringende (=0) findet. Waehrenddessen zaehlt man mit, oder man bestimmt am Ende den Abstand zwischen Stringende und Stringanfang.

Wie man nehme einen Zeiger? Sollen wir das Programm etwa in C schreiben, und das dann mit gcc in einen Assembler-Code umwandeln?? Dann könnte ich mit nem Zeiger auch was anfangen…

Wenn du eien Speicheradresse in ein Register packst, hast du auch einen Zeiger. Und eine Speicheradresse bekommst du ja als Parameter übergeben.

Re: T3 Blatt 4 2003-11-18 21:47
Fred
War dir das ne große Hilfe? Hab jedenfalls noch nicht die zündende Idee…
Was unterscheidet denn den Call Befehl von dem Jump Befehl?

kann mir noch mal wer folgende zeilen genauer erklären?
so zeile für zeile.

Hier nochmal die aktuellen Werte auf dem Stack und ihre Indizes relativ zu %ebp in Bytes:

8 4 0 -4 -8 .L79: ; (x) (ra) > (old %ebp) (old %ebx) (new x)
Zur besseren Veranschaulichung ein vertikaler Stackaufbau und die Adressierung:

8(%ebp) x (argument pushed by caller) 4(%ebp) ra (return address pushed by CALL operation) (%ebp) old %ebp (saved by callee) -4(%ebp) old %ebx (saved by callee) -8(%ebp) new x (argument pushed by caller and already processed by callee)
movl -4(%ebp), %ebx ; altes %ebx wieder herstellen
Also im Kommentar steht ja eigentlich schon alles - wir hatten am Anfang der Funktion ebx auf den Stack gepusht und danach verändert, also müssen wir den alten Wert wieder herstellen.

movl %ebp, %esp ; (x) (ra) > (old %ebp)
Hier wird der Stackpointer wieder restauriert - den hatten wir am Anfang der Funktion in ebp gesichert und anschliessend durch den pushl %ebx und "pushl new x" verändert.

popl %ebp ; (x) > (ra)
Hier wird das alte ebp, welches wir zu Beginn der Funktion gesichert hatten, wieder hergestellt.

ret ; (x)
Das Unterprogramm wird beendet, indem die return adress vom Stack geholt und dort hin gesprungen wird.

Entschuldigt, aber weiss jemand, wo Befehle wie CALL, RET, JMP, Jcc näher beschrieben werden? Ich meine in Bezug auf %eip finde ich nicht viel.
Such mal bei google oder hier im UniMatiX nach [edit]

Hm, ist vielleicht etwas überdimensionert. Wie wäre es mit
http://ivs.cs.uni-magdeburg.de/bs/lehre/sose99/bs1/seminare/assembler.shtml

Auch hier gilt natürlich wieder: Vorsicht INTEL Syntax.

Re: T3 Blatt 4 2003-11-19 09:03
Anonymer User
moinsen,

das bei Aufgabe 4.3.x den String begrenzende Nullzeichen..ist "vier Byte lang" der Wert 0 oder wie soll man sich das vorstellen ?

Danke ;)

Re: T3 Blatt 4 2003-11-19 12:22
UncleOwen
Genau.

Re: T3 Blatt 4 2003-11-20 13:32
Anonymer User
// edit Slater-Übersetzung: Das ist ja alles nicht so einfach.

Knuffe Euch und hab Euch lieb

Re: T3 Blatt 4 2003-11-20 13:58
TriPhoenix
Was will uns das genau sagen? Ich glaube solche ausbrüche kannst du sinnvoller posten

cat > /dev/null
<hier der wutausbruch>
^D

[img]http://unimatix.sternenvolk.de/gfx/24.gif[/img]