Apple M1芯片ARM64汇编程序文件读写异常问题排查
问题分析与解决
核心问题
你的程序在调用open系统调用后,没有立即检查返回值是否为错误状态,直接将返回值存入x10并开始读取。当/test.txt不存在时,open会返回负数(错误码,通常为-2表示文件不存在),但代码直到read之后才做错误判断,导致程序尝试从无效的文件描述符读取数据。
在macOS ARM64的系统调用逻辑中,传入无效文件描述符给read时,系统会将其当作标准输入(stdin,文件描述符0)处理,这就是程序等待输入并回显的原因——它实际在读取键盘输入后输出到stdout。
修复步骤
需要在open调用后立刻检查返回值,若为负数则直接跳转到错误处理逻辑:
修改后的完整代码
.section __DATA,__data .p2align 2 buffer: .zero 4096 .section __TEXT,__text .global _main .build_version macos, 13, 0 .p2align 2 _main: // x9: buf ptr // x10: file descriptor storage // x11: file size in bytes //init ptr to buf adrp x9, buffer@PAGE add x9, x9, buffer@PAGEOFF // open file adr x0, file_path mov x1, #0 // O_RDONLY mov x2, #0444 // 八进制权限,符合UNIX权限规范 mov x16, #5 // open syscall number svc 0 // 新增:检查open是否失败,返回值<0则跳转到错误处理 cmp x0, #0 blt error // copy valid file descriptor to x10 mov x10, x0 .p2align 2 stream_buffer: // make syscall read, file descriptor is in x10 mov x0, x10 mov x1, x9 mov x2, #4096 mov x16, #3 // read syscall number svc 0 // if x0 == 0, exit, no bytes were read cmp x0, #0 beq exit blt error // store number of bytes read mov x11, x0 // write to stdout from buffer mov x0, #1 // stdout fd mov x1, x9 mov x2, x11 mov x16, #4 // write syscall number svc 0 b stream_buffer .p2align 2 exit: // exit with status code 0 mov x0, #0 mov x16, #1 // exit syscall number svc 0 .p2align 2 error: mov x0, #1 adr x1, file_not_found_error_string mov x2, #20 mov x16, #4 svc 0 b exit .p2align 2 file_path: .asciz "/test.txt" .p2align 2 file_not_found_error_string: .asciz "file was not found.\n"
额外说明
- 权限值
#0444用八进制表示更符合UNIX权限的规范,虽然十进制444数值相同,但八进制是权限设置的标准写法。 - macOS ARM64系统调用失败时会返回负数错误码,通过
cmp x0, #0+blt error可以捕获所有open失败的场景。
内容的提问来源于stack exchange,提问作者user14924651
相关产品推荐
相关产品推荐

