NASM中stat系统调用返回st_size为0的原因排查求助
解决NASM中stat系统调用返回st_size为0的问题
我看到你在macOS环境下用NASM调用stat系统调用获取文件大小时,遇到了st_size始终返回0的问题,咱们一步步来排查和解决:
1. 先确认系统调用是否执行成功
你当前的代码直接push了syscall的返回值,但没有判断stat调用是否成功。如果stat调用失败(比如目标文件不存在、权限不足),rax会返回-1,此时stat缓冲区里的内容是未定义的,刚好显示为0也只是巧合。建议先添加错误检查逻辑:
syscall cmp rax, 0 jne stat_failed ; 跳转到错误处理分支
2. 核心问题:st_size的偏移值错误
你代码里写的[rsi + 96]是错误的——macOS 64位环境下,__DARWIN_STRUCT_STAT64结构体中st_size的正确偏移是80字节。你可以通过以下命令验证结构体成员偏移:
clang -x c -include sys/stat.h -E - | grep -A25 "struct stat64"
错误的偏移导致你读取的是结构体里的其他无关字段,刚好值为0,这才是问题的根源。
修正后的完整代码
把偏移值改成80,同时补充错误处理,修正后的代码如下:
global _main extern _printf extern _perror section .bss stat resb 144 ; __DARWIN_STRUCT_STAT64的大小确实是144字节,这个没问题 section .text filename: db "test.asm", 0 ; 确保该文件在程序运行的当前目录下 format: db "%lld", 10, 0 err_msg: db "stat failed", 0 _main: mov rax, 0x20000bc ; Darwin平台的stat系统调用号,这个是正确的 mov rdi, filename mov rsi, stat syscall cmp rax, 0 jne stat_error ; 调用失败则进入错误处理 ; 调用成功,读取并打印st_size mov rdi, format mov rsi, [stat + 80] ; 使用正确的st_size偏移 call _printf jmp exit_program stat_error: mov rdi, err_msg call _perror ; 打印错误原因 exit_program: ret
额外注意事项
- 编译链接时记得链接系统库:
nasm -f macho64 yourfile.asm && ld -lSystem -o yourfile yourfile.o - 运行程序时,要确保
test.asm存在于当前工作目录,否则stat会直接失败。
内容的提问来源于stack exchange,提问作者a_random_programmer
相关产品推荐
相关产品推荐

