AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Float-Parameter per ASM übergeben

Ein Thema von Neutral General · begonnen am 2. Jun 2008 · letzter Beitrag vom 7. Jun 2008
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Float-Parameter per ASM übergeben

  Alt 2. Jun 2008, 21:37
Hi,

Ich habe gerade sowas:

Delphi-Quellcode:
procedure TForm1.Test(f: Single);
begin
  ShowMessage(FloatToStrF(f,ffNumber,2,2));
end;
Diese Methode würde ich gerne über ASM aufrufen, ich scheitere jedoch beim Versuch... Es kommt immer nur 0 an.

Delphi-Quellcode:
mov edx, [Params]
mov edx, [edx] // nicht so wichtig.. Float wird in edx geladen

mov eax, Self
call TForm1.Test
Was muss ich da anders machen?

Gruß
Neutral General
Michael
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Float-Parameter per ASM übergeben

  Alt 2. Jun 2008, 21:54
Warum schaust du nicht einfach in der CPU-Ansicht nach?

Es sieht so aus, als ob Floats in jedem Fall auf den Stack geschoben werden müssen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

Re: Float-Parameter per ASM übergeben

  Alt 2. Jun 2008, 21:56
Hi,

Ja das habe ich auch durch das CPU-Fenster herausgefunden, aber es funktioniert bei mir nicht... :

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
begin
  asm
    push 3.4
    call TForm1.Test
  end;
end;
Es kommt trotzdem 0 an...
Michael
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Float-Parameter per ASM übergeben

  Alt 2. Jun 2008, 21:59
Konstante Floats solltest du als Konstanten deklarieren, andernfalls kann es in BASM zu seltsamen Effekten kommen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: Float-Parameter per ASM übergeben

  Alt 2. Jun 2008, 22:04
Hi,

Ok ich habs gemerkt...

Naja das Problem ist, das ich den Float-Wert über ein Array of Const bekomme.

Das ganze sieht also so aus:

Delphi-Quellcode:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Test.FloatDings([2.1]);
end;

procedure TTest.FloatDings(Params: Array of Const);
begin
  asm
    mov edx, [Params]
    mov edx, [edx]

    push edx
    mov eax, Form1 // egal jetzt^^
    call TForm1.Test
  end;
end;

procedure TForm1.Test(f: Single);
begin
  ShowMessage(FloatToStrF(f,ffNumber,2,2);
end;
Was kann ich tun?

Gruß
Neutral General
Michael
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Float-Parameter per ASM übergeben

  Alt 2. Jun 2008, 22:17
Mitdenken!
Ein Array of const ist, wie dir sicherlich bekannt ist, ein Array of TVarRec mit spezieller Längenangabe.
Jetzt schau dir doch bitte mal an, wie Floats in TVarRec gespeichert wird (System.pas).
In jedem Fall als Extended und nie als Single oder Double, außerdem noch als Zeiger. Also musst du ein bisschen anpassen, denn du hast noch einen Zeiger mehr, den du dereferenzieren musst. Grundsätzlich hast du jetzt die Wahl, TForm1.Test so zu verändern, dass es Extendeds entgegennimmt, oder in FloatDings ein wenig mit der FPU herumzuspielen.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: Float-Parameter per ASM übergeben

  Alt 4. Jun 2008, 17:48
Hi,

Oh du hast ja Recht Hatte sogar mal gesehn das sie im TVarRec als PExtended gespeichert werden aber ich hatte es irgendwie wieder vergessen

Naja dann wollte ich anfangen an den Wert hinter dem PExtended zu kommen. Der erste Schock war aber dann da, als ich sehen musste das SizeOf(Extended) = 10... Was ist denn das für ein "krummer" Wert?! Ich dachte bisher immer Extendeds wären auch 8 Byte groß..

Also habe ich mir das mal im CPU-Fenster angeschaut:

Zitat von CPU-Fenster:
Unit1.pas.101: f := 334.34;

004580C7 C7042485EB51B8 mov [esp],$b851eb85
004580CE C74424041E852BA7 mov [esp+$04],$a72b851e
004580D6 66C74424080740 mov word ptr [esp+$08],$4007
Habe allerdings bisher nicht geschafft das nachzubauen...

Delphi-Quellcode:
// edx: PExtended
mov eax,[edx]
mov ecx,[edx+4] // ...
mov [eax+4],ecx // mov [eax+4],[edx+4] compiliert nicht *)
mov word ptr [eax+8],[edx+8] // *) + hab ich auch nicht anders hinbekommen
*) Ich bin leider ziemlich unerfahren was ASM betrifft...

Ich denke ich verstehe den Code aus dem CPU-Fenster, aber ich kanns nicht auf meine Situation übertragen

Gruß
Neutral General
Michael
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#8

Re: Float-Parameter per ASM übergeben

  Alt 4. Jun 2008, 17:54
Delphi-Quellcode:
asm
  fld tbeyt ptr [edx]
  fstp tbyte ptr [eax]
end;
Oder über SSE

Edit: Stimmt, qword waren nur 8.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Float-Parameter per ASM übergeben

  Alt 4. Jun 2008, 17:56
Hier denkst du mal wieder zu kompliziert. Eigentlich willst du doch nur den Extended-Wert auf den Stack schieben, damit du die Funktion aufrufen kannst.
Delphi-Quellcode:
// edx: PExtended
push word ptr [edx + 8] //zuerst gepusht -> liegt am weitesten weg, daher fangen wir hinten an
push [edx + 4]
push [edx]
Damit sollte es klappen.

Übrigens, wegen deines Erstaunens über SizeOf(Extended): Intel verwendet drei Größen für Floats: 4 Byte (Single), 8 Byte (Double = Real) und 10 Byte (Extended). Im Inline-Assembler sprichst du Extended für fld und fst(p) mit TByte an (vermutlich steht das für "ten byte").
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#10

Re: Float-Parameter per ASM übergeben

  Alt 4. Jun 2008, 18:11
Hi Dax und Apollonius,

@Dax: Habs jetzt so gelöst wie Apollonius gesagt hat, aber ich werd mir diese Float-Befehle auch mal angucken.. Kann ja nichts schaden was dazuzulernen

@Apollonius: Danke, es funktioniert, aaber ( ) es taucht ein ganz seltsamer effekt auf:

Delphi-Quellcode:
// Diese Funktion rufe ich auf f = 2.1
procedure TForm1.Test3(f: Extended);
begin
   ShowMessage(FloatToStrF(f,ffNumber,5,2));
end;

Zitat:
---------------------------
Project1
---------------------------
2,10











































---------------------------
OK
---------------------------
Und das ist die verkürzte Darstellung -.-

PS: Ich poste nochmal grad wie das ganze aufgerufen wird:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form1.ExecuteScriptMethod('Test3',[2.1]);
end;

procedure TForm1.ExecuteScriptMethod(Method: String;
  Params: array of Const);
var proc: Pointer;
    i, off: Integer;
    max: Integer;
    p1,p2: Integer;
begin
  proc := MethodAddress(Method);
  max := Length(Params);

  for i:= 2 to max-1 do
  begin
    off := i*8; // stack-parameter pushen (floats noch nicht eingebaut!)
    asm
      mov edx, [Params]
      add edx, off
      mov edx, [edx]
      push edx
    end;
  end;

  // 1 - 3. Parameter übergeben (wobei 1. Parameter = Self)
  p1 := Params[0].VType;
  p2 := Params[1].VType;
  asm
    mov eax, max
    and eax, eax
    jz @Self // Kein Parameter
    sub eax,1
    jz @Param1 // 1 Parameter, sonst 2 Parameter
@Param2:
    mov ecx, [Params];
    add ecx, 8
    mov ecx, [ecx]
@Param1:
    mov edx, [Params]
    mov edx, [edx]

    mov eax, p1 // wenn Params[0].VType = vtExtended (3)
    sub eax, 3
    jnz @Self // dann float pushen
      push word ptr [edx+$08]
      push [edx+$04]
      push [edx]
@Self:
    mov eax,self // self übergeben

    call proc // methode aufrufen
  end;
end;
PS: Bitte nicht meine Methode optimieren... Es funktioniert so weit und dadrüber bin ich froh.. nachher hab ich zwar tollen Code, aber der ist dann nicht von mir sondern von sonst jemandem und das mag ich nicht

Gruß
Neutral General
Michael
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 08:55 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