如何使用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字节和地址数据。
匹配下游逻辑
修正后的代码生成的二进制数据完全符合下游程序的读取逻辑:
- 代码段中先写入3个0字节,对应下游
fseek(f, Section.ptrToRaw+3, SEEK_SET)跳过前3字节的操作。 - 紧接着写入
RegisterTable的4字节地址,下游通过fread读取该地址后进行计算处理。
内容的提问来源于stack exchange,提问作者bobix
相关产品推荐
相关产品推荐

