Italia
Assembler Foro

ASM: StdCall mit beliebig vielen Parametern

 
- Page 1 -



Uwe
''Pascal''
Niemeier
Hi Leute!

In der Hoffnung, daß hier der eine oder andere ASM-Kenner mitliest, stelle ich mal 'ne Frage:

Ich suche eine Möglichkeit, eine StdCall-Funktion mit beliebig vielen Parametern aufzurufen.
Das das grundsätzlich possibile ist, zeigt dieses Snippet:
TestX proc ;----------------------------------------------------
push ebp
mov eax,ebp
sub eax,esp
sub eax,64
pop ebp

.IF eax==4

    ret 4

.ELSEIF eax==8

    ret 8

.ELSEIF eax==12

    ret 12

.ELSEIF eax==16

    ret 16

.ENDIF

TestX endp;-----------------------------------------------------

Das klappt sowohl als Funktion in einer dll als auch als "Embedded ASM" direkt in Profan:
window 800,600
declare a#:dim a#,48
long a#,0=734366549,1088979908,83395421,79824245
long a#,16=-2095256832,91556088,-352319294,217613074
long a#,32=214041973,-2096567552,58003704,4290
print call(a#,1)
print call(a#,1,2)
print call(a#,1,2,3)
print call(a#,1,2,3,4)
waitinput

Nun denke ich aber, es sollte auch einfacher und universeller gehen, indem man durch verbiegen von Pointern mit einem einfachen RET auskommt und sich den Bandwurm von IF-Abfragen sparen kann (RET akzeptiert ja keine Register als Parameter).
Stehe da allerdings etwas auf dem Schlauch, was Stack-Manipulationen betrifft.

Kann jemand helfen?

[OFFTOPIC]BTW: @ iF: Hab's irgendwie nicht hingekriegt, dieses Posting unter "Assembler" abzulegen [/OFFTOPIC]


SeeYou
Pascal
 
05.11.2010  
 



« Dieser Beitrag wurde als Lösung gekennzeichnet. »

Hallo Uwe, ist gelungen...

bzw.

bzw.

Ablauf fehlerfrei getestet unter 32Bit WinXP XProfan 11.

Man muss halt die Rücksprungandresse sichern und diese nach künstlichem Reduzieren des Stacks an die neue Stackposition ablegen.

Würde mich freuen wenn Du damit etwas anfangen kannst.
 
05.11.2010  
 



Ich glaube ich wüsste schon wie man das ... ich teste das heute Abend gleich mal und berichte. (ohne Ifs, Schleifen und jmp eax*sonstwas)

[OFFTOPIC]Hab den Topic per DB nach Assembler verschoben. Als ich eben probierte hier in unter Assembler Topics zu erzeugen (auch gleichnamige) funktionierte das problemlos. Was genau war passiert das sich das Thema hier nicht ablegen ließ?[/OFFTOPIC]
 
05.11.2010  
 



Hallo Uwe, ist gelungen...

bzw.

bzw.

Ablauf fehlerfrei getestet unter 32Bit WinXP XProfan 11.

Man muss halt die Rücksprungandresse sichern und diese nach künstlichem Reduzieren des Stacks an die neue Stackposition ablegen.

Würde mich freuen wenn Du damit etwas anfangen kannst.
 
05.11.2010  
 




Uwe
''Pascal''
Niemeier
Hi iF!

Klasse! Haut hin!

Die Funktion soll immer nur einen konstanten Wert zurückgeben, aber eben bei beliebig vielen Parametern, unabhängig von deren Inhalt.

Ich will daraus eine universelle Dummy-Funktion per OLE-Interfaces basteln (war ja klar )
Leider klappt eben das noch nicht, wahrscheinlich weil gerade da meine Berechnung der Rücksprungadresse/Parameterzahl nicht stimmt. Aber das kriege ich raus...

Danke per deine Aiuto!

PS: Wenn du dies liest hat das Posting geklappt

SeeYou
Pascal
 
07.11.2010  
 



Juhu ^^

Stumpf gesagt reichts scheinbar wenn am Funktionkopf
steht um den Stack per ret 0 zu präparieren bei egal wie vielen Params.
 
07.11.2010  
 




Uwe
''Pascal''
Niemeier
Nachtrag @ iF:

Trotz deiner Lösung werde ich diese Technik wohl nicht verwenden können
Anscheinend kann es vorkommen, daß der Aufrufer ( in meinem Fall Windows selbst, das die Methoden meines Interfaces aufruft ) vor dem Funktionsaufruf Werte per den Eigenbedarf auf den Stack pusht, die gar nicht als Parameter per die Funktion vorgesehen sind.
Und damit ist die Parameterberechnung durch ebp minus esp  hinfällig
Also ist es weiterhin nötig, per jede Parameterzahl eine eigene Dummy-Funktion bereitzustellen. Aber den Versuch war's wert!

SeeYou
Pascal
 
10.11.2010  
 



Sorry, da habe ich ad hoc auch keine Idee - besonders wenn die Aufruferfunktion auch mit dem Stack werkelt.

Ich potuto mir noch vorstellen das "Win" die Differenz in solch Fall in einem Register mitliefert oder per Stack - da eine Abhängigkeit herauszufummeln ist aber bestimmt ziemlich "irre".
 
10.11.2010  
 



Obwohl...

Wenn Du mal lauter Longs vom Stack einfach frech in einen Debugviewer puschst ...

vlt. klappts ja wenn man mehr als nur 1 Long zurücksichert.
 
10.11.2010  
 




Uwe
''Pascal''
Niemeier
Hi iF!

Ich glaube inzwischen nicht mehr, daß das Ganze machbar ist:
Jede Methode hat nun mal eine feste Anzahl Parameter, und derjenige, der die Methoden bereitstellt (und darum geht es ja), hat eben dafür Sorge zu tragen, daß diese Parameter korrekt bearbeitet werden. Warum sollte sich M$ die Mühe machen, diese Anzahl irgendwo einzubauen? Und wenn, wäre es eben undokumentiert und damit seeeehr wackelig...Die Idee mit der MultiParameter-Methode ist ja auf meinem Mist gewachsen
Außerdem hält sich der Aufwand bei der bisherigen Technik auch in Grenzen; hier eine Version des OLE-RTF-Controls:
window 800,600
 $H Windows.ph
 $H RichEdit.ph
usermessages 16'--WM_CLOSE
def StgCreateDocfileOnILockBytes(4) !"ole32","StgCreateDocfileOnILockBytes"
def CreateILockBytesOnHGlobal(3) !"ole32","CreateILockBytesOnHGlobal"
def &NI $80004001'--Not Implemented
def &OK 0'----------OK

proc CreateIMD'---------------------------------------InterfaceMethodDummy

    var a&=~GlobalAlloc(0,8)
    byte a&,0=$B8'-------mov eax,&(2)
    long a&,1=&(2)'------Rückgabe: vorgegebene Konstante
    byte a&,5=$C2'-------ret &(1)*4+4
    word a&,6=&(1)*4+4'--Anzahl Parameter * 4 + "This"-Pointer
    return a&'-----------Fertige Funktion im Speicher
    '--PS: Mit ein paar NOP's zum Verschieben der Platzhalter paßt alles in 1 Zeile mit 4 LongInts

endproc'------------------------------------------------------------------

proc GetNewStorage'------------------------------------------GetNewStorage

    parameters IFace&,IStorage&
    declare ILockBytes&
    CreateILockBytesOnHGlobal(0,1,addr(ILockBytes&))
    StgCreateDocfileOnILockBytes(ILockBytes&,$1012,0,IStorage&)
    call(long(long(ILockBytes&,0),8),ILockBytes&)'--ILockBytes::Release
    return &OK

endproc'------------------------------------------------------------------

declare VTable#:dim VTable#,60'-----------------------IRichEditOleCallback-Interface
long VTable#, 0=CreateIMD(1,&NI)'-------------QueryInterface
long VTable#, 4=CreateIMD(0,&NI)'-------------AddRef
long VTable#, 8=CreateIMD(0,&NI)'-------------Release
long VTable#,12=procaddr("GetNewStorage",2)'--GetNewStorage
long VTable#,16=CreateIMD(3,&NI)'-------------GetInPlaceContext
long VTable#,20=CreateIMD(1,&NI)'-------------ShowContainerUI
long VTable#,24=CreateIMD(3,&OK)'-------------QueryInsertObject
long VTable#,28=CreateIMD(1,&NI)'-------------DeleteObject
long VTable#,32=CreateIMD(5,&OK)'-------------QueryAcceptData
long VTable#,36=CreateIMD(1,&NI)'-------------ContextSensitiveHelp
long VTable#,40=CreateIMD(3,&NI)'-------------GetClipboardData
long VTable#,44=CreateIMD(3,&NI)'-------------GetDragDropEffect
long VTable#,48=CreateIMD(4,&NI)'-------------GetContextMenu
long VTable#,52=VTable#
var IFace&=VTable#+52
var Edit&=create("richedit",%hwnd,"",20,20,500,500)
sendmessage(Edit&,~EM_SETOLECALLBACK,0,IFace&)'---EM_SETOLECALLBACK
var File$=loadfile$("RTF mit Objekten wählen","*.rtf")
Rtf("LoadRTF",Edit&,File$)

while 1

    waitinput
    case %umessage=16:break

endwhile

sendmessage(Edit&,~EM_SETOLECALLBACK,0,0)
destroywindow(Edit&)
dispose VTable#
'--Hier müßten eigendlich alle Methoden-Dummys mit ~GlobalFree() freigegeben werden

War aber gut, mal wieder ein wenig ASM zu üben

SeeYou
Pascal
 
12.11.2010  
 



Answer


Topictitle, max. 100 characters.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Posting  Font  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Topic-Options

9.162 Views

Untitledvor 0 min.
Jens-Arne Reumschüssel06.01.2024
funkheld30.12.2021
RudiB.13.11.2021
p.specht27.05.2020
Di più...

Themeninformationen

Dieses Thema hat 2 subscriber:

iF (5x)
Uwe ''Pascal'' Niemeier (4x)


Admins  |  AGB  |  Applications  |  Autori  |  Chat  |  Informativa sulla privacy  |  Download  |  Entrance  |  Aiuto  |  Merchantportal  |  Impronta  |  Mart  |  Interfaces  |  SDK  |  Services  |  Giochi  |  Cerca  |  Support

Ein Projekt aller XProfaner, die es gibt!


Il mio XProfan
Private Notizie
Eigenes Ablageforum
Argomenti-Merkliste
Eigene Beiträge
Eigene Argomenti
Zwischenablage
Annullare
 Deutsch English Français Español Italia
Traduzioni

Informativa sulla privacy


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie