AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials [Artikel] Aufrufkonventionen
Tutorial durchsuchen
Ansicht
Themen-Optionen

[Artikel] Aufrufkonventionen

Ein Tutorial von Luckie · begonnen am 24. Mär 2006 · letzter Beitrag vom 27. Mär 2006
Antwort Antwort
Benutzerbild von Luckie
Luckie
Registriert seit: 29. Mai 2002
Dieser Forenbeitrag hat mich dazu angeregt einen neuen Artikle für meine Homepage zu verfassen. Und zwar geht es kurz und knapp um Aufrufkonventionen.

Artikel: Aufrufkonventionen

Rechtschreibfehler bitte wie immer per PN melden. Danke.
Ein Teil meines Codes würde euch verunsichern.
 
Benutzerbild von Ultimator
Ultimator

 
FreePascal / Lazarus
 
#2
  Alt 25. Mär 2006, 16:13
Da hab ich doch glatt mal ne Frage^^
Wo genau ist der Unterschied zwischen stdcall und safecall, wenn doch bei beiden "Von rechts nach links - Routine - Nein" der Fall ist (also Parameterübergaberichtung - "Stackaufräumer" - Übergabe in Register), außer dass stdcall der Windows-Standard ist?
Julian J. Pracht
  Mit Zitat antworten Zitat
brechi
 
#3
  Alt 25. Mär 2006, 16:38
Da haben sich aber 1-2 Fehler eingeschlichen, und es ist noch sonderlich vollständig.

1) "Messagebox erwscheint," -> "erscheint"

2) register -> Übergabe in Registern? Jain, nur die ersten 3 in EAX, EDX, ECX dann alle folgenden auf dem Stack

3) cdecl ist auch noch relativ interessant wurde aber nicht beschrieben (nur in der Tabelle)

4) "Und stdcall ist insofern interessant, als dass es die Aufrufkonvention von Windows API Funktionen ist."
Stimmt auch nicht (mehr). Das gilt nur für Win32, Win64 hat ne total beschissende Aufrufkonvention, die ähnlich der register ist und dazu noch Typenabhängig

Sollte man eventluell noch ein bischen ausarbeiten ;>
  Mit Zitat antworten Zitat
Robert Marquardt
 
#4
  Alt 25. Mär 2006, 17:18
Man sollte auch erklaeren warum die Aufrufkonventionen so sind wie sie sind.

Bei stdcall (frueher pascal genannt) ist keine variable Anzahl von Parametern moeglich, dafuer kann die aufgerufene Funktion bei der Rueckkehr die Parameter vom Stack abraeumen. Das spart natuerlich Instruktionen, da meist die RET-Instruktion das mit erledigt.
Von links nach rechts die Parameter auf den Stack zu schieben (erster Parameter ist oben auf dem Stack) ist fuer den Parset/Codegenerator einfacher. Das stammt noch von Wirth selbst, der bei Pascal auch auf die Effizienz des Compilers geschaut hat.

Bei cdecl ist eine variable Anzahl Parameter moeglich, dafuer muss aber der Aufrufer die Parameter selbst abraeumen. Es folgt also jedem Funktionsaufruf ein ADD SP, xxx, da nur der Aufrufer weiss wieviel er auf den Stack gepackt hat.
Die Parameter muessen von rechts nach links auf den Stack geschoben werden, damit sie dann aufsteigend auf dem Stack stehen, d. h. erster Parameter ist unten. Damit kann man in C (deshalb der Name cdecl) nun die Parameter als Array ueber einen Pointer zugreifen.

register ist effizient, da der Compiler besser optimieren kann, aber dafuer geht die Sprachunabhaengigkeit verloren. Delphi und C/C++ haben unterschiedliche Register-Aufrufkonventionen. Es werden so viele Parameter wie moeglich in Register gepackt und der Rest geht nach stdcall-Konvention.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

 
Delphi 2006 Professional
 
#5
  Alt 25. Mär 2006, 17:44
Zitat von Robert Marquardt:
Man sollte auch erklaeren warum die Aufrufkonventionen so sind wie sie sind.
Das wußte ich nicht, aber das kann ich ja jetzt noch ergänzen.

@brechi: Jetzt kenne ich das interessantean cdecl.

Zu safecall habe ich in "Delphi in a nutshell" noch was gefunden und werde es ergänzen. Das wird mir aber erst morgen möglich sein.
Michael
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

 
Delphi 2006 Professional
 
#6
  Alt 26. Mär 2006, 22:53
So, habe jetzt erstmal die zusätzlichen Informationen von Robert aufgenommen und noch ein paar Tippfehler beseitigt (und wahrscheinlich neue eingebaut. ).
Michael
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

 
Delphi 10.2 Tokyo Professional
 
#7
  Alt 27. Mär 2006, 09:28
Ich verbessere jetzt mal, damit sich das nicht noch jemand falsch merkt.

Zitat von Robert Marquardt:
Bei stdcall (frueher pascal genannt) ...
stdcall wurde noch nie pascal genannt. Früher (16-Bit Windows) benutzten alle API-Funktionen die pascal Aufrufkonvention, heute benutzen sie stdcall.

Zitat von Robert Marquardt:
Damit kann man in C (deshalb der Name cdecl) nun die Parameter als Array ueber einen Pointer zugreifen.
Nicht falsch, aber vielleicht noch als Ergänzung: das ursprüngliche C kannte keine Prototypen. Man konnte die Routine
Code:
int open(name, flags, mode)
     char *name;
     int flags, mode;
{
}
auch einfach mit dem Parameter "5" aufrufen (und abstürzen lassen). Bei vielen C-Library-Funktionen (wie hier open) hat man dann optionale Parameter nach hinten gepackt, damit man sie einfach weglassen konnte ("mode" wird hier nur beim Anlegen einer neuen Datei gebraucht). Man kann also in ganz einfachem C nicht nur über ein Array auf diese Parameter zugreifen.

Zitat von Robert Marquardt:
register ... Es werden so viele Parameter wie moeglich in Register gepackt und der Rest geht nach stdcall-Konvention.
Nein, danach geht's in der pascal-Konvention weiter.


@Luckie: in deinem Beitrag ist aber alles korrekt dargestellt.
Volker
  Mit Zitat antworten Zitat
Antwort Antwort


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 03:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz