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

RISC-V汇编实现.GRAY图像读写功能异常求助

问题分析与修复方案

你的RISC-V汇编代码存在多处寄存器操作、系统调用参数错误,导致图像读取/写入异常。以下是具体问题和修复后的代码:


核心问题列表

  1. 寄存器保存/恢复错误:使用sb(单字节存储)保存32位寄存器s0/s1,导致寄存器值被截断;恢复时错误加载到a0/a1而非原寄存器。
  2. 文件描述符关闭错误:writeGray中关闭的是图像缓冲区地址而非打开的文件描述符,导致文件未正确刷新。
  3. 输出文件路径错误:main中调用writeGray时传入输入文件路径,覆盖了原输入文件而非写入目标输出文件。
  4. 可选缺失:部分环境下打开写入文件时需要指定文件权限(如0644)。

修复后的完整代码

.data 段(无修改)

.data
input: .asciz "cat_noisy.gray"
output_mean: .asciz "cat_mean.gray"
output_median: .asciz "cat_median.gray"
error: .asciz "erro a ler ficheiro"
status_read: .asciz "image read"
status_write: .asciz "image written"
image: .space 239600 # (599 * 400)
.text
.global main

readGray 函数修复

readGray: 
    # 保存寄存器到栈(32位寄存器用sw而非sb)
    addi sp, sp, -8
    sw s0, 0(sp)
    sw s1, 4(sp)
    
    # 打开文件
    mv s0, a1          # 保存图像缓冲区地址
    li a7, 1024        # 系统调用:打开文件
    li a1, 0           # 标志:只读模式
    ecall              # 执行打开,文件描述符返回至a0
    mv s1, a0          # 保存文件描述符
    
    beqz a0, readGray_error # 打开失败跳转错误处理
    
    # 读取文件
    li a7, 63          # 系统调用:读取文件
    mv a0, s1          # 文件描述符
    mv a1, s0          # 缓冲区地址
    li a2, 239600      # 读取字节数
    ecall              # 执行读取
    
    # 可选:检查读取字节数是否符合预期
    bne a0, a2, readGray_error

readGray_done:
    # 关闭文件
    li a7, 57          # 系统调用:关闭文件
    mv a0, s1          # 传入正确的文件描述符
    ecall 
    
    # 恢复寄存器并清理栈
    lw s0, 0(sp)
    lw s1, 4(sp)
    addi sp, sp, 8 
    
    # 打印成功信息
    la a0, status_read 
    li a7, 4 
    ecall 
    ret 
    
readGray_error:
    la a0, error
    li a7, 4
    ecall 
    j readGray_done

writeGray 函数修复

writeGray: 
    # 保存寄存器到栈
    addi sp, sp, -8 
    sw s0, 0(sp) 
    sw s1, 4(sp) 
    
    # 打开文件(写入模式)
    mv s0, a1          # 保存图像缓冲区地址
    li a7, 1024        # 系统调用:打开文件
    li a1, 1           # 标志:写入模式
    li a2, 0644        # 文件权限:所有者读写,其他只读(部分环境需要)
    ecall              # 执行打开,文件描述符返回至a0
    mv s1, a0          # 保存文件描述符
    
    beqz a0, writeGray_error # 打开失败跳转错误处理
    
    # 写入文件
    li a7, 64          # 系统调用:写入文件
    mv a0, s1          # 文件描述符
    mv a1, s0          # 缓冲区地址
    li a2, 239600      # 写入字节数
    ecall              # 执行写入
    
    # 可选:检查写入字节数是否符合预期
    bne a0, a2, writeGray_error

writeGray_done:
    # 关闭文件(传入正确的文件描述符)
    li a7, 57 
    mv a0, s1 
    ecall
    
    # 恢复寄存器并清理栈
    lw s0, 0(sp)
    lw s1, 4(sp)
    addi sp, sp, 8 
    
    # 打印成功信息
    la a0, status_write 
    li a7, 4
    ecall 
    ret 
    
writeGray_error: 
    la a0, error 
    li a7, 4 
    ecall 
    j writeGray_done 

main 函数修复

main:
    # 读取图像
    la a0, input
    la a1, image
    jal readGray 
    
    # 写入图像(使用正确的输出文件路径)
    la a0, output_mean
    la a1, image 
    jal writeGray
    
    # 退出程序
    li a7, 10 
    ecall 

验证步骤

  1. 编译并运行修复后的代码。
  2. 使用ImageMagick转换输出文件:convert cat_mean.gray -size 400x599 gray: cat_mean.png。
  3. 检查生成的PNG图像是否与原输入图像一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:55:55