ARM 64汇编实现SELECT/CASE结构遇运行异常求排查
ARM64汇编实现SELECT/CASE结构的问题修复
你的代码存在几处核心错误,导致无法正确匹配输入并输出对应消息,以下是问题分析和修正方案:
错误点分析
- read系统调用参数缺失:调用
read(系统调用号63)时,未指定输入缓冲区地址(x1)和读取字节数(x2),会导致读取行为异常甚至崩溃。 - 混淆read返回值与输入内容:
read返回的w0是成功读取的字节数,而非输入的数字本身。用户输入的是ASCII字符(比如输入1对应ASCII码0x31),需转换为数值后再比较。 - write系统调用缺少长度参数:调用
write(系统调用号64)时,未指定输出字符串长度(x2),系统无法确定输出字节数,会导致内容混乱。 - stdout编号错误:原代码将stdout的文件描述符误写为
0(实际是stdin的编号),导致提示信息无法输出到屏幕。
修正后的代码
// Declare program entry point .global _start // Messages to be displayed .data prompt: .asciz "Input a number: " // Prompt message prompt_len = . - prompt // 自动计算提示语长度 case1_msg: .asciz "You entered 1\n" case1_len = . - case1_msg case2_msg: .asciz "You entered 2\n" case2_len = . - case2_msg else_msg: .asciz "You entered a value other than 1 and 2\n" else_len = . - else_msg input_buf: .skip 2 // 2字节缓冲区:存储输入的数字字符+换行符 .text _start: // 显示提示语 mov x0, #1 // stdout文件描述符为1 adr x1, prompt mov x2, prompt_len mov x8, #64 // 调用write系统调用 svc #0 // 获取用户输入 mov x0, #0 // stdin文件描述符 adr x1, input_buf // 指向输入缓冲区 mov x2, #2 // 最多读取2字节(数字+换行) mov x8, #63 // 调用read系统调用 svc #0 // 将ASCII字符转换为数值:减去'0'的ASCII码(0x30) ldrb w1, [input_buf] sub w1, w1, #0x30 // 匹配CASE分支 cmp w1, #1 beq case1 cmp w1, #2 beq case2 b else_case case1: // 输出CASE1消息 mov x0, #1 adr x1, case1_msg mov x2, case1_len mov x8, #64 svc #0 b end_select case2: // 输出CASE2消息 mov x0, #1 adr x1, case2_msg mov x2, case2_len mov x8, #64 svc #0 b end_select else_case: // 输出ELSE消息 mov x0, #1 adr x1, else_msg mov x2, else_len mov x8, #64 svc #0 end_select: // 终止程序 mov x0, #0 mov x8, #93 svc #0
关键修改说明
- 添加输入缓冲区:定义
input_buf存储用户输入,长度设为2字节,足够容纳单个数字和换行符。 - 修正read参数:指定缓冲区地址和读取长度,确保正确获取输入内容。
- ASCII转数值:读取缓冲区首字节并减去
'0'的ASCII码,将字符转换为对应整数。 - 修正stdout编号:将write调用的
x0设为1(正确的stdout编号)。 - 自动计算字符串长度:用
. - 标签名自动计算字符串长度,避免手动输入出错。 - 补全write长度参数:每个write调用都指定正确的字符串长度,确保输出内容完整。
内容的提问来源于stack exchange,提问作者dkk
相关产品推荐
相关产品推荐

