AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Rückgabewerte von Funktionen und Prozeduren
Thema durchsuchen
Ansicht
Themen-Optionen

Rückgabewerte von Funktionen und Prozeduren

Ein Thema von Hansa · begonnen am 3. Jul 2003 · letzter Beitrag vom 4. Jul 2003
 
Gast
(Gast)

n/a Beiträge
 
#28
  Alt 3. Jul 2003, 22:24
Das Argument, daß C++ keine Unterscheidung kennt ist etwas naiv!
C wurde nämlich erfunden um Programmierern das Leben schwer zu machen.

Laßt mich mal ein wenig tiefer buddeln:

Delphi-Code. Es ist eine Prozedur und eine Funktion! ...
STDCALL wurde verwendet um den Unterschied anschaulicher darzustellen,
da Delphi ansonsten diverse Parametertypen (u.a. Integer) im Register
übergibt.
Delphi-Quellcode:
procedure prozedur(var i:Integer); // Anschaulicher!!!
begin
  i:=i+1;
end;

function funktion(i:Integer):Integer; stdcall; // Anschaulicher!!!
begin
  result:=i+1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i:Integer;
begin
  i:=funktion(5); // ergebnis 6
  prozedur(i); // ergebnis 7
end;
Etwas Pseudo-Code:
Code:
procedure prozedur(var i:Integer); stdcall;
--------------
push   ebp            // EBP sichern
mov    ebp, esp       // Stack Frame
~~~~~~~~~~~~~~
mov    eax, [ebp+$08] // "EAX := @i"
inc    dword ptr [eax] // EAX^ := EAX^ + 1 // inc(EAX^)
~~~~~~~~~~~~~~
pop    ebp            // EBP wiederherstellen
ret    $04             // Rückkehren
--------------

function funktion(i:Integer):Integer; stdcall;
--------------
push   ebp            // EBP sichern
mov    ebp, esp       // Stack Frame
~~~~~~~~~~~~~~
mov    eax, [ebp+$08] // EAX := i
inc    eax            // i := i + 1 // inc(i)
~~~~~~~~~~~~~~
pop    ebp            // EBP wiederherstellen
ret    $04             // Rückkehren
--------------

procedure TForm1.Button1Click(Sender: TObject);
--------------
push   $05             // Parameterübergabe
call   0043C6AC       // Funktion Resultat in EAX
mov    [ebp-$04], eax // i := EAX
lea    eax, [ebp-$04] // EAX := @i // Adresse von "i" in EAX
call   0043C6A8        // Prozedur
--------------
Uns interessieren die Stellen zwischen den: "~~~~~~~~~~~~~~".

Also! Ich habe extra alles kommentiert. Bei Prozedur() sieht man, daß nicht
eine lokale Variable auf dem Stack, sondern die Speicheradresse an der "i"
liegt, verändert wird. Wenn man so will, wird folgendes übergeben:
  • @i ... hätte man also beispielsweise geschrieben Prozedur(iInteger); so wäre dies das Selbe!!!
  • @i sollte bekannt sein, es ist die Adresse an der "i" liegt.

Bei Funktion() hingegen wird zuerst der übergebene Wert, welcher auf dem
Stack als "lokale Variable" (lokale Variablen und Parameter sind eigentlich
intern das Gleiche) liegt, in das Register EAX übergeben. Da ordinale
Rückgabewerte bei den Aufrufkonventionen STDCALL und REGISTER jeweils in
EAX zurückgegeben werden, wird EAX nur noch inkrementiert.

WÜRDE MAN ALSO:
Prozedur(i:Integer) schreiben, dann wäre "i" eine "lokale Variable" und damit
ginge der Rückgabewert verloren! Hingegen bei obigem Beispiel (als Wieder-
holung) wird direkt PInteger(@i)^:=PInteger(@i)^+1; modifiziert.

Jetzt klar?

Du modifizierst nämlich direkt eine "globale" Variable. Für den Compiler ist
das gleich ... der kann jede Speicherstelle so referenzieren, auch wenn im
Delphi-Source die Variable "i" innerhalb von Button1Click() eine "lokale"
Variable ist.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:59 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz