okay, ich werd das scenario mal erweitern:
die parameter können auch quads, floats und doubles sein.
da helfen keine prototypes und auch keine funktionen ala Call[C]Function[Fast].
'CallFunctionFast' manuell mit ASM
hi leute,
na gut, da ja niemand eine lösung für mein problem hatte, hab ich mir gedacht, selbst ist der mann. ich habs nach stundenlangen ausprobieren geschafft. falls jemand interresse daran hat, hier der fertige code. ich entschuldige mich aber schon mal im voraus für den wahrscheinlich grottenschlechten asm-programmierstil. tja wenn man sich das halt selbst beibringt, aber egal, hier der code:
na gut, da ja niemand eine lösung für mein problem hatte, hab ich mir gedacht, selbst ist der mann. ich habs nach stundenlangen ausprobieren geschafft. falls jemand interresse daran hat, hier der fertige code. ich entschuldige mich aber schon mal im voraus für den wahrscheinlich grottenschlechten asm-programmierstil. tja wenn man sich das halt selbst beibringt, aber egal, hier der code:
Code: Alles auswählen
Structure CFASM_PARAM
type.b
StructureUnion
byte.b
word.w
long.l
quad.q
float.f
double.d
char.c
*pointer
EndStructureUnion
EndStructure
#Pointer = -1
Procedure CallFunctionASM(*func, param.CFASM_PARAM(), *ret.CFASM_PARAM)
count.l = CountList(param())
*memory = AllocateMemory(count*9+1)
type.b = *ret\type
pos.l = 0
ForEach param()
PokeB(*memory+pos, param()\type): pos + 1
Select param()\type
Case #Pointer
PokeL(*memory+pos, param()\pointer): pos + 4
Case #Byte
PokeB(*memory+pos, param()\byte): pos + 1
Case #Word
PokeW(*memory+pos, param()\word): pos + 2
Case #Long
PokeL(*memory+pos, param()\long): pos + 4
Case #Quad
PokeQ(*memory+pos, param()\quad): pos + 8
Case #Float
PokeF(*memory+pos, param()\float): pos + 4
Case #Double
PokeD(*memory+pos, param()\double): pos + 8
Case #Character
PokeW(*memory+pos, param()\char): pos + 2
EndSelect
Next
! MOV Ecx, dword [p.p_func]
! MOV Edi, dword [p.v_count]
! MOV Esi, dword [p.p_memory]
callfunctionasm_loop:
! MOVSX Ebx, byte [Esi]
! INC Esi
! CMP Ebx, -1 ;Pointer
! JE l_callfunctionasm_long
! CMP Ebx, 0 ;Byte
! JE l_callfunctionasm_byte
! CMP Ebx, 1 ;Word
! JE l_callfunctionasm_word
! CMP Ebx, 2 ;Long
! JE l_callfunctionasm_long
! CMP Ebx, 3 ;Float
! JE l_callfunctionasm_long
! CMP Ebx, 4 ;Quad
! JE l_callfunctionasm_quad
! CMP Ebx, 6 ;Double
! JE l_callfunctionasm_double
! CMP Ebx, 7 ;Character
! JE l_callfunctionasm_char
! JMP l_callfunctionasm_next
callfunctionasm_byte:
! MOVSX eax, byte [esi]
! PUSH eax
! ADD esi, 1
! JMP l_callfunctionasm_next
callfunctionasm_word:
! MOVSX eax, word [esi]
! PUSH eax
! ADD esi, 2
! JMP l_callfunctionasm_next
callfunctionasm_long:
! PUSH dword [esi]
! ADD esi, 4
! JMP l_callfunctionasm_next
callfunctionasm_quad:
! PUSH dword [esi+4]
! PUSH dword [esi]
! ADD esi, 8
! JMP l_callfunctionasm_next
callfunctionasm_double:
! LEA eax, qword [esi]
! PUSH dword [eax+4]
! PUSH dword [eax]
! ADD esi, 8
! JMP l_callfunctionasm_next
callfunctionasm_char:
! MOVZX eax, word [esi]
! PUSH eax
! ADD esi, 2
! JMP l_callfunctionasm_next
callfunctionasm_next:
! DEC edi
! JNE l_callfunctionasm_loop
! CALL ecx
If (type = #Pointer)
*pointer = 0
! MOV dword [p.p_pointer], eax
*ret\pointer = *pointer
ElseIf (type = #Byte)
byte.b = 0
! MOV byte [p.v_byte], al
*ret\byte = byte
ElseIf (type = #Word)
word.w = 0
! MOV word [p.v_word], ax
*ret\word = word
ElseIf (type = #Long)
long.l = 0
! MOV dword [p.v_long], eax
*ret\long = long
ElseIf (type = #Quad)
quad.q = 0
! PUSH edx
! PUSH eax
! POP dword [p.v_quad+4]
! POP dword [p.v_quad+4]
*ret\quad = quad
ElseIf (type = #Float)
float.f = 0
! FSTP dword [p.v_float]
*ret\float = float
ElseIf (type = #Double)
double.d = 0
! FSTP qword [p.v_double]
*ret\double = double
ElseIf (type = #Character)
char.w = 0
! MOV word [p.v_char], ax
*ret\char = char
EndIf
FreeMemory(*memory)
EndProcedure
Procedure.f test(double.d, long.l, quad.q, *pointer)
Debug double
Debug long
Debug quad
Debug *pointer
ProcedureReturn 2.5
EndProcedure
NewList param.CFASM_PARAM()
InsertElement(param())
param()\type = #Double
param()\double = -1.234
InsertElement(param())
param()\type = #Long
param()\long = 12
InsertElement(param())
param()\type = #Quad
param()\quad = 247932409487029348
InsertElement(param())
param()\type = #Pointer
param()\pointer = @param()
ret.CFASM_PARAM\type = #Float
CallFunctionASM(@test(), param(), ret)
Debug "----------"
Debug ret\float
Re: 'CallFunctionFast' manuell mit ASM
Sorry für die Leichenfledderrei, aber ich bräuchte das für ein Projekt sowohl für X64 als auch für x86 (der obrige Funktioniert nicht mehr).
Ich möchte einen String auswerten und damit eine Function aufrufen.
etwa so in Pseudocode:
Die Functionsadresse bekommt man ja leicht mit den Runtime Library raus.
Wenn man nur Integer übergeben will, dann ist es auch noch kein Problem. Da geht CallfunctionFast und eine sehr langen Select-Case (für jede Parameteranzahl eine andere).
Strings übergeben ist da auch kein Problem, da übergibt man bei CallfunctionFast einfach die Adresse auf den String.
Nur mit Floats/Double streikt CallFunctionFast komplett, da geht überhaupt nichts.
Ich möchte einen String auswerten und damit eine Function aufrufen.
etwa so in Pseudocode:
Code: Alles auswählen
Runtime Procedure Get(w1,w2,w3)
;magische Funktion
EndProcedure
Runtime Procedure output(text.s)
;noch mehr magie
EndProcedure
Runtime Procedure SetF(float.f)
;reinste hexerei!
EndProcedure
Threaded CallStringRet.s
Procedure CallString(*ret.integer,String.s)
;zerlegen
;functionsname mit runtime-library in Adresse *func übersetzen
;parameteranzahl finden
Select PCount
Case 0
ret=CallFunctionFast(*func)
Case 1
ret=CallFunctionFast(*func,f1)
;usw.
EndSelect
CallStringRet=Str(ret)
*ret\i=@CallStringRet
Procedure #True ;wurde ausgeführt.
EndProcedure
adr.i
CallString(@adr,"Get(10,20,44)"):
Debug PeekS(adr)
CallString(@adr, ~"Output(\"test\")"):
Debug PeekS(adr)
CallString(@adr,"SetF(10.4F)"):
Debug PeekS(adr); (F kennzeichnet hier die Float-Zahl).
Wenn man nur Integer übergeben will, dann ist es auch noch kein Problem. Da geht CallfunctionFast und eine sehr langen Select-Case (für jede Parameteranzahl eine andere).
Strings übergeben ist da auch kein Problem, da übergibt man bei CallfunctionFast einfach die Adresse auf den String.
Nur mit Floats/Double streikt CallFunctionFast komplett, da geht überhaupt nichts.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Re: 'CallFunctionFast' manuell mit ASM
Wenn es nicht eine Fremd_Lib ist versuch es doch mal den Variablentype Variant.
P.S. Wenn es sich um eine 32Bit Anwendung handelt, musst du einfach ein Double als als zwei Parameter auflösen...
P.S. Wenn es sich um eine 32Bit Anwendung handelt, musst du einfach ein Double als als zwei Parameter auflösen...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive