Question

I have an array with 32bit values (nativeParameters with length nativeParameterCount) and a pointer to the function (void* to a cdecl function, here method->nativeFunction) thats supposed to be called. Now I'm trying to do this:

// Push parameters for call
if (nativeParameterCount != 0) {
    uint32_t count = 0;
pushParameter:
    uint32_t value = nativeParameters[nativeParameterCount - count - 1];
            asm("push %0" : : "r"(value));
    if (++count < nativeParameterCount) goto pushParameter;
}

// Call method
asm("call *%0" : : "r"(method->nativeFunction));

// Return value
uint32_t eax;
uint32_t edx;
asm("push %eax");
asm("push %edx");
asm("pop %0" : "=r"(edx));
asm("pop %0" : "=r"(eax));
uint64_t returnValue = eax;

// If the typesize of the methods return type is >4 bytes, or with EDX
Type returnType = method->returnType.type;
if (TYPE_SIZES[returnType] > 4) {
    returnValue |= (((uint64_t) edx) << 32);
}

// Clean stack
asm("add %%esp, %0" : : "r"(parameterByteSize));

Is this approach suitable to perform a native call (assuming that all target functions accept only 32bit values as parameters)? Can I be sure that it doesn't destroy the stack or mess with registers, or somehow else influence the normal flow? Also, are there other ways of doing this?

Was it helpful?

Solution

Instead of doing this manually yourself, you might want to use the dyncall libary which does all this handling for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top