如何在MIPS汇编中将十六进制数写入文件?
问题分析与修正代码
你的代码核心问题是用了错误的系统调用:syscall 34是将十六进制数输出到控制台,而非写入文件。要实现写入文件,需要先把整数转换成十六进制字符串,再用文件写入的系统调用完成操作。
修正后的代码
.data filename: .asciiz "output.txt" hex_chars: .asciiz "0123456789ABCDEF" # 十六进制字符集 buffer: .space 10 # 存储转换后的十六进制字符串(含换行和终止符) newline: .asciiz "\n" .text main: li $t0, 36 # 要转换的整数 # 打开文件(写入模式) li $v0, 13 la $a0, filename li $a1, 1 li $a2, 0 syscall move $s0, $v0 # 保存文件描述符到$s0 # 调用十六进制转换函数,结果存在buffer中 move $a0, $t0 la $a1, buffer jal int_to_hex # 写入十六进制字符串到文件 li $v0, 15 move $a0, $s0 la $a1, buffer li $a2, 10 # 写入长度(最多9位十六进制+换行+终止符) syscall # 关闭文件 li $v0, 16 move $a0, $s0 syscall # 退出程序 li $v0, 10 syscall # 整数转十六进制字符串函数 # 参数:$a0 = 要转换的整数,$a1 = 存储结果的缓冲区地址 int_to_hex: addi $sp, $sp, -12 sw $ra, 0($sp) sw $s0, 4($sp) sw $s1, 8($sp) move $s0, $a0 # $s0 = 待转换整数 move $s1, $a1 # $s1 = 缓冲区指针 li $t1, 8 # 最多处理8位十六进制(32位整数) li $t2, 0 # 计数已转换的位数 reverse_loop: beq $t1, $t2, end_reverse andi $t3, $s0, 0xF # 取低4位 la $t4, hex_chars add $t4, $t4, $t3 lb $t4, 0($t4) sb $t4, 0($s1) addi $s1, $s1, 1 srl $s0, $s0, 4 # 右移4位 addi $t2, $t2, 1 j reverse_loop end_reverse: # 移除前导零 la $t0, buffer remove_leading_zeros: lb $t3, 0($t0) beq $t3, '0', skip_zero j copy_non_zero skip_zero: addi $t0, $t0, 1 j remove_leading_zeros copy_non_zero: lb $t3, 0($t0) beq $t3, 0, add_newline sb $t3, 0($s1) addi $s1, $s1, 1 addi $t0, $t0, 1 j copy_non_zero add_newline: la $t4, newline lb $t4, 0($t4) sb $t4, 0($s1) addi $s1, $s1, 1 sb $zero, 0($s1) # 添加字符串终止符 lw $ra, 0($sp) lw $s0, 4($sp) lw $s1, 8($sp) addi $sp, $sp, 12 jr $ra
关键修正点
- 新增
int_to_hex函数:将32位整数转换为十六进制字符串,自动处理前导零并添加换行符 - 使用
syscall 15(文件写入)替代错误的syscall 34,该调用需要传入文件描述符、缓冲区地址和写入长度 - 将文件描述符保存到
s0寄存器,避免后续系统调用覆盖该关键值
内容的提问来源于stack exchange,提问作者MIPS
相关产品推荐
相关产品推荐

