MacOS简易汇编程序无法捕获用户输入,求解决缓冲区错误
MacOS汇编输入缓冲区错误修复方案
核心问题分析
你的代码存在两个关键错误,直接导致缓冲区/系统调用异常:
- 错误的Syscall编号:MacOS的系统调用编号必须加上
0x2000000前缀,你使用的是Linux的Syscall编号(如write=4、read=3),这会触发错误的内核服务,进而引发内存访问异常。 - Prompt长度硬编码错误:
.asciz会自动添加null终止符,你指定的长度16会把这个null字节也输出到终端,虽不致命,但属于不规范写法。
另外,若后续需要将输入作为字符串处理,name_buffer仅分配8字节会缺少存储null终止符的空间,容易引发字符串越界问题。
修复后的代码
.global _start // Write the prompt to stdout _start: mov x0, 1 // File descriptor for stdout ldr x1, =prompt // Address of the prompt mov x2, prompt_len // 自动计算Prompt长度,避免硬编码错误 mov x16, 0x2000004 // MacOS syscall number for write svc 0 // Call write syscall // Read user input mov x0, 0 // File descriptor for stdin ldr x1, =name_buffer // Buffer to store input mov x2, 8 // Maximum number of characters to read mov x16, 0x2000003 // MacOS syscall number for read svc 0 // Call read syscall // 给输入添加null终止符,确保是合法C风格字符串 strb wzr, [x1, x0] // x0是read返回的实际读取字节数,在缓冲区末尾写0 // Exit program mov x16, 0x2000001 // MacOS syscall number for exit mov x0, 0 // Exit code 0 (success) svc 0 prompt: .asciz "Enter your name: " prompt_len = . - prompt - 1 // 减去1,排除.asciz自动添加的null字节 name_buffer: .ds 9 // 分配9字节:8个输入字符 + 1个null终止符
关键修复点说明
- Syscall编号修正:所有系统调用添加
0x2000000前缀,这是MacOS内核区分系统调用与其他陷阱的强制要求。 - 自动计算Prompt长度:用
prompt_len = . - prompt - 1自动计算可见字符长度,避免手动数错字符数。 - 缓冲区扩容:将
name_buffer改为9字节,预留空间存储null终止符,防止后续字符串操作时出现越界访问。 - 添加null终止符:利用
read返回的实际读取字节数(存在x0中),在缓冲区末尾写入null字节,确保输入是合法字符串。
内容的提问来源于stack exchange,提问作者FJR
相关产品推荐
相关产品推荐

