AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Assembler Parameter auf Stack legen
Thema durchsuchen
Ansicht
Themen-Optionen

Assembler Parameter auf Stack legen

Ein Thema von mwilms · begonnen am 24. Nov 2022 · letzter Beitrag vom 29. Nov 2022
Antwort Antwort
markus888

Registriert seit: 23. Dez 2018
46 Beiträge
 
#1

AW: Assembler Parameter auf Stack legen

  Alt 25. Nov 2022, 19:46
In x64 musst du Platz auf dem Stack machen bevor due eine Funktion callst
Ich verstehe nicht, warum der Delphi Compiler das nicht macht.

Wenn ich eine Funktion/Prozedur aufrufe, dann reserviert immer die aufgerufene Funktion/Prozedur den Speicher.
Dem Aufrufer ist theoretisch ja auch nur der benötigte Stapelspeicher für die übergebenen Variablen bekannt.
Sprich der Vorgang wäre doppelt erforderlich, da der aufgerufene Code ja auch noch den Speicher für die internen Variablen reservieren müsste.

Wo siehst du den Vorteil, wenn der Aufrufer den Platz für die übergebenen Variablen reserviert?

Hier ein stupider Code:

Code:
function work_2(i,e:byte):Boolean;
var x:Integer;
begin
  x:=e+i;
  work_2:= x>0;
end;
function work_1(t, y :double;i,e,z,k:byte):boolean;stdcall;
var
  v:array[0..100] of Byte;
begin
 v[0]:= i;
 v[i]:= e;
 work_1:= (t<y) and work_2(i,e);
end;

begin
  var x:double;
  try
  work_1(3.5, 134.1, 20,30,10,40);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
Zitat von Stapelspeicher Reservierung bei Beginn von work_1:
X64Fpu.dpr.25: begin
push rbp
sub rsp,$0000000000000090
mov rbp,rsp

Zitat von Funktion Rückgabe ins Register schreiben und Speicher freigeben bei end von work_1:
X64Fpu.dpr.29: end;
movzx rax,byte ptr [rbp+$0000008f]
lea rsp,[rbp+$00000090]
pop rbp
Der Aufrufer reserviert nichts, das macht nur der Empfänger - warum hält sich Delphi hier nicht an die Vorgaben?
Weil was ist bei einer dll - da habe ich ja keinen Einfluss auf den Aufrufer - oder verhält sich der Compiler dann Normkonform?
Bei 32 Bit mit inline asm musste man sich damit ja nicht beschäftigen.
Da ich aber mit x64 noch keine asm Erfahrung habe, wäre es interessant hier eine universelle Lösung zu haben.

Edit: Hab jetzt etwas genauer hingesehen, und merke grade dass ich das Wesentliche mangels Erfordernis noch nicht ganz verstanden habe.
Der Stack-Base Pointer wird ja durch den call gesetzt. Muss mich da noch etwas vertiefen.

Geändert von markus888 (25. Nov 2022 um 23:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.374 Beiträge
 
Delphi 12 Athens
 
#2

AW: Assembler Parameter auf Stack legen

  Alt 26. Nov 2022, 00:12
Jupp, der Aufrufer kann sich garnicht um sowas kümmern ... woher soll er wissen was wie in der Funktion gemacht wird, und außerdem könnte es sich auch mal ändern.
Aber ja, rein von den Daten ist es schon möglich, dass der Aufrufer bereits Platz auf dem Stack vorbereitet, für alle Parameter in den Registern ... aber wenn, dann wäre es doch eigentlich schwachsinnig "eventuell" nutzlos sowas zu machen, falls es dann doch nicht benutzt wird. Da könnte man auch gleich ALLEs auf den Stack legen und sich das mit den Registern sparen.


Was aber geht, wie man es z.B. unter Win32 mit den verschiedenen CallingConventions kennt,

* wer den Speicher freigibt, also wer den Stack nach der Ausführung zurücksetzt
meißtens macht es die Funktion, welche normal weiß was sie für Parameter hat,
aber kennt sie es nicht, dann muß es der Aufrufer machen.
-> ein Beispiel sind VarArgs (beim cdecl), wo nur der Aufrufer zu 100% weiß, was er wirklich rein gab.

* oder eben wo und in welcher Reihenfolge die Parameter übergeben werden
-> Register oder ausschließlich auf dem Stack
-> von vorwärts oder rückwärts, bzw. von links nach rechts oder andersrum

So gesehn ist es praktisch, wenn es nur noch eine "offizielle" Variante gibt.
Ja, natürlich kann man dennoch sonstwelchen Mist bauen und es nach belieben machen, aber schon alleine für's Debuggen ist es günstig, wenn es möglichst wenig Vaiationen gibt, weil dann Compilerunabhängig alles gleich analysiert werden kann.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (26. Nov 2022 um 00:16 Uhr)
  Mit Zitat antworten Zitat
markus888

Registriert seit: 23. Dez 2018
46 Beiträge
 
#3

Nach etwas intensiverem Testen

  Alt 26. Nov 2022, 01:07
schaut die Sache etwas anders aus.
Das Groh scheint unproblematisch zu sein.
Mit lokalen Variablen kann ganz normal gearbeitet werden.

Hauptproblem: Die ersten 4 Parameter die via Register übermittelt werden.
Normalerweise ermittelt der Compiler die Adressen der Variablen, was in diesem Fall nicht funktioniert.

Es ist mir also derzeit nur via Stack-Adresse möglich, die Werte aus den Registern diesen Variablen zuzuweisen, bzw. mit diesen Variablen zu Arbeiten, was natürlich recht mühsam ist.

Kennt irgend wer einen Weg, dies einfacher zu lösen, bzw. wie geht ihr damit um?
  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 01:36 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