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

如何确保MIPS从数组输出数字'4'而非ASCII对应的EOT字符

MIPS汇编字符映射输出问题解决

问题概述

我编写了一段MIPS汇编代码,用于读取用户输入并通过键值数组转换为目标字符串,目前遇到两个问题:

  • 数组中的映射值是2、3、4这类整数,但MIPS会将其当作ASCII码处理(比如数字4会被识别为EOT控制字符),需要实现输入$时输出实际数字4的效果。
  • 尝试将输出系统调用从4(字符串输出)改为1(整数输出)后,得到了奇怪的数字268501072,无法理解异常原因。

原代码

.data
    
inBuf:      .space  80      # input line
outBuf:     .space  80      # char types for the input line
prompt:     .asciiz "Enter a new input line. \n"
.data
tabChar:    
    .word   0x09, 6     # tab
    .word   0x0a, 6     # LF
    .word   ' ', 6
    .word   '#', 5
    .word   '$', 4
    .word   '(', 4 
    .word   ')', 4 
    .word   '*', 3 
    .word   '+', 3 
    .word   ',', 4 
    .word   '-', 3 
    .word   '.', 4 
    .word   '/', 3 
    .word   '0', 1
    .word   '1', 1 
    .word   '2', 1 
    .word   '3', 1 
    .word   '4', 1 
    .word   '5', 1 
    .word   '6', 1 
    .word   '7', 1 
    .word   '8', 1 
    .word   '9', 1 
    .word   ':', 4 
    .word   'A', 2
    .word   'B', 2 
    .word   'C', 2 
    .word   'D', 2 
    .word   'E', 2 
    .word   'F', 2 
    .word   'G', 2 
    .word   'H', 2 
    .word   'I', 2 
    .word   'J', 2 
    .word   'K', 2
    .word   'L', 2 
    .word   'M', 2 
    .word   'N', 2 
    .word   'O', 2 
    .word   'P', 2 
    .word   'Q', 2 
    .word   'R', 2 
    .word   'S', 2 
    .word   'T', 2 
    .word   'U', 2
    .word   'V', 2 
    .word   'W', 2 
    .word   'X', 2 
    .word   'Y', 2
    .word   'Z', 2
    .word   'a', 2 
    .word   'b', 2 
    .word   'c', 2 
    .word   'd', 2 
    .word   'e', 2 
    .word   'f', 2 
    .word   'g', 2 
    .word   'h', 2 
    .word   'i', 2 
    .word   'j', 2 
    .word   'k', 2
    .word   'l', 2 
    .word   'm', 2 
    .word   'n', 2 
    .word   'o', 2 
    .word   'p', 2 
    .word   'q', 2 
    .word   'r', 2 
    .word   's', 2 
    .word   't', 2 
    .word   'u', 2
    .word   'v', 2 
    .word   'w', 2 
    .word   'x', 2 
    .word   'y', 2
    .word   'z', 2
    .word   0x5c, -1        # if you ‘\’ as the end-of-table symbol


.text
getline:
la  $a0, prompt     # Prompt to enter a new line
li  $v0, 4
syscall

la  $a0, inBuf      # read a new line
li  $a1, 80 
li  $v0, 8
syscall

linearSearch:
li $t0, 0 #load 0 into index

j linearLoop

linearLoop:
li $t4, 0 #load 0 into inner index
lb $a0, inBuf($t0) #load first byte from input
j linearLoopTab


linearLoopTab:
lb $a1, tabChar($t4) #load first byte from tabchar
beq $a1, $a0, found #compares input byte to tab byte, if similar jump to found
li $t2, '#' #makes t2 '#'
beq $a0, $t2, exit #if current input byte is '#', exit
addiu $t4, $t4, 8 #add index
j linearLoopTab #loop back

found:
addi $t4,$t4,4 #selects correct pos for encrypted message
lb $a2, tabChar($t4) #load first byte from input
subi $t4,$t4,4 #reverting pos


sb $a2, outBuf($t0) #store it into outbuff at index pos
addi $t0, $t0, 1 #add index
j linearLoop


exit:
la $a0, outBuf
li $v0, 4         #prints and leaves
syscall
la $a0,inBuf
jal clear
la $a0,outBuf
jal clear
li $v0, 10 #exit command
syscall

clear:
    li    $t0, 0

解决方案

1. 输出数字字符而非ASCII控制码

数组中的映射值是整数,要输出对应的数字字符,需要将整数转换为ASCII码。ASCII中数字'0'的编码是48,给每个映射值加上48即可得到对应数字的ASCII码:

  • 例如整数4 → 4 + 48 = 52,对应ASCII的'4'

修改found段代码:

found:
addi $t4,$t4,4          # 定位到映射值位置
lb $a2, tabChar($t4)    # 读取映射的整数
addi $a2, $a2, 48       # 转换为对应数字的ASCII码
subi $t4,$t4,4          # 恢复索引位置

sb $a2, outBuf($t0)     # 存入输出缓冲区
addi $t0, $t0, 1        # 输入缓冲区索引+1
j linearLoop

2. 系统调用1输出奇怪数字的原因

系统调用1(li $v0,1)要求$a0存储整数的值,但你直接将outBuf的内存地址加载到$a0,输出的268501072就是outBuf在内存中的地址值,并非目标整数。

如果要用系统调用1输出单个数字,需要逐个取出outBuf中的整数值存入$a0后调用,不能直接传入缓冲区地址。

3. 补充完整clear函数逻辑

原代码的clear函数未完成清空缓冲区的操作,补充如下:

clear:
    li    $t0, 0
clear_loop:
    sb    $zero, ($a0, $t0)  # 将当前位置设为字符串结束符0
    addi  $t0, $t0, 1
    bne   $t0, 80, clear_loop # 循环清空80字节
    jr    $ra                # 返回调用处

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:46:48