为何NASM无法写入Unicode格式的正斜杠(U+002F)?
NASM汇编中写入正斜杠(U+002F)输出为空的问题
我尝试运行以下NASM汇编代码,意图创建文件并写入正斜杠字符,但写入后输出为空。其他Unicode字符(如逗号\u002c、@符号\u0040)均可正常工作。
原代码:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point ;create the file mov eax, 8 mov ebx, file_name mov ecx, 0777 ;read, write and execute by all int 0x80 ;call kernel mov [fd_out], eax ; write into the file mov edx, len ;number of bytes mov ecx, msg ;message to write mov ebx, [fd_out] ;file descriptor mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel ; close the file mov eax, 6 mov ebx, [fd_out] ; write the message indicating end of file write mov eax, 4 mov ebx, 1 mov ecx, msg_done mov edx, len_done int 0x80 ;open the file for reading mov eax, 5 mov ebx, file_name mov ecx, 0 ;for read only access mov edx, 0777 ;read, write and execute by all int 0x80 mov [fd_in], eax ; read from file mov eax, 3 mov ebx, [fd_in] mov ecx, info mov edx, len int 0x80 ; close the file mov eax, 6 mov ebx, [fd_in] int 0x80 ; print the info mov eax, 4 mov ebx, 1 mov ecx, info mov edx, len int 0x80 mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data file_name db 'myfile.txt' msg db `\u002f` len equ $-msg msg_done db 'Written to file', 0xa len_done equ $-msg_done section .bss fd_out resb 1 fd_in resb 1 info resb 26
我尝试过多种写法来表示正斜杠,包括:
msg db 0x2f,0xa msg db 0x2f msg db 0x2f,0 msg db 2fh
但均无法解决问题,其他字符则能正常写入并输出。
问题原因
核心问题是文件关闭操作未完成:原代码中创建文件并写入后,只设置了eax=6(sys_close的系统调用号)和ebx=[fd_out],但没有调用int 0x80触发内核执行关闭操作。这会导致文件缓冲区的内容没有被刷新到磁盘,写入的正斜杠字符停留在内存中,后续读取自然拿不到数据。其他字符可能因为程序退出时的隐式缓冲区刷新(不可靠行为)被写入,才造成“只有正斜杠失效”的假象。
另外,当使用msg db 0x2f时,len equ $-msg的计算是正确的(值为1),但如果文件没正确关闭,这个字节永远不会被持久化。
解决方案
补全文件关闭的系统调用,确保写入的数据被刷入磁盘:
修改后的完整代码:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point ;create the file mov eax, 8 mov ebx, file_name mov ecx, 0777 ;read, write and execute by all int 0x80 ;call kernel mov [fd_out], eax ; write into the file mov edx, len ;number of bytes mov ecx, msg ;message to write mov ebx, [fd_out] ;file descriptor mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel ; close the file mov eax, 6 mov ebx, [fd_out] int 0x80 ; 新增这一行,触发内核关闭文件,刷新缓冲区 ; write the message indicating end of file write mov eax, 4 mov ebx, 1 mov ecx, msg_done mov edx, len_done int 0x80 ;open the file for reading mov eax, 5 mov ebx, file_name mov ecx, 0 ;for read only access mov edx, 0777 ;read, write and execute by all int 0x80 mov [fd_in], eax ; read from file mov eax, 3 mov ebx, [fd_in] mov ecx, info mov edx, len int 0x80 ; close the file mov eax, 6 mov ebx, [fd_in] int 0x80 ; print the info mov eax, 4 mov ebx, 1 mov ecx, info mov edx, len int 0x80 mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data file_name db 'myfile.txt' msg db 0x2f ; 直接用十六进制表示正斜杠,简洁可靠 len equ $-msg msg_done db 'Written to file', 0xa len_done equ $-msg_done section .bss fd_out resb 1 fd_in resb 1 info resb 26
验证步骤
- 编译链接:
nasm -f elf32 test.asm -o test.o; ld -m elf_i386 test.o -o test - 运行程序:
./test - 查看输出:会打印
Written to file和正斜杠/ - 检查文件:
cat myfile.txt会显示/
内容的提问来源于stack exchange,提问作者user3506446
相关产品推荐
相关产品推荐

