Historisch gesehen, warum scheint es so zu sein, als ob jeder und ihr kleiner Bruder ihre eigenen Gesprächskonventionen definiert? Sie haben C, C ++, Windows, Pascal, Fortran, Fastcall und wahrscheinlich eine Zillion andere, die ich nicht erwähnen wollte. Sollte nicht eine Konvention für die überwiegende Mehrheit der Anwendungsfälle am effizientesten sein? Gibt es jemals einen guten Grund, einen vor dem anderen zu bevorzugen?
Die von Ihnen genannten Aufrufkonventionen wurden im Laufe der Jahrzehnte für verschiedene Sprachen und unterschiedliche Hardware entwickelt. Sie alle hatten unterschiedliche Ziele. Cdecl unterstützte variable Argumente für printf. Stdcall führte zu kleineren Code-Gen, aber keine variablen Argumente. Fastcall könnte die Leistung von einfachen Funktionen mit nur einem oder zwei Argumenten auf älteren Maschinen erheblich beschleunigen (ist aber heute selten schneller).
Beachten Sie, als wenn x64 eingeführt wurde, zumindest unter Windows, dass es eine einzige Aufrufkonvention hatte.
Raymond Chen hat eine großartige Serie über die Geschichte der Aufrufkonventionen geschrieben. Sie können beginnen hier .
Weil historisch alle und ihr kleiner Bruder ihre eigenen Rufkonventionen definiert haben. Sie wurden alle für unterschiedliche Zwecke geschaffen und somit von unterschiedlichen Leistungsanforderungen getrieben. Zum Beispiel favorisiert C ++ Optimierungen für die Übergabe des Parameters this
.
Ein Teil des Grundes ist die zugrunde liegende Architektur des Mikroprozessors (oder Prozessors). Die meisten Sprachen beginnen auf einer bestimmten CPU und verwickeln sich ein wenig in diese Architektur. Zum Beispiel hatte der alte Univac 1100-Computer nicht einmal einen Call-Stack!
Ein weiterer Grund dafür ist, dass es nicht möglich ist, die beste Lösung vorherzusehen, bis Sie verschiedene Methoden ausprobiert haben.
Sie werden für verschiedene Zwecke und mit verschiedenen Optimierungssystemen erstellt.
Um zum Beispiel "Stack Overflow" (kein Wortspiel beabsichtigt) zu reduzieren, dachten einige Leute an verschiedene Ideen, Funktionen aufzurufen, um Stapelüberläufe unmöglich zu machen.
Ein anderes Beispiel ist der Lambda-Kalkül. Um nicht zu vage zu sein, aber in Lambda können Funktionen nur ein Argument übergeben und einen Wert zurückgeben und benötigen daher ihre eigenen Aufrufkonventionen.
Tags und Links assembly calling-convention history low-level