x86 32位汇编调用write系统调用输出原始二进制乱码问题排查
问题根因
输出乱码的核心原因是字符串长度计算语法错误:
NASM 中计算字符串长度的标准写法是[长度标签] equ $ - [字符串起始标签],其中$代表当前行的汇编地址,二者差值就是字符串占用的字节数。
你代码中写的msg1Len equ -$msg1、msg2Len equ -$msg2存在两处错误:
- 错误给字符串标签加了
$前缀,$msg1属于非法地址引用 - 减法顺序写反且额外加了负号,计算得到的
msg1Len/msg2Len是极大的无符号整数值,导致write系统调用除了输出目标字符串,还会输出字符串后续内存中无关的二进制数据,也就是你看到的乱码。
另外原代码中的文件名没有添加字符串结束符0,存在概率性创建错误文件名的隐患。
修正后的完整代码
global _start _start: ; 打印第一条消息 mov eax, 4 mov ebx, 1 mov ecx, msg1 mov edx, msg1Len int 0x80 ; 创建文件 mov eax, 8 ; sys_creat 系统调用号 mov ebx, name ; 要创建的文件名 mov ecx, 0777 ; 文件权限 int 0x80 ; 触发系统调用 ; 打印第二条消息 mov eax, 4 mov ebx, 1 mov ecx, msg2 mov edx, msg2Len int 0x80 ; 退出程序 mov eax, 1 int 0x80 .data msg1 db "Making file", 0xa ; 末尾0xa为换行符,可按需删除,仅优化输出格式 msg1Len equ $ - msg1 ; 修正后的长度计算 msg2 db "File Made", 0xa ; 末尾0xa为换行符,可按需删除 msg2Len equ $ - msg2 ; 修正后的长度计算 name db "Itworked", 0 ; 文件名末尾加0作为结束符,保证系统调用正确识别
编译运行验证
使用你原有的编译命令即可正常运行:
nasm -f elf32 -o makefile.o makefile.asm ld -m elf_i386 -o makefile makefile.o ./makefile
修正后运行不会再出现乱码,文件创建功能也完全正常。
内容的提问来源于stack exchange,提问作者user15124295
相关产品推荐
相关产品推荐

