You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

汇编代码实现数组扩容时触发Segmentation fault问题求助

汇编数组扩容段错误问题排查

输入5个元素后触发Segmentation fault,代码意图是数组满员后自动翻倍扩容、复制旧元素,支持继续输入直到终止,最后输出统计数据。以下是代码中的核心错误及修复方案:

核心错误点及修复

1. createNewArray函数calloc参数完全错误

calloc规范为void *calloc(size_t nmemb, size_t size),即第一个参数是元素个数,第二个是单个元素大小。原代码错误地将旧数组指针传给第一个参数,还误用了rdx寄存器(calloc仅需两个参数)。

修复步骤:

  • 在.bss段新增变量跟踪当前数组容量:
    segment .bss
       arrayPtr:       resq 1
       currentCapacity: resq 1  ; 记录当前数组可容纳的元素数
       intInput:       resd 1
    
  • 在asm_main初始化数组时同步设置初始容量:
    mov   rdi, ARRAY_SIZE
    mov   rsi, ELEMENT_SIZE
    call  calloc
    mov   [arrayPtr], rax
    mov   [currentCapacity], ARRAY_SIZE  ; 初始容量设为5
    
  • 修改createNewArray的calloc调用及复制逻辑:
    createNewArray:
       mov   rsi, [currentCapacity]
       add   rsi, rsi            ; 翻倍容量
       mov   rdi, rsi            ; 新数组元素个数
       mov   rsi, ELEMENT_SIZE   ; 单个元素大小
       call  calloc
       test  rax, rax            ; 检查内存分配是否成功
       jz    error_handle        ; 可添加内存分配失败的处理逻辑
    
       ; 复制旧数组到新数组
       mov   rsi, [arrayPtr]     ; 源地址:旧数组
       mov   rdi, rax            ; 目标地址:新数组
       mov   rcx, [currentCapacity]  ; 复制元素个数等于当前容量
       cld
       rep   movsd
    
       ; 更新数组指针和容量
       mov   [arrayPtr], rax
       mov   [currentCapacity], rsi
       ret
    

2. rep movsd未正确设置源/目标地址

原代码调用rep movsd前未初始化rsi(源地址)和rdi(目标地址),使用寄存器垃圾值读写内存直接触发段错误。上述修复后的createNewArray已正确设置这两个寄存器。

3. 扩容触发条件错误

原代码用固定初始值ARRAY_SIZE判断是否扩容,忽略了扩容后数组容量已翻倍的事实,应该判断元素个数是否等于当前数组容量。

修复:

cmp   r15, [currentCapacity]  ; 替换原有的cmp r15, ARRAY_SIZE
jl    arrayNotFull
call  createNewArray
mov   rdi, [arrayPtr]

4. inputLoop使用loop指令逻辑错误

loop指令依赖rcx自动减1判断循环结束,但rcx被用来存储初始数组大小,扩容后修改rcx会导致循环次数混乱。输入循环应为无限循环直到遇到EOF,无需依赖rcx计数。

修复:

inputLoop:
   push  rcx
   push  rdi
   ; ... 输入提示、scanf逻辑 ...
   pop   rdi
   stosd
   pop   rcx
   jmp   inputLoop  ; 替换loop inputLoop,改为无条件跳转

5. sumLoop中r8未初始化

原代码用r8存储累加和,但未将其初始化为0,第一次累加会使用垃圾值导致计算错误。

修复:

mov   r8, 0           ; 初始化累加和为0
mov   rax, 0
mov   rsi, [arrayPtr]
mov   rcx, r15
cld
sumLoop_body:
   lodsd
   add   r8, rax          ; 累加当前元素到r8
   loop  sumLoop_body

6. 最值查找中rsi赋值错误

在min/max查找逻辑中,mov rsi, [rax]将数组元素值赋值给rsi,但注释说明rsi应存储最值的地址,导致后续操作无效。

修复:

; 最小值查找部分
mov   rax, [arrayPtr]
mov   ebx, [rax]
mov   rcx, r15
dec   rcx
mov   rsi, rax  ; 替换mov rsi, [rax],存储地址而非元素值
loopStart:
   ; ... 后续逻辑 ...

; 最大值查找部分同理
mov   rax, [arrayPtr]
mov   ebx, [rax]
mov   rcx, r15
dec   rcx
mov   rsi, rax  ; 替换mov rsi, [rax]

内容的提问来源于stack exchange,提问作者SlicedAero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 14:27:03