AArch64设备汇编系统调用无法打开磁盘文件,求技术支持
AArch64汇编open系统调用返回负数句柄问题
问题背景
我是业余程序员,正在学习Android Termux环境下的AArch64汇编开发,用GNU as汇编器和ld链接器写程序,尝试打开同路径下已存在的test.txt文件,但open系统调用返回负数句柄(异常),不确定svc调用的寄存器参数是否正确。
编译执行步骤:
- 用nano编写源码
rec1.s - 编译:
as -o rec1.o rec1.s - 链接:
ld -s -o rec1 rec1.o - 执行:
./rec1
原代码:
.data title: .ascii "Test disk open for aarch64\n" filename: .ascii "test.txt" // existing short text file path: .ascii "../gas/" // path where the file resides err0: .ascii "Zero error\n" errneg: .ascii "Negative error\n" .bss buffer: .space 100 .text .global _start _start: // title of program mov x0,#1 ldr x1,=title mov x2,#17 mov w8,#64 svc 0 // open disk file ldr x0,=path ldr x1,=filename mov x2,#0 // flag ? mov x3,#0666 // mode ? mov w8,#56 svc 0 // x0 should have handle at this stage // check for valid handle cmp x0,#0 // branch if handle is zero beq error0 blt errorneg mov x19,x0 // store handle in x19 // read disk file mov x0,x19 ldr x1,=buffer mov x2,#10 mov w8,#63 svc 0 // display buffer mov x0,#1 ldr x1,=buffer mov x2,#10 mov w8,#64 svc 0 // close the file mov x0,19 mov w8,#57 svc 0 b exit exit: mov x0,#0 mov w8,#93 svc 0 error0: mov x0,#1 ldr x1,=err0 mov x2,#11 mov w8,#64 svc 0 b exit errorneg: mov x0,#1 ldr x1,=errneg mov x2,#15 mov w8,#64 svc 0 b exit
错误原因分析
- open参数传递错误:AArch64的
open系统调用(编号56)要求第一个参数是完整的文件路径字符串,你把路径和文件名拆成两个寄存器传递,系统无法识别。 - 字符串无终止符:
.ascii定义的字符串不会自动添加\0,系统处理时会读到内存垃圾数据,导致路径识别失败。 - close调用参数错误:关闭文件时你直接传了数值19到x0,而不是之前保存的文件句柄x19。
- 标题长度计算错误:原代码中标题字符串长度写的17,实际是27,会导致打印内容异常。
修复后的代码
.data title: .ascii "Test disk open for aarch64\n" filename: .asciz "../gas/test.txt" // 拼接完整路径,.asciz自动加\0 err0: .asciz "Zero error\n" errneg: .asciz "Negative error\n" .bss buffer: .space 100 .text .global _start _start: // 打印程序标题 mov x0,#1 ldr x1,=title mov x2,#27 // 修正标题字符串实际长度 mov w8,#64 // write系统调用编号 svc 0 // 打开文件:完整路径传入x0 ldr x0,=filename mov x2,#0 // O_RDONLY 只读打开 mov w8,#56 // open系统调用编号 svc 0 // 检查句柄有效性 cmp x0,#0 beq error0 blt errorneg mov x19,x0 // 保存文件句柄到x19 // 读取文件内容 mov x0,x19 ldr x1,=buffer mov x2,#10 // 读取10字节 mov w8,#63 // read系统调用编号 svc 0 // 打印读取到的内容 mov x0,#1 ldr x1,=buffer mov x2,#10 mov w8,#64 svc 0 // 关闭文件:使用保存的句柄x19 mov x0,x19 mov w8,#57 // close系统调用编号 svc 0 b exit exit: mov x0,#0 mov w8,#93 // exit系统调用编号 svc 0 error0: mov x0,#1 ldr x1,=err0 mov x2,#11 mov w8,#64 svc 0 b exit errorneg: mov x0,#1 ldr x1,=errneg mov x2,#15 mov w8,#64 svc 0 b exit
修复说明
- 用
.asciz替代.ascii,自动给字符串添加终止符\0 - 将路径和文件名拼接成完整路径
../gas/test.txt,直接传入x0作为open的第一个参数 - 修正close调用的参数,使用之前保存的x19句柄
- 修正标题字符串的长度,确保打印内容完整
内容的提问来源于stack exchange,提问作者Chris Leslie
相关产品推荐
相关产品推荐

