【问题标题】:Is it correct to perform a function call like this?执行这样的函数调用是否正确?
【发布时间】:2015-06-14 20:37:09
【问题描述】:

我有一个包含 32 位值的数组(nativeParameters,长度为 nativeParameterCount)和一个指向函数的指针(void* 指向 cdecl 函数,这里是 method->nativeFunction)应该被调用。现在我正在尝试这样做:

// 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));

这种方法是否适合执行本机调用(假设所有目标函数只接受 32 位值作为参数)?我可以确定它不会破坏堆栈或弄乱寄存器,或者以其他方式影响正常流程吗?另外,还有其他方法吗?

【问题讨论】:

  • nativeParameterCount 是什么? nativeParameters 是什么?你为什么要gotoing 而不是使用for 循环?
  • 让我们退后一步:你真正想用这个完成什么?你想调用一个你有函数指针的函数吗?
  • 这完全不安全。例如,在编译器不知情的情况下推入堆栈可能会弄乱任何局部变量引用。你不应该为此使用内联 asm,编写一个单独的 asm 模块,你可以控制。
  • @maxdev 听起来您想使用汇编来编写此代码。 (或者如果你真的想用 C 来写,那么用 C, 而不是半 C 半汇编。)
  • 此外,根据架构/平台,参数可能会在寄存器中传递,而不是被压入堆栈(例如,在x86-64 上)。

标签: c assembly virtual-machine inline-assembly vm-implementation


【解决方案1】:

您可能希望使用 dyncall libary 为您完成所有这些处理,而不是自己手动执行此操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-16
    • 2019-10-23
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    相关资源
    最近更新 更多