klausur 02/2003

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

klausur 02/2003
next one:

1) name MUELLER, punkte 50, note 2 (2 dummybytes wegen alignment zwischen name und punkte); big endian, da die note sonst 2^30 waere (unwahrscheinlich)

2a) 5 bit
2b) 5 bit
2c) 13 bit
2d) 16 bit
2e)
movl $0x12345678, %r1
movl (%r1), %r0

3i)
movb x, %al
shlb $4, %al
subb x, %al
movb %al, y
3ii) bis zu 15 = 1111 (2), da um 4 stellen geshiftet wird und keine 1 rausgeshiftet werden darf, ohne das ergebnis zu verfaelschen.

4) 14+4 takte am anfang, 10 mal 16 takte pro schleife, 9 takte am schluss -> 187 takte, 18,7 mikrosekunden

5)
ggt:
movl 8(%esp), %eax     # a in %eax
movl 4(%esp), %ebx     # b in %ebx
cmpl %ebx, %eax     # vergleich a mit b
jl kleiner
jg groesser
jmp ende     # ansonsten liegt a schon in %eax
kleiner:
pushl %eax     # a
subl %eax, %ebx     # b-a
pushl %ebx
call ggt
addl $8, %esp     # parameter freigeben
jmp ende     # returnwert schon in %eax
groesser:
pushl %ebx     # b
subl %ebx, %eax     # a-b
pushl %eax
call ggt
addl $8, %esp     # parameter freigeben
jmp ende     # returnwert schon in %eax
ende:
ret

6) schwer zu beschreiben, das zweite nibble muss halt mit 10 multipliziert werden, dies geschieht durch einen einfachlinksshift und dazu die addition von einem dreifachlinksshift. dann entsprechend addieren lassen.

so,
dazu gleich mal 2 fragen:

1.) wenn ich

cmpl %ebx, %eax     # vergleich a mit b
jl kleiner
jg groesser

schreibe, kann ich das so lassen und bleiben die condition codes auch nach dem jl noch gesetzt oder muss ich zwischen jl und jg nochmal einen cmpl-befehl hauen?

2.) was ist denn nochmal der unterschied zwischen einem halb- und einem volladdierer? war ein halbaddierer ein volladdierer ohne carryeingang?


also zu 3b ne Frage:Hab die 3a mit addieren von sich selbst gemacht (wie im Skript).
Deswegen war meine Folgerung für die 3b:
16x < 2^9 (bis 2^8 geht ja 1 Byte)
=> x<32

Oder sehe ich da was falsch?


Ich habe die Aufgabe auch durch mehrmalige Addition gelöst:

movb   x, %al
addb %al, %al
addb %al, %al
addb %al, %al
addb %al, %al
subb   x, %al
movb %al,   y

Damit kann 0<=x<=17 sein, da der Überlauf bei der letzten Additon durch die nachfolgende Subtraktion kompensiert wird.
Allerdings kann x nie größer als 17 werden, da das Ergebnis dann nicht mehr in 8 Bit gespeichert werden kann.


Wie soll das funktionieren dass das sub den carry kompensiert?
Wenn du addierst und es kommt zu einem carry-bit dann ist die gegebene Zahl knapp größer als 00000000!
Wenn du da dann mit sub was abziehst hättestt du ja eine negative Zahl!?Aber nicht das richtige Ergebnis!


ich verstehe deinen ansatz nicht ganz, den muesstest du nochmal genauer posten. auf jeden fall muessen die 16 mal x ja in 6 bit gespeichert werden koennen, auch wenn du danach wieder etwas davon abziehst. deshalb wuerde ich schreiben
16x < 2^8
=> x<16 => x maximal 15


hmm, hab das gerade mal durchgerechnet und es geht tatsaechlich, obwohl es meiner meinung nach nicht ganz sauber ist: bei der letzten add-op entsteht ja ein carry, das du aber nicht weiter beachtest. durch das abziehen entsteht eigentlich ein negatives ergebnis, wenn dies als positives interpretiert wird, (1111.1111 bei x=17) stimmt es aber. also hast du eigentlich recht. dein programm ist aber ineffizient, die 4 addlbefehle kannst du durch ein shlb $4, %eax ersetzen.


Die negative Zahl, die sich bei der Subtraktion ergibt ist genau das gewünschte Ergebnis, wenn man die Zahl als unsigned betrachtet. Das ist ja das tolle am rechnen mit dem (B-1)-Komplement (bei der Subtraktion):[list]
[]wenn man vom Minimum des Zahlenbereiches eins abzieht erhält man das Maximum
[
]wenn zum Maximum eins dazuaddiert, kommt man zum Minimum
[/list]

Richtig. Ich habe beim meiner Implementierung an den Mitsubishi-Prozessor gedacht, der sowieso nur 1-fach-Shift-Befehle kennt. Die Aufgabe läßt auf jeden Fall mehrere Lösungen zu.


Kannst du so lassen. Die Sprungbefehle verändern keine Flags, ich hab’s ausprobiert.


perfekt! das spart doch schon mal wieder einige zeilen. danke fuers ausprobieren!


Hab gedacht da es ein 8-Bit Rechner ist kann die zahl genau bis 2^8 gehen.Und die 16 x ist der Maximale Wert den man erreicht bei der Addition mit sich selbst!
Aber vielleicht/wahrscheinlich is es dann falsch!


Wi kommt man bei Aufgabe 4 auf die 14+4 am anfang? 14 hab ich auch, aber woher 4?


Hab ich zwar hier schon irgendwo mal erklärt, aber nochmal:

Du hast die 14; der letzte Aufruf war aber ein jmp cont-> deswegen springst du runter zu cont !!!Und da sind die restlichen 4 Takte (cmp …, jl…).
Und erst dann fängst du oben mit dem loop an!


Hi!Noch ne kurze Frage:
Wie viele Takte braucht ein jmp-Befehl?Ich hab gedacht 2 , aber eigentlichspringt man ja im Speicher an eine andere Adresse?


ändert man da nicht einfach den InstructionPointer (Register)? Das holen der Instruktion gehört ja laut angabe schon zu den zwei Takten.


jou, so wuerde ich das auch sehen. ist natuerlich immer mehrdeutig so eine aufgabe, aber es kommt ja auf die argumentation an, die du hinschreiben kannst, wenn du noch zeit dafuer hast.


Zur 2)
Wie kommt man auf die 5 Bit / 13 Bit / 16 Bit?

Da WELL '4


Ist nicht 'Schnelle Multiplikation genau das Verfahren mit immer durch 2 teilen und am Schluss von allen ungeraden das nochmal dazu addieren(schon klar das du das mit dem Shift gut abkürzt, aber wollen die das evtl genau so und nicht anders(also mit adds, Schritt für Schritt))
Also wollen die evtl gleich noch ein bissl Theorie abfragen, oder gibts Extra-Pkte auf effizientere Algorihtmen?


shiften is immer gut, wie ich mitgeschrieben hab, im 2ten semester? war ne klausuraufgabe, ne vorgegebene zahl mit 254 zu multiplizieren. Wenn du da nach der schnellen multiplikation das hinschreibst brauchst du ewig (soviel platz is garned aufm papier). einfach die zahl um 8bits shiften (= mit 256 multiplizieren) und dann zweimal die ursprüngliche zahl abziehn. Wenn man sowas verstanden hat und weis wie n framepointer aufgebaut ist, hat man die klausur im prinzip bestanden. Is ne klausur zum denken, nicht zum stupiden auswendig gelerne. Was auch lustig war, war ne aufgabe wo se uns n assemblercode gegeben haben und man sagen sollte was der code macht … und da war ne endlosschleife miteingebaut g