octacone wrote:I need some quick help.
How do I do this:
Code: Select all
C code:
void MyFunction(void* test1, void* test2, size_t size)
{
MyFunctionDoAssembly(test1, test2, size);
}
NASM Code:
MyFunctionDoAssembly:
mov test1, esi
mov test2, edi
mov size, ebx
I am assuming you are asking about how to get at the location of the variables test1, test2 etc.
Forgive me if I seem to be teaching you to suck eggs, but if you haven't worked at assembly level before you may not know some of this.
Firstly, you must know how yor C code will carry out the calling of "MyFunctionDoAssembly", called the 'calling convention'
Traditional C put size, test2, and test1 onto the stack and then did a call instruction. This is called the C calling convention and note that the parameters go on to the stack
from the end i.e. backwards. There are good reasons for doing this, principally to allow C to implement functions with varying numbers of parameters, like printf, but that doesn't need to be explained in detail here. Another issue is whether the caller or the called function 'cleans up the stack' at the end of the call. An advantage of the C calling convention from your point of view is that the caller is responsible, so your assembler function doesn't have to worry about that
An alternative method is to use the Pascal or Standard calling conventions in which the parameters are put on the stack forwards, or a register calling convention where the parameters don't go on to the stack at all and are passed in registers.
To be sure what happens you should declare your functions with an explicit calling convention and I'm using the C convention as an example here: "_cdecl void MyFunctionDoAssembly
The start of your function can then be like this:
push ebp ;Save ebp so the calling routine gets it back in tact
mov ebp esp ;ebp now provides a stable pointer into the stack
The stack (working upwards from what ebp points to) now looks this this
ebp -> Currently the value of esp, but esp may alter during your routine
[ebp+4] Old value of ebp that you have just pushed
[ebp+8] Return address for getting back to the calling function
[ebp+12] *test1 [Lowest in memory, pushed on to the stack most recently]
[ebp+16] *test2
[ebp+20] size4 [Highest in memory, pushed on to the stack first by the caller]
so mov test1,esi is coded mov [ebp+12], esi
{{EDIT}}
Whoops! What a load of rubbish
[ebp+12] is of course a pointer to your real object so you will almost certainly require something like:
mov ebx [ebp+12]
mov [ebx] esi
or, if test1 is a structure:
mov [ebx+someoffset] esi
{{End edit}}
and when you've finished:
pop ebp
ret
Caveats
-----------
Don't know where you're writing your assembler function. If, for example, you are using inbuilt facilities within your compiler it may do some of this work for you and so you should not duplicate it. If your using a separate assembler, then it will also have conventions you can use to simplify all this. I've also assumed you're using a flat 32 bit model.