使用MinGW编译含汇编代码的32位PE格式C文件报错求助
MinGW编译含汇编代码的32位PE格式C文件报错求助
嘿,我来帮你拆解下问题根源,你遇到的三个编译错误都是汇编语法不匹配和指令使用错误导致的,具体解决思路如下:
1. jz/jnz操作数类型不匹配的问题
你写的汇编代码是Intel风格的语法(比如jz $ + $13这种基于当前指令地址的偏移写法),但MinGW的GCC默认使用AT&T汇编语法,两种语法的操作数格式、跳转偏移逻辑完全不同,所以汇编器会报错“操作数类型不匹配”。
解决办法有两种:
- 最省心的方式:编译时给GCC加
-masm=intel参数,强制使用Intel汇编语法; - 或者把代码改成AT&T风格的跳转写法(不过Intel风格对x86开发者更直观,推荐前者)。
另外,手动计算跳转偏移很容易出错,建议用标签替代硬编码的偏移量,比如:
__asm__ __volatile__( "jz skip_block\n\t" "jnz jump_over\n\t" // 这里放你要执行的中间代码 "skip_block:\n\t" // ...后续代码 "jump_over:\n\t" );
2. emit %0xe8指令不存在的问题
emit是MASM等汇编器的指令,用来直接插入字节数据,但MinGW用的GNU汇编器(GAS)不认识这个指令,你需要替换成GAS支持的.byte关键字,把emit %0xe8改成.byte 0xe8即可。
修正后的完整代码示例
#include <stdio.h> int main() { __asm__ __volatile__( "jz $ + 13\n\t" "jnz $ + 7\n\t" ".byte 0xe8\n\t" ); return 0; }
正确的编译命令
加上-masm=intel参数指定Intel语法,确保代码能被正确解析:
i686-w64-mingw32-gcc -masm=intel file.c -o file.exe
这样编译应该就能解决你遇到的三个错误了,要是还有细节问题可以再补充说明~
备注:内容来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

