Mips 字符串中每两个字符交换一次并修复异常错误

Mips 字符串中每两个字符交换一次并修复异常错误,mips,Mips,我得到一个异常错误,我不知道为什么。我需要一些关于异常修复的帮助,以及如何交换用户输入字符串中的字符 输入和输出应如下所示: 输入:Apples 输出:perpse .text main: #Prompt user for string la $a0, promptStr li $v0, 4 syscall #Get String li $v0,8 la $a0, buffer li $a1, 20 syscall move $t0, $a0 #Initialize

我得到一个异常错误,我不知道为什么。我需要一些关于异常修复的帮助,以及如何交换用户输入字符串中的字符

输入和输出应如下所示:

输入:
Apples

输出:
perpse

.text
main:

#Prompt user for string
la $a0, promptStr
li $v0, 4
syscall

#Get String
li $v0,8 
    la $a0, buffer 
    li $a1, 20
syscall

move $t0, $a0

#Initialize pointer to start of string (specify register)
la $t0, buffer 

#Get a char from the string (register)
loop:   lb $t1, ($t0)
我在这里得到了未定义的
指令引用,我不知道为什么,因为我在类似的问题中使用过它,在字符串末尾分支出循环

这是错误消息

Instruction references undefined symbol at 0x00400058
[0x00400058] 0x11200000  beq $9, $0, 0 [strEnd-0x00400058]; 48: beqz $t1, strEnd 
我不知道这个密码是否正确。我只是需要帮助理解 如何交换字符以及代码的外观

#Swap the 2 chars by writing them back to the original string
sb $t2, ($t0)
sb $t1, ($t0)

#Add 1 to the string pointer
add $t0, 1 #Fixed

#Jump back to loopStart
j loop

#Display modified string
endStr: la $a0,ans
li $v0, 4
syscall

move $a0,$t2
li $v0, 4
syscall

#Blankline
la $a0, end
li $v0, 4
syscall

#Exit porgram
    li $v0, 10
syscall

.data
buffer: .space 20
promptStr: .asciiz "Input a string : "
blankLine   : .asciiz "\n"

错误
beqz$t0,strEnd
的问题在于输入错误:您所指的标签是
endStr
。错误本身告诉您这一点,突出显示未定义的
[strEnd-0x00400058]
。此外,spim在加载时警告我:

以下符号未定义:
结束
ans
在修复丢失的标签后,逻辑并不十分正确,尽管看起来您的思路是正确的。其思想是以字符对的形式跨过字符串,交换元素并在遇到空字符时退出(或者,根据您希望如何处理换行符,也可以选择换行符——最好是剥离/咀嚼)

对于初学者和一个相当次要的问题,在程序顶部附近有一条死指令:

move $t0, $a0  # $t0 will be overwritten by the next la

#Initialize pointer to start of string (specify register)
la $t0, buffer
进入循环和主逻辑,代码
beqz$t0,strengd
使用字符串的地址作为分支条件,而不是该地址的字节
$t1
。这会产生一个无限循环

接下来,
$t0
,遍历字符串的指针出现问题。逻辑

sb $t2, ($t0)
sb $t1, ($t0)
不起作用,因为
$t0
已递增,因此代码在

#Add 1 to the string pointer
add $t0, 1#Fixed
解决方案是在执行任何
添加$0,1
操作之前,将
$t0
存储在临时寄存器中。比如:

move $t3 $t0    # save the address of buf for swap

# ... later on, after incrementing `$t0` ...

sb $t2, ($t3)
sb $t1, ($t0)
在这里,您还可以通过添加/减去偏移量或使用索引遍历字符串来使用索引策略

最后,我不确定打印时,在程序结束时,
move$a0,
应该做什么

这里有一个可能的解决方案,可以解决这些问题,并通常清理逻辑:

.text
main:
    # prompt user for string
    la $a0 prompt
    li $v0 4
    syscall

    # get string
    la $a0 buffer 
    li $a1 20
    li $v0 8
    syscall

    move $s0 $a0    # incrementable pointer to buf

loop:
    # t1 = *(buf++) and exit if '\0' or '\n'
    move $t0 $s0    # save the address of buf for swap
    lb $t1 ($t0)    # t1 = *buf
    beqz $t1 end    # break if '\0'
    beq $t1 10 end  # break if '\n'
    add $s0 1       # buf++

    # t2 = *buf and exit if '\0' or '\n'
    lb $t2 ($s0)    # t2 = *buf
    beqz $t2 end    # break if '\0'
    beq $t2 10 end  # break if '\n'

    # swap the chars
    sb $t2 ($t0)    # *prev_buf = curr_buff_char
    sb $t1 ($s0)    # *buf = prev_buff_char

    # increment pointer and continue to the next pair
    add $s0 1       # buf++
    j loop

end: 
    # display modified string
    la $a0 buffer
    li $v0 4
    syscall
    
    # exit program
    li $v0 10
    syscall

.data
buffer: .space 20
prompt: .asciiz "Input a string : "
运行示例:

$ spim -f swap_alternating_chars.s
Input a string : Apple
pAlpe
$ spim -f swap_alternating_chars.s
Input a string : Apples
pAlpse

是否要共享异常消息?退出条件将测试指针是否为null:您应该改为查找NUL字符。你试过单步走吗?
$ spim -f swap_alternating_chars.s
Input a string : Apple
pAlpe
$ spim -f swap_alternating_chars.s
Input a string : Apples
pAlpse