RISC-V汇编实现.GRAY图像读写功能异常求助
问题分析与修复方案
你的RISC-V汇编代码存在多处寄存器操作、系统调用参数错误,导致图像读取/写入异常。以下是具体问题和修复后的代码:
核心问题列表
- 寄存器保存/恢复错误:使用
sb(单字节存储)保存32位寄存器s0/s1,导致寄存器值被截断;恢复时错误加载到a0/a1而非原寄存器。 - 文件描述符关闭错误:
writeGray中关闭的是图像缓冲区地址而非打开的文件描述符,导致文件未正确刷新。 - 输出文件路径错误:
main中调用writeGray时传入输入文件路径,覆盖了原输入文件而非写入目标输出文件。 - 可选缺失:部分环境下打开写入文件时需要指定文件权限(如
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
验证步骤
- 编译并运行修复后的代码。
- 使用ImageMagick转换输出文件:
convert cat_mean.gray -size 400x599 gray: cat_mean.png。 - 检查生成的PNG图像是否与原输入图像一致。
内容的提问来源于stack exchange,提问作者ramwen0
相关产品推荐
相关产品推荐

