如何使用GCC编译器编译DB和DD汇编指令

问题描述 投票:0回答:1

我正在尝试使用 gcc 编译器在我的项目中编译遗留模块(用 C 编写)。我正在使用 codeblocks IDE 进行编译。我能够解决我遇到的大部分问题,但无法使用 gcc 编译以下内联汇编代码。

extern void *RegisterTable;

    void REGISTER(void) {
      asm db 0,0,0
      asm dd word ptr RegisterTable
    }

gcc 无法识别 db 和 dd 指令。因此,我尝试将上面的代码更改为如下所示,以期在 gcc 中编译

    extern void *RegisterTable;
    void REGISTER(void) {
      asm
      (
      ".byte 0,0,0\n\t"
      ".long word ptr RegisterTable\n\t"
      );
}

但是这段代码在第二行“.long word ptr RegisterTable”中也给出了以下错误 "" 因为它无法识别 PTR

错误:行尾有垃圾,第一个无法识别的字符是 `p'

非常感谢任何有关如何使用 gcc 编译此汇编代码的帮助。

编辑:使用的汇编程序是'as',默认情况下是gcc。此外,这段代码是将“RegisterTable”函数的地址放在特定位置 - 具体来说,第一个“db”指令将三个零作为代码段的前 3 个字节,第二个“dd”指令将RegisterTable 函数的地址作为二进制文件代码段的第 4 位。二进制文件是 PE 格式(windows 文件格式)。处理二进制文件的下游进程会查找此地址进行处理。它是通过首先读取 PE 头结构,然后从 PE 头中找到代码段来完成的,在找到代码段的开始后,下游进程使用下面的代码读取上面代码放置的 RegisterTable 函数的地址在我的问题

  // Get Registration table 
  fseek(f, Section.ptrToRaw+3, SEEK_SET); //Skip the 0,0,0
  fread(&ptrTab, sizeof(ptrTab), 1, f);
  M->RTab = GetRegisterTable32(M->Mem, ptrTab-PEHdr.imgBase-PEHdr.baseOfData);
c gcc codeblocks
1个回答
1
投票

gcc 允许您在函数之外使用内联汇编。所以你可以简单地做以下,outside任何功能:

asm(".text \n\t"
    ".byte 0,0,0 \n\t"
    ".long RegisterTable");

这将在您的代码部分中放置三个零字节,后跟

RegisterTable
的地址。

请注意,GNU 汇编程序不需要任何类似于

word ptr
的东西;这是特定于想要跟踪对象类型的类似 MASM 的汇编器。

如果您的平台在 C 定义的符号上使用前导下划线,那么您可能必须改用

_RegisterTable

如果符号

REGISTER
在任何地方使用(不在您显示的代码中),则:

asm(".global REGISTER \n\t"
    ".text \n\t"
    "REGISTER: \n\t"
    ".byte 0,0,0 \n\t"
    ".long RegisterTable");

然而,困难的部分是确保这三个字节在可执行文件的代码段中是first。仅仅把它放在你的

.c
文件的顶部可能不会可靠地工作。编译器和/或链接器很有可能会在其前面放置其他内容,例如启动或库代码。您可以使用链接描述文件来完成此操作,但这可能会很痛苦。这是我认为你应该作为一个单独的问题提出的问题。

从长远来看,你最好的选择可能是弄清楚为什么程序需要从它自己的可执行文件中解析数据,因为这是一件很奇怪的事情,并重新设计这方面以使用更容易和更不脆弱的东西(例如,从一个单独的平面文件中读取它,或加载一个 DLL)。

© www.soinside.com 2019 - 2024. All rights reserved.