You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GCC编译器编译含DB、DD指令的内联汇编代码?

解决GCC编译遗留C模块中PE地址写入的内联汇编问题

问题根源

原代码采用MSVC风格的内联汇编(asm db/dd),而GCC默认使用GNU汇编器(GAS),采用AT&T语法,不兼容MASM的指令格式,导致编译报错。你之前修改的代码中,.long word ptr RegisterTable里的word ptr是MASM特有的内存操作符,GAS无法识别,因此出现junk at end of line错误。

修正后的代码

extern void *RegisterTable;
void REGISTER(void) {
    // 使用volatile防止GCC优化删除无副作用的汇编代码
    asm volatile (
        ".byte 0, 0, 0\n\t"  // 对应原代码的db 0,0,0
        ".long RegisterTable\n\t"  // 对应原代码的dd RegisterTable,直接写入符号地址
    );
}

关键说明

  • .byte 0,0,0:和原MSVC的db 0,0,0功能完全一致,在代码段写入3个0字节。
  • .long RegisterTable:GAS的.long指令用于定义4字节数值,直接传入符号名RegisterTable,汇编器会自动将其解析为该符号的内存地址,写入代码段中,替代原MASM的dd word ptr RegisterTable(原代码中word ptr属于冗余写法,因为dd本身就是定义4字节双字)。
  • asm volatile:添加该关键字是为了防止GCC因优化(认为REGISTER函数无输出/副作用)而删除这段汇编代码,确保代码段中始终存在需要的0字节和地址数据。

匹配下游逻辑

修正后的代码生成的二进制数据完全符合下游程序的读取逻辑:

  1. 代码段中先写入3个0字节,对应下游fseek(f, Section.ptrToRaw+3, SEEK_SET)跳过前3字节的操作。
  2. 紧接着写入RegisterTable的4字节地址,下游通过fread读取该地址后进行计算处理。

内容的提问来源于stack exchange,提问作者bobix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 10:12:31