ARMv7树莓派3B+读取输入存数组程序运行报Illegal instruction错误排查
树莓派ARMv7汇编Illegal instruction错误原因定位
- 字符串和常量位置错误
你的代码开头没有声明段属性,
.LC0到.LC3的字符串默认被放在了.text代码段,虽然只读访问没问题,但你后续定义的.L10地址表被放在了.data段,代码段中用ldr r0, .L10这种PC相对寻址方式访问不同段的地址,汇编阶段无法计算正确偏移,会导致读取到非法的函数/字符串地址,跳转到错误位置执行触发非法指令。
- 栈空间溢出
你申请的栈空间只有48字节(
sub sp, sp, #48),但存储用户输入下标的位置是fp-52,已经超出了申请的栈范围,写入时会破坏栈上存储的lr返回地址、fp栈帧指针,后续返回或寻址时跳转到非法地址执行。
- 外部符号未声明
你只声明了
printf为外部符号,调用的__isoc99_scanf没有加.extern声明,部分版本的glibc甚至没有导出__isoc99_scanf符号,直接调用scanf即可。
- 数组地址计算逻辑错误
你在读取数组对应下标的值时,地址计算逻辑混乱,很容易读取到非法地址,跳转或访问错误触发异常。
核心修复建议
- 将
.LC0到.LC3的字符串放到.section .rodata只读数据段,加载字符串地址直接用ldr r0, =.LC0伪指令,不需要自己维护.L10地址表 - 调整栈空间大小,至少预留足够存储循环变量、10个int数组、下标变量的空间
- 补充
scanf的外部声明,直接调用scanf而非__isoc99_scanf - 简化数组寻址逻辑,数组基址可以存在寄存器中避免计算错误
内容的提问来源于stack exchange,提问作者Leo lee
相关产品推荐
相关产品推荐

