'CallFunctionFast' manuell mit ASM

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

'CallFunctionFast' manuell mit ASM

Beitrag von CSHW89 »

Hallo erstmal an alle

also ich hab ein kleines problem: es ist ja denk ich bekannt, dass die Funktion 'CallFunctionFast()' nicht sehr flexibel ist. deshalb wollte ich mal eine eigene Funktion schreiben, bei der zur compilierzeit noch nicht bekannt ist, von welchem Typ die Parameter sein sollen, und es überhaupt möglich ist auch Floats, Doubles und Quads zu übergeben. Da ich aber wenig bis gar keine Ahnung von ASM habe, hab ich nach drei stunden ausprobieren erfolglos aufgegeben. vielleicht könnt ihr mir ja weiter helfen. meine grundidee ist folgende:

Code: Alles auswählen

Structure param
  type.b
  StructureUnion
    byte.b
    word.w
    long.l
    quad.q
    float.f
    double.d
    char.c
    *pointer
  EndStructureUnion
EndStructure

#Pointer = 127


Procedure.f test(a.l, b.d, c.b)
  Debug a ; sollte ausgeben: 10000000
  Debug b ; -12.3
  Debug c ; 13
  ProcedureReturn 0.003
EndProcedure


Procedure callfunc(*func, result.param, param.param())
  ForEach param()
    Select param()\type
    Case #Byte
      ; 'param()\byte' der Parameterliste hinzufügen
    Case #Word
      ; 'param()\word' der Parameterliste hinzufügen
    Case #Long
      ; 'param()\long' der Parameterliste hinzufügen
    Case #Quad
      ; 'param()\quad' der Parameterliste hinzufügen
    Case #Float
      ; 'param()\float' der Parameterliste hinzufügen
    Case #Double
      ; 'param()\double' der Parameterliste hinzufügen
    Case #Character
      ; 'param()\char' der Parameterliste hinzufügen
    Case #Pointer
      ; 'param()\pointer' der Parameterliste hinzufügen
    EndSelect
  Next
  ; Die Funktion '*func' mit der Parameterliste aufrufen
  Select result\type
  Case #Byte
    ; Speichert den Rückgabewert in 'result\byte'
  Case #Word
    ; Speichert den Rückgabewert in 'result\word'
  Case #Long
    ; Speichert den Rückgabewert in 'result\long'
  Case #Quad
    ; Speichert den Rückgabewert in 'result\quad'
  Case #Float
    ; Speichert den Rückgabewert in 'result\float'
  Case #Double
    ; Speichert den Rückgabewert in 'result\double'
  Case #Character
    ; Speichert den Rückgabewert in 'result\char'
  Case #Pointer
    ; Speichert den Rückgabewert in 'result\pointer'
  EndSelect
EndProcedure


NewList param.param()
InsertElement(param())
param()\type = #Long
param()\long = 10000000
InsertElement(param())
param()\type = #Double
param()\double = -12.3
InsertElement(param())
param()\type = #Byte
param()\long = 13

result\type = #Float

callfunc(@test(), result, param())

Debug result\float ;sollte 0.003 ausgeben
wär echt super, wenn da jemand ne idee hätte.
danke schon mal im vorraus.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

Prototypes ?
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Beitrag von CSHW89 »

damit kann ich floats, doubles und quads übergeben, stimmt schon. ich will aber noch mehr. zur compilerzeit sind die parametertypes noch nicht bekannt. prototypes erledigen nicht das problem!!
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Beitrag von CSHW89 »

Hab vielleicht noch ne anderidee. ist es in asm möglich eine procedure mit einer parameterliste aufzurufen, wenn die parameter in einem speicherblock gespeichert sind. konkret stell ich mir das so vor:

Code: Alles auswählen

Procedure test(a.w, b.d)
  Debug a  ; -1241
  Debug b  ; 13.4
EndProcedure

*mem = AllocateMemory(100)
PokeD(*mem, 13.4)
PokeW(*mem+8, -1241)

;Aufruf der test-Procedure mit den Parametern in *mem
Wenn es möglich ist, würd ich mich über eine realisierung freuen!!
Benutzeravatar
NicknameFJ
Beiträge: 324
Registriert: 03.06.2007 14:36
Wohnort: Von der Sonne aus gesehen der dritte Planet

Beitrag von NicknameFJ »

Meinst Du so was in der Art

Code: Alles auswählen

Structure MyOwn
  wd.w
  db.d
EndStructure


Procedure test(*pointer.MyOwn)
  Debug *pointer\wd
  Debug *pointer\db
EndProcedure

*mem.MyOwn = AllocateMemory(SizeOf(MyOwn))

*mem\wd = -1241
*mem\db = 13.4

test(*mem)
oder habe ich Dich da irgendwie falsch verstanden?


[EDIT]
Ich glaube die letzen zwei/drei Wochen etwas von NicTheQuick oder Kaeru Gaman gelesen zu haben dass sich damit beschäftigt eine variable Parameterliste an eine Procedure zu übergeben. Habe es leider auf die Schnelle nicht gefunden. Musst nochmal die SuFu bemühen- bin mir nicht ganz sicher von vom der Beitrag war, glaube aber NTQ oder KG
PS: Alle im Text enthaltenen Schreibfehler sind beabsichtigt und dienen der Belustigung aller

Bild
Benutzeravatar
mk-soft
Beiträge: 3871
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Es gibt verschiedene möglichkeiten auch ohne ASM Parameter dynamisch zu übergeben.

hier mal zwei möglichenkeiten als Ansatz welchen weg man gehen kann.

http://www.purebasic.fr/german/viewtopi ... highlight=
http://www.purebasic.fr/german/viewtopi ... highlight=

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Beitrag von CSHW89 »

Tja, das sind ganz gute ideen, danke dafür, allerdings ist das nicht das, was ich suche:
die funktion test, die ich dort geschrieben habe, kann nicht verändert werden. die deklaration ist ja:

Code: Alles auswählen

Procedure test(a.w, b.d)
EndProcedure
und das soll auch so bleiben. deshalb ist es nicht möglich das problem mit purebasic zu lösen. das muss irgendwie mit asm gehen. wenn ihr also noch irgendeine idee habt. das wär echt super. ich brauch das unbedingt. danke schon mal.
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

> die funktion test, die ich dort geschrieben habe, kann nicht verändert werden

Dann sind Prototypes das richtige.

Wenn die Deklaration immer Func(Word.w, Double.d) ist, ist das auch gleich der passende Prototype.

Gruß, Alex
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Beitrag von CSHW89 »

Ich werd hier noch verrückt :freak: .
Also folgendes Scenario:

ich hab in einer dll proceduren, die kann ich nicht ändern, ich weiß aber zur compilerzeit nicht, wie die parameterliste aussieht (fragt jetzt nicht warum, die dll kann sich jederzeit ändern, nachdem ich mein programm fertig habe). die informationen bekomme ich von der dll zur LAUFZEIT. Aus diesen informationen will ich eine procedure in der dll aufrufen!
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Wenn du es erst zur Laufzeit bekommst versuche mal Call[C]Function[Fast]
und uebergib die Pointer.
Falls du Kontakt zu Programierer hast, erzaehl ihm mal dass das totaler Mist ist...
Antworten