Windows10 x64下用ld编译32位汇编报错:unrecognised emulation mode: 32
解决Windows 10 x64下ld编译32位汇编报错"unrecognised emulation mode: 32"的问题
问题场景
在Windows 10 x64专业版环境下,尝试编译以下32位Linux风格汇编代码:
; [Assembly Tests].exe ; ; Tests ; Author: Simpfey global _start section .text: _start: mov eax, 0x4 mov ebx, 1 mov ecx, message mov edx, message_length int 0x80 mov eax, 0x1 mov ebx, 0 int 0x80 section .data: message: db "Hello World!", 0xA message_length equ $-message
执行链接命令:
ld -m32 -o ./build/Assembly.exe ./build/Assembly.o
时出现错误:unrecognised emulation mode: 32
解决方法
1. 换用适配32位Windows的链接器
你当前使用的ld大概率是64位版本,不支持-m32参数指定32位模式。可以直接调用MinGW-w64的32位专用链接器i686-w64-mingw32-ld,修改命令为:
i686-w64-mingw32-ld -o ./build/Assembly.exe ./build/Assembly.o
如果系统里没装MinGW-w64的32位组件,需要先通过包管理工具(比如Chocolatey)或者直接下载安装包补充安装。
2. 修正汇编代码的系统兼容性问题(核心)
你写的是Linux系统专属的汇编代码(依赖int 0x80系统调用、_start入口),但目标是生成Windows的.exe文件——两者的系统调用接口、程序入口规范完全不同,就算链接成功也无法在Windows上运行。如果要生成能在Windows执行的程序,需要修改代码适配Windows的PE格式和API:
- 入口点改为符合Windows规范的
_main - 调用Windows原生API(比如
WriteConsole、ExitProcess)替代Linux的int 0x80
修改后的32位Windows汇编示例:
; Windows 32位可执行汇编示例 global _main extern _GetStdHandle@4 extern _WriteConsoleA@20 extern _ExitProcess@4 section .text _main: ; 获取标准输出句柄 push -11 call _GetStdHandle@4 mov ebx, eax ; 输出字符串 push 0 push message_length push message push ebx call _WriteConsoleA@20 ; 退出程序 push 0 call _ExitProcess@4 section .data message: db "Hello World!", 0xA message_length equ $ - message
对应的编译链接命令(用MinGW-w64工具链):
nasm -f win32 -o ./build/Assembly.o ./Assembly.asm i686-w64-mingw32-gcc -m32 -o ./build/Assembly.exe ./build/Assembly.o
用gcc链接可以自动处理Windows PE文件的依赖,比直接调用ld更省心。
3. 若目标是编译Linux程序,改用WSL环境
如果你只是想编译Linux可执行文件而非Windows的.exe,直接在WSL(Windows子系统Linux)里安装nasm和binutils工具包,然后在WSL环境下执行原命令即可,完全不会出现兼容性问题。
内容的提问来源于stack exchange,提问作者czlowieczyna-czan
相关产品推荐
相关产品推荐

