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

Venus模拟器中调用free系统调用的RISC-V代码无法终止问题

Venus模拟器中调用free后代码无法终止的问题分析与解决

我从大型代码中隔离出以下简易RISC-V代码,其中malloc和free的实现取自伯克利CS61C 2020秋季项目2:

.globl main

# we have a0, a1, a2
main:
    addi sp, sp, -36
    sw s0, 0(sp)
    sw s1, 4(sp)
    sw s2, 8(sp)
    sw s3, 12(sp)
    sw s4, 16(sp)
    sw s5, 20(sp)
    sw s6, 24(sp)
    sw s7, 28(sp)
    sw s8, 32(sp)

    addi sp, sp, -24
    sw ra, 8(sp)
    sw a0, 12(sp)
    sw a1, 16(sp)
    sw a2, 20(sp)

    li a0, 4
    jal ra, malloc
    mv s0, a0

    lw ra, 8(sp)
    lw a0, 12(sp)
    lw a1, 16(sp)
    lw a2, 20(sp)
    addi sp, sp, 24

    # cleaning m0
    addi sp, sp, -16
    sw a0, 0(sp)
    sw a1, 4(sp)
    sw a2, 8(sp)    
    sw ra, 12(sp)
    
    mv a0, s0
    jal ra, free

    lw a0, 0(sp)
    lw a1, 4(sp)
    lw a2, 8(sp)
    lw ra, 12(sp)
    addi sp, sp, 16

    #Epilog
    lw s0, 0(sp)
    lw s1, 4(sp)
    lw s2, 8(sp)
    lw s3, 12(sp)
    lw s4, 16(sp)
    lw s5, 20(sp)
    lw s6, 24(sp)
    lw s7, 28(sp)
    lw s8, 32(sp)
    addi sp, sp, 36
    ret
    
free:
    mv a1 a0
    li a0 0x3CC
    addi a6 x0 4
    ecall
    ret


malloc:
    mv a1 a0
    li a0 0x3CC
    addi a6 x0 1
    ecall
    ret

这段代码在Venus模拟器中运行时无法终止,但注释掉调用free的相关代码后即可正常运行,寻求问题原因及解决办法。


问题原因

Venus模拟器的系统调用规范与你使用的CS61C项目中的实现不匹配:

  • 对于free系统调用(a6=4),Venus要求待释放的内存指针直接放在a0寄存器中作为参数;
  • 当前的free实现错误地将a0(指针)移到a1,然后把a0设置为0x3CC,导致系统调用接收到错误的参数,触发未定义行为,最终使程序无法正常终止。

而malloc的实现能正常工作,是因为Venus的malloc系统调用(a6=1)确实要求分配大小放在a1,a0设为0x3CC,这部分符合规范。

解决办法

修改free函数的实现,直接使用a0传递待释放的指针,无需将其移到a1:

free:
    li a0 0x3CC  # 保留系统调用标识
    addi a6 x0 4 # free对应的系统调用编号
    ecall
    ret

修改后,调用free时传递的指针会正确被系统调用识别,程序就能正常执行并终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 22:13:15