【问题标题】:Visual Studio - Compiling 32-bit code inside 64-bit projectVisual Studio - 在 64 位项目中编译 32 位代码
【发布时间】:2017-08-03 09:07:46
【问题描述】:

直接问我的问题:如何使用 32 位 ASM 编译器编译我的 ASM 文件,将其包含在我的 64 位项目中,并使用 ASM 文件的函数名访问编译后的代码?

如果有点不清楚,我可以详细说明:

我正在将我的一个项目从 32 位转换为 64 位,但遇到了技术问题。我的项目编译了一个 ASM 文件并使用编译后的二进制文件作为输入。

当我的项目是 32 位时,这很容易。我在项目中包含了 ASM 文件,并添加了一个构建规则以使用 Microsoft Macro Assembler 编译它们 - 然后我可以通过将我想从 ASM 访问的每个函数导出到 .h 来访问我的 32 位项目中的编译代码头文件并使用函数名访问它(我能够这样做是因为它被编译为 obj 并且链接器知道这些符号,因为我将原型导出到 .h 文件)。

现在,我需要将此代码转换为 64 位,但我仍然需要将 ASM 编译为 32 位代码并且仍然能够执行相同的操作(从我的 64 访问已编译的 32 位代码位程序)。 但是,当我尝试编译它时,它显然无法识别指令,因为现在整个项目正在编译为 64 位代码。

提前致谢。

【问题讨论】:

  • 您不能在 64 位进程中加载​​或运行 32 位代码。您的选择是更新汇编代码(让它编译为 64 位:您可能不需要更改代码);或在自己的进程中运行 32 位代码(与父进程进行某种形式的进程间通信)。
  • @Richard,没说我需要运行它。我需要使用编译后的 32 位代码作为程序的输入
  • @Richard,要清楚,让我们假设我的 64 位应用程序有一个缓冲区,它需要用我的 .ASM 文件中编译的 32 位函数代码填充,我仍然需要.ASM 文件将包含在我的项目中,但编译为 32 位代码
  • 我没有 VS,但我希望它 to be able to customize the buildchain 或处理文件的方式。应该调用ml 而不是ml64
  • 这正是我现在所做的,我将它设置为 ml.exe 而不是 ml64.exe 用于使用自定义构建工具而不是 Microsoft 汇编器的 32 和 64 配置:) 现在代码编译但我还没有检查链接器是否可以正常工作。一旦我得到它的工作,我会把它作为答案发布。

标签: c windows visual-studio assembly x86


【解决方案1】:

如果我试图将 32 位代码嵌入到 64 位程序中(这是一件可疑的事情,但为了争论,假设您有充分的理由并且实际上知道自己在做什么结果)——我会采用 32 位代码,无论是用 C、汇编还是其他东西编写的——并将其编译为一个单独的项目,生成一个 DLL 作为输出。这不涉及编译链中的额外怪异:它只是一个普通的 32 位 DLL。

然后,该 32 位 DLL 可以作为二进制资源嵌入到您的 64 位应用程序中 — 只是您可以加载和访问的一块内存。

那么,您实际上如何使用该 DLL 中的已编译代码执行任何操作呢?我会使用 Joachim Bauch 的 MemoryModule 库的一个有点被破解的版本来访问它。 MemoryModule 旨在从一大块内存中加载 DLL 并提供对其导出的访问——就像 Windows API 的 LoadLibrary() 一样,仅从内存而不是从文件中。它旨在以与调用进程相同的位大小来执行此操作,但有点骇人听闻,您可能可以将其编译为 64 位库,但能够读取 32 位库。由此产生的用法将非常简单:

// Load the embedded DLL first from the current module.
hresource = FindResource(hmodule, "MyLibrary.DLL", "binary");
hglobal = LoadResource(hmodule, hresource);
data = LockResource(hglobal);
size = SizeofResource(hmodule, hresource);

// Turn the raw buffer into a "library".
libraryHandle = MemoryLoadLibrary(data, size);

// Get a pointer to some export within it.
myFunction = MemoryGetProcAddress(libraryHandle, "myFunction");

也就是说,正如我之前提到的(以及其他人也提到的),即使您可以获得指向导出的指针,您也无法调用它们,因为代码是 32 位的,甚至可能不是加载到低于 4GB 标记的地址。但如果你真的想在 64 位应用程序中嵌入 32 位代码,我会这样做。

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 2013-03-20
    • 2017-01-21
    • 2011-05-01
    • 1970-01-01
    • 2014-11-05
    • 2019-05-01
    • 2011-04-12
    • 1970-01-01
    相关资源
    最近更新 更多