Je moet alle pointers (/argumenten, wat het ook zijn) ook pushen, alleen bij de C calling convention moet je dat in omgekeerde volgorde doen. De return waarde van de functie (als dat is wat je bedoelt met return pointer) geef ik wel terug, de conventie is namelijk dat voor een int (of het meeste wat even groot is als een int) teruggegeven wordt in eax.
Bewaart ebx op de stack, omdat ebx/esi/edi/ebp onveranderd moeten zijn na het uitvoeren van een functie.
code:
1
2
3
| mov ecx, [esp+0Ch] ; numArgs
mov eax, [esp+08h] ; pFunc
mov edx, [esp+10h] ; pArgs |
Haalt de drie argumenten van de functie op en stopt ze in ecx (numArgs), eax (pFunc) en edx (pArgs).
code:
1
2
3
| test ecx, ecx
mov ebx, ecx
jz _callFunc |
Kijkt of ecx 0 is (geen parameters), kopieert ecx naar ebx omdat die later nodig is en ebx niet door aan te roepen functie gewijzigd wordt maar ecx wel. Bovendien wordt ecx ook nog gewijzigd in de loop. Als ecx 0 was wordt het pushen van de parameters overgeslagen en direct de functie aangeroepen (jump naar _callFunc), anders valt ie er doorheen en gaat ie de parameters pushen:
code:
1
2
3
4
| _pushParams:
push dword ptr [edx+ecx*4-4]
dec ecx
jnz _pushparams |
edx is een pointer naar de parameter lijst. ecx is in het begin het aantal parameters. Nu moeten de parameters in omgekeerde volgorde gepusht worden, dus bijvoorbeeld bij 4 parameters eerst index 3, dan 2, dan 1 en dan 0.
De array begint bij edx, vanaf dan neemt elke index 4 bytes in (int). Element x staat dus op edx + 4 * x. In dit geval kan je dan dus edx + 4 * ecx gebruiken, alleen moet er nog een - 4 bij omdat ecx in het begin 1 meer dan de hoogste index is (aantal elementen -1 = hoogste index).
Dan wordt in elke iterator ecx met 1 verminderd en teruggesprongen als die nog niet 0 is (=nog niet klaar). Bovenstaande komt dus overeen met:
C:
1
2
3
4
5
6
7
| int ecx = aantal parameters;
int *edx = pointer naar array;
while(ecx>0)
{
push(edx[ecx-1]);
ecx--;
} |
Dan:
De functie pointer zat in eax, dus call eax voert gewoon de functie uit.
De C calling convention zegt dat de caller de stack moet opruimen. In dit geval is dat aan ruimte aantal parameters * 4. Ebx was het aantal parameters, 'shl ebx, 2' is ebx<<2 oftewel ebx*4. 'Add esp, ebx' zorgt dat de stack pointer opgehoogd wordt met de juiste waarde zodat deze weer correct is.
Geef ebx z'n orginele waarde terug en return naar de caller. Na de 'call eax' is de return waarde van die functie in eax gezet. Eax is daarna niet meer aangepast en wordt door de caller dus gezien als de return waarde van deze functie.
[
Voor 4% gewijzigd door
madwizard op 04-06-2003 22:34
]