AArch64汇编代码无法读取标准输入(stdin)求助
环境信息
| 条目 | 信息 |
|---|---|
| 计算机 | MacBook 2022 M2 13英寸 24GB |
| 操作系统 | MacOS 15.1 Beta 2405055e |
| 编译命令 | as hello.s -g -o hello.o && ld -o hello.exec hello.o -lSystem -syslibroot $(xcrun -sdk macosx --show-sdk-path) -e _start -arch arm64 |
问题描述
我是汇编完全新手,正在学习Mach-O系统的AArch64汇编。以下是我的代码:
.global _start .align 4 _start: mov X0, #0 adr X1, buffer mov X2, #128 mov X16, 3 svc #0x80 mov X0, #1 adr X1, buffer mov X2, #128 mov X16, 4 svc #0x80 mov X0, #0 mov X16, 1 svc #0x80 buffer: .skip 128
代码无法正常工作,shell操作过程如下(test是我输入的内容):
(base) ----------------------------------------------------------------------------------- ╭─ makabaka1880@Makabakas-MacBookPro.local ╰─ ./helloworld.exec [17:23] 127 ~/ASM test (base) ----------------------------------------------------------------------------------- ╭─ makabaka1880@Makabakas-MacBookPro.local ╰─ est [17:26] 0 ~/ASM zsh: command not found: est
通过lldb调试发现,执行mov X2, #128后,X1指向的buffer内存区域为空:
(lldb) memory read -s1 -fu -c128 0x00000001003b7f24 --force 0x1003b7f24: 0 0x1003b7f25: 0 0x1003b7f26: 0 0x1003b7f27: 0 0x1003b7f28: 0 0x1003b7f29: 0 0x1003b7f2a: 0 0x1003b7f2b: 0 0x1003b7f2c: 0 0x1003b7f2d: 0 ...
问题原因
Syscall编号错误:你使用的
3(read)、4(write)、1(exit)是x86_64架构的syscall编号,MacOS AArch64架构下的syscall需要加上0x2000000前缀,正确编号为:- read:
0x2000003 - write:
0x2000004 - exit:
0x2000001
错误的编号会导致内核无法识别请求,读取操作直接失败。
- read:
输入未被程序捕获:由于syscall调用失败,程序没有读取到输入内容,输入的
test\n直接被shell接收,shell解析时出现了est命令找不到的错误。编译命令笔误:原命令中多写了一个
as,会导致编译失败。
修正方案
修正后的汇编代码
.global _start .align 4 _start: // 读取标准输入到buffer,最多128字节 mov X0, #0 // 文件描述符:标准输入 adr X1, buffer // 缓冲区地址 mov X2, #128 // 最大读取字节数 mov X16, #0x2000003 // AArch64 syscall: read svc #0x80 // 写入标准输出,使用read返回的实际字节数 mov X2, X0 // 将read返回的实际读取字节数传给write mov X0, #1 // 文件描述符:标准输出 adr X1, buffer // 缓冲区地址 mov X16, #0x2000004 // AArch64 syscall: write svc #0x80 // 退出程序,返回码0 mov X0, #0 // 退出状态码 mov X16, #0x2000001 // AArch64 syscall: exit svc #0x80 buffer: .skip 128
修正后的编译命令
as hello.s -g -o hello.o && ld -o hello.exec hello.o -lSystem -syslibroot $(xcrun -sdk macosx --show-sdk-path) -e _start -arch arm64
额外说明
- MacOS AArch64的syscall必须加上
0x2000000前缀,这是系统规定的偏移量,用于区分不同类型的系统调用。 read调用完成后,X0寄存器会返回实际读取的字节数(包括输入的换行符),将其传给write的X2参数,可以避免输出多余的空字节。- 若仍有问题,可在lldb中查看syscall返回值(X0),负数表示调用失败,对应MacOS的错误码。
内容的提问来源于stack exchange,提问作者Mmakabaka1880
相关产品推荐
相关产品推荐

