2010-09-29 - Aufgabe 07 Assembler-Programmierung

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.

2010-09-29 - Aufgabe 07 Assembler-Programmierung
Vereinfachen Sie den folgenden bedingten Ausdruck und stellen Sie ihn nur mit Hilfe von if-then-goto-/goto-Anweisungen dar! (6 Punkte)

if (((a > 0) && (b > 0)) || ((a < 0) && (b < 0)))
x();
else y();

[color=blue]

if(!(a>0)) goto secondtry;
if(!(b>0)) goto secondtry;
goto do_stuff;
secondtry:
if(!(a<0))  y();
    if(!(b<0))  y();
        dostuff:     x();

[/color]

Ein Compiler habe folgenden Assembler-Code generiert:

func:

cmpl $0, 4(%esp)

jle error

movl $0, %eax

movl $1, %edx

loop:

addl %edx, %eax

addl $1, %edx

cmpl %edx, 4(%esp)

jge loop

jmp end

error:

movl $-1, %eax

end:

ret

Wie könnte der dazugehörige Hochsprachen-Code ausgesehen haben?
(10 Punkte)

[color=blue] if(a[2] <= 0) { return -1;} int i = 1; int y = 0; do { y += i; i++;} while ( i < a[2] ); return y; [/color]


IMHO geht hieraus nicht hervor, dass nach x() bzw. y() das Programm an der selben Stelle weitermacht. Außerdem würde ich Funktionsaufrufe nicht mit Sprungmarken vermischen („goto y()“).


gibts da einen trick für doofe?


Meines Wissens nach ist 4(%esp) der erste Aufrufparameter, d.h. du hast so was wie

int func ( int x ){
if(x <= 0) {return -1;}
...
while(i <= x);
return y;
}

Du meinst wahrscheinlich 8(%ebp)*. 4(%esp) dürfte einfach nur der vorletzte dem Stack hinzugefügte Wert sein.

Aber du hast recht dass a[2] eher unpassend ist:
Wenn 4(%esp) = a[2], dann wäre (%esp) = a[1] und a[0] wäre unterhalb des Stackpointers also eigentlich ungültig…

(* eine übliches Schema ist, dass (%ebp) den gesicherten %ebp enthält, dann folgt die Rücksprungadresse, dann die Aufrufparameter)


Nach den Folien (http://www3.informatik.uni-erlangen.de/Lehre/GRa/SS2010/Gra_Kap_4.pdf, Folie 45ff.) sollte das schon der Parameter sein :slight_smile:
Hier wird halt davon ausgegangen, dass kein Frame-Pointer-Zeug gemacht wird.


[...]
my_then:
x();
goto end;
my_else:
y();
end:
[...]

ich war von einem 16bit Int ausgegangen. geht ihr von 32bit aus?
würde es dann sinn machen…?


cmpl = compare long


also wenn ich mich auf einem 16bit system befinde, 32bit? falls 32bit, 64 … usw ?


Zumindest bei Intel-Architektur steht das “l”-Suffix i.d.R. für 32-bit Werte, egal ob du x86 oder x64 Code generierst.


gut. danke.
zurück zum thema:
würde mein code, wenn ich a[2] durch a[1] ersetze sinn machen. die andere argumentation habe ich noch nicht verstanden…


Schau dir mal die oben zitierte Folie an…
Zur Übergabe von Parametern an Unterfunktionen werden die Parameter zum Beispiel über den Stack übergeben.
Die liegen dann da, und beim Funktionsaufruf wird dann die Rücksprungadresse draufgepusht, d.h. oben auf dem Stack liegt die Rücksprungadresse.
Direkt drunter liegt der Parameter, der übergeben werden sollte.
Da der Stack in Richtung kleinerer Adressen wächst, und an [esp] der letzte draufgepushte Wert liegt, ist [esp+4] = 4(%esp) der Parameter.

Jetzt klar? :slight_smile:


gut das glaube ich halbwegs verstanden zu haben .
abschließende frage: ein parameter könnte aber schon die form eines arrays besitzen. durch irgendwelche speicherzellen scheine ich ja durchiterieren zu wollen… ? oder handelt es sich hierbei einfach um die einzelnen parameter. haben also funktionen (da sie über den Stack implementier werden) eine variable parameter anzahl? ; sprich: mein programm bildet die summe der 10 übergabeparameter ?
also

int func(int a, intb, ...) { return a+b+...;}

Ersetze in dem oben von dir geschriebenen Code [m]a[2][/m] durch [m]x[/m] und überlege nochmal was die Funktion genau macht.


addiert er alle nat. zahlen bis x auf?
auf gut deutsch , er macht das was der klein gauß hätte rechnen sollen, nur das er schlauer war als unser assembler-programmierer?


Deine nachträgliche Änderung hat übrigens neue Probleme:

[quote=clebinger:1294942184]
[color=blue]secondtry: if(!(a<0)) y(); if(!(b<0)) y(); dostuff: x();[/color][/quote]

Angenommen a = b = 1, dann:
y() wird ausgeführt, kehrt zurück,
y() wird nochmal ausgeführt, kehrt zurück,
x() wird ausgeführt…


[quote=John Late]
Deine nachträgliche Änderung hat übrigens neue Probleme:

du meinst in etwa so : ?

[color=blue] if(!(a>0)) goto secondtry; if(!(b>0)) goto secondtry; goto do_stuff; secondtry: if(!(a<0)) { y(); goto end; } if(!(b<0)) { y(); goto end; } dostuff: x(); end: end; [/color]


Streng genommen darfst du nur “if-then-goto” benutzen, also du kannst nicht [m]y()[/m] und [m]goto[/m] im [m]if[/m] verwenden, sondern nur [m]goto[/m].

edit: Was hat es eigentlich mit der seltsamen Einrückung auf sich?