如何修复ARM汇编代码中的段错误?插入排序实现故障排查
问题根源及修复方案
核心问题:栈空间严重不足
你需要存储50个64位整数的数组,共需50×8=400字节空间,但当前alloc的计算仅分配了80字节(原计算-(16+20+16+16)&-16),数组写入时直接越界覆盖栈上的关键数据(如返回地址lr、帧指针fp),这是触发段错误的主要原因。
修复:重新计算alloc,包含数组空间和其他局部变量:
alloc = -(400 + 32) & -16 @ 400字节数组 + 32字节局部变量,按16字节对齐 dealloc = -alloc
数组地址与索引计算错误
- 数组起始地址未保留:原代码在
loop1中每次循环都重新计算v,循环结束后v指向数组最后一个元素而非起始地址,导致排序阶段地址偏移完全错误。 - offset未初始化:
lsl offset, offset, 3执行时offset是垃圾值,第一次循环就会导致数组越界访问。
修复:
- 初始化阶段直接保留数组起始地址:
main: stp fp, lr, [sp, alloc]! mov fp, sp mov v, fp add v, v, 32 @ 数组从fp+32位置开始,避开其他局部变量 - 修正
loop1的索引计算逻辑:loop1: bl rand and x0, x0, #255 ldr w11, [fp, -8] @ 获取当前索引i mov offset, w11 lsl offset, offset, 3 @ 转换为字节偏移(8字节/元素) str x0, [v, offset] @ 写入数组对应位置 add w11, w11, 1 str w11, [fp, -8]
排序逻辑多处错误
- 无效赋值覆盖数据:
sxtw temp64, temp中temp未初始化,直接覆盖了从数组取出的待插入元素值,导致比较逻辑使用垃圾数据。 - 元素后移逻辑失效:
ldr c, [v, j, SXTW 3]后直接str c, [v, j, SXTW 3]等于无操作,未实现插入排序的元素后移逻辑。
修复:重写排序部分代码:
mov i, #1 sort_outer_1: cmp i, #50 b.gt print ldr temp64, [v, i, SXTW 3] @ 取出当前待插入元素 mov j, i sort_inner: cmp j, #0 ble sort_outer_2 sub j, j, #1 @ 移动到前一个元素索引 ldr c, [v, j, SXTW 3] @ 取出前一个元素 cmp temp64, c b.ge sort_outer_2 @ 当前元素无需继续移动,退出内层循环 str c, [v, j, #8] @ 前一个元素后移 b sort_inner sort_outer_2: str temp64, [v, j, SXTW 3] @ 插入元素到正确位置 add i, i, 1 b sort_outer_1
栈操作混乱
原代码在stp fp, lr, [sp, alloc]!完成栈分配后,又手动执行add sp, sp, -8 & -16调整栈指针,破坏了栈帧结构,导致局部变量偏移计算全部错误。
修复:删除手动调整sp的代码,所有局部变量通过fp的合法偏移访问。
排序后数组打印逻辑缺失
原代码print标签下仅打印了标题和一次元素,未循环遍历所有数组元素。
修复:添加打印循环:
print: ldr x0, =fmt2 bl printf mov wzr, w9 str wzr, [fp, -8] print_loop: ldr i, [fp, -8] cmp i, #50 b.ge end_print ldr x0, =fmt3 mov w1, i ldr x2, [v, i, SXTW 3] bl printf add i, i, 1 str i, [fp, -8] b print_loop end_print:
内容的提问来源于stack exchange,提问作者Jarvis
相关产品推荐
相关产品推荐

