【问题标题】:How do you pass a string as an argument to the "call" instruction in inline assembly?如何将字符串作为参数传递给内联汇编中的“调用”指令?
【发布时间】:2010-02-18 18:12:27
【问题描述】:

基本上,我希望能够做这样的事情:

//assume myFunction is defined and takes one argument that is an int
char * functionName = "myFunction";
int arg = 5;

__asm{
    push a
    call functionName
}

基本上我想调用一个名称存储在字符串中的函数。这样做的正确语法是什么?

编辑: 我们在谈论 x86 汇编

【问题讨论】:

  • 改写问题。 single int 作为参数 char * 是什么意思?你错过了一个重要的细节——你在看什么样的处理器?您想要大致的想法还是实际的类似 x86 的汇编代码?
  • 我看不懂样本。调用不能是字符串,它必须是函数指针。您需要获取指向该函数的指针才能调用它。一种可能性是在您自己的 DLL 上使用 GetProcAddr。
  • 对不起,混淆了,我的意思是该函数接受一个 int 类型的参数:被调用的函数并不重要,我只是在解释为什么我将 "a: 推入堆栈。

标签: assembly call inline-assembly


【解决方案1】:

你不能,至少不能直接。

call 将地址作为参数。即使您编写了“调用函数名”,链接器也会将函数名替换为函数的实际地址。您需要首先将该字符串映射到其地址。通常,C 和 C++ 不支持任何类型的关于函数名称映射的运行时元数据,从而允许这样做。如果函数是从 DLL 中导出的,您可以使用 GetProcAddress 找到它的地址。

如果函数列表是静态的,您可以自己提前创建映射。

类似:

std:map<string, PVOID> functionMappings;
functionMappings["MyFunction"] = MyFunction;


// Later


PVOID function = functionMappings["MyFunction"];

__asm
{
    push a;
    call [function]
}

一些注意事项:

我相信标准说函数指针可能大于 PVOID。这应该适用于 Windows x86/x64 平台。

您没有说您使用的是什么调用约定 - 此代码假定 stdcall。

这是一件非常非常奇怪的事情——你想解决什么问题?

【讨论】:

  • 我想我需要使用GetProcAddress。对不起,如果这是一个愚蠢的问题,但是该函数的类型返回值是什么?例如,int a = GetProcAddress( dllHandle, "myFunction" ); 会起作用吗?
  • 顺便说一句,代码中暗示了什么 __stdcall ?仅仅是调用者没有从堆栈中弹出参数,还是有其他原因?
  • __stdcall 是一种调用约定——如果您正在编写执行函数调用的程序集,您需要了解调用约定。网上有很多资源可用于 GetProcAddress 和调用约定。 MSDN 甚至有示例代码展示了如何使用 GetProcAddress 的返回值。
【解决方案2】:

这是不可能的,您正在尝试按名称调用操作。汇编程序只有一个按值调用,其中 value 是一个地址。您需要将名称转换为地址并将地址传递给汇编程序,这意味着您需要在名称和地址之间进行某种交叉引用。编译器可以在这里为您提供帮助,在 C 和 C++ 中,您需要查找函数指针以查看获取函数地址所需的语法,然后可以将其传递给汇编器。

先发制人:是的,有时编译器可以将符号嵌入到可执行文件中,然后可以对其进行搜索,但这是一种充满问题的方法。数据的格式可以在编译器版本之间改变,信息可以被链接器剥离等等。

【讨论】:

    【解决方案3】:

    我不知道有什么方法可以轻松做到这一点。在一些高级语言中,您可以使用反射来实现这一点,但 C 和汇编都没有该功能可用。到链接器完成时,所有函数调用都解析为地址。也许如果您可以访问一些调试基础设施,您可以对函数名称进行反向查找以获取其地址,但这并不是一件容易从汇编中实现的事情。

    或者您可以使用在编译时定义的函数指针来存储您感兴趣的函数的地址(尽管您仍然需要一些方法将您的字符串转换为函数指针,大概是通过字符串比较表查找) .如果这是您感兴趣的事情,我建议您编写 C 等效项,然后查看编译器输出的汇编代码以了解它如何处理函数指针。

    【讨论】:

      猜你喜欢
      • 2013-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      • 1970-01-01
      • 2011-01-19
      • 2016-09-08
      • 2023-04-08
      相关资源
      最近更新 更多