HA! KALT ERWISCHT!!! Er hat einen Pointer oder aber eben eine Referenz übergeben!!! Naja, genau genommen wurde die lokale Variable schon in main angelegt, dann hat er den Pointer als Parameter an die Funktion übergeben und dann in der Funktion lokal eine struktur angelegt, die Werte dorthin geschrieben, die komplette struktur dann kopiert auf die Adresse, die als Parameter übergeben wurde, und dann den Pointer zurückgegeben. Jetzt sieht man das zwar nicht im C-Code, aber eben im Assembler Output. Ok, hier die Übersetzung für Assembler unkundige. Ich haffe das so kommentiert zu haben, dass es verständlich ist. Gruss - Arndt struct zeit { int stunde; int minute; int sekunde; }; struct zeit demo () { /* pushl %ebp // Stack retten movl %esp,%ebp // subl $24,%esp // Platz für 36 byte lokale Variablen schaffen */ struct zeit meinezeit = { 1, 2, 3 }; /* movl 8(%ebp),%eax // merke Parameter 2 in eax // ACHTUNG, diese Funktion bekommt Parameter, // auch wenn man es im C-Code nicht sieht! und zwar wird, // wie ich in main gleich zeige, schon lokal Platz für die Struktur // auf dem Stack angelegt. // Ok, Das ist schon Ok, aber eben nicht C, wie ich es gelernt habe. // Danke Bernhard, das kleine Beispiel hat mich wieder etwas gelehrt! // Man lernt hlt nie aus ;-) // So, nun füllen wir die Strukutr (LOKAL) movl $1,-12(%ebp) // 1 Siehe struct meinezeit = {1,2,3}; movl $2,-8(%ebp) // 2 Siehe struct meinezeit = {1,2,3}; movl $3,-4(%ebp) // 3 Siehe struct meinezeit = {1,2,3}; // Und jetzt kopieren wir die lokale Struktur an die Speicherzellen, // die uns als Parameter übergeben wurden. (Ein bischen Redundant, // aber sonst hätten Leute wie ich, die Ihr Geld mit Gerätetreibern // und Assembler-Speed-Ups verdienen ja auch keine // Daseinsberechtigung ;-) movl -12(%ebp),%edx // Das ist die '1' movl %edx,(%eax) movl -8(%ebp),%edx // Das ist die '2' movl %edx,4(%eax) movl -4(%ebp),%edx // Das ist die '3' movl %edx,8(%eax) */ return meinezeit; /* // Naja, einfach einen Nop als Sprung getarnt ;-) // Ist aber ggf. zum Debuggen sehr nützlich! jmp .L2 .L2: // Den hier kann man sich sparen, eax wird in sich selbst kopiert // und enthält, ganz nebenbei gesagt, einen POINTER auf die // Struktur... kicher movl %eax,%eax leave // Stack aufräumen // Also genau genommen heist das Assembler-päarchen // ENTER ... LEAVE, aber da leave auch nur ein mov esp,ebp ist // ggf. mit Addition von 'n' ist das schon ok. // 4 draufhauen und zurück an den Aufrufer... ret $4 */ } int main (int argc, char *argv[]) { // pushl %ebp ; - Basepointer retten // movl %esp,%ebp ; - Basepointer auf Stackpointer setzen // subl $24,%esp ; - 36 byte für lokale Variablen reservieren struct zeit nocheinezeit; // leal -12(%ebp),%eax; - Pointer auf struct zeit nocheinezeit laden // addl $-12,%esp ; - 12 weiter Byte platz schaffen // pushl %eax ; - Pointer // call demo ; - demo ( pointer ) aufrufen nocheinezeit = demo(); // addl $12,%esp ; - Un den Stack wieder freiräumen // movl -4(%ebp),%eax ; - Ok ,das hier ist langweilig, // pushl %eax ; - es ist lediglich der printf(...) // movl -8(%ebp),%eax ; - // pushl %eax ; - // movl -12(%ebp),%eax ; - // pushl %eax ; - // pushl $.LC0 ; - // call printf ; - printf("Std: %d\nMin: %d\nSek: %d\n", nocheinezeit.stunde, nocheinezeit.minute, nocheinezeit.sekunde); // addl $16,%esp ; - Stack nach dem printf wieder korrigieren // xorl %eax,%eax ; - eax mit 0 laden, und dann zurückgeben return 0; // jmp .L3 // .p2align 4,,7 //.L3: // leave // ret }