Seite 2 von 2

Verfasst: 27.06.2009 11:28
von CSHW89
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].

Verfasst: 02.07.2009 16:04
von CSHW89
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:

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

Verfasst: 06.01.2016 01:02
von GPI
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:

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). 
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.

Re: 'CallFunctionFast' manuell mit ASM

Verfasst: 06.01.2016 01:32
von mk-soft
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...