在MIPS中反转字符串时加载字节和存储字节问题?

问题描述 投票:0回答:1

我正在尝试反转汇编中的字符串。我是新手,所以我不知道如何调试。这是当前的代码。

## $a0 --> address of string
## $v0 --> string length

reverse_string:
    j string_length # this subroutine works
    la $t3, STR_str # contains the string
    
    div $t9, $v0, 2 # divide string length by 2
    add $t8, $zero, $zero # this is the counter
    sub $v0, $v0, 1 # string length - 1
    add $t7, $t3, $v0 # offset by string length - 1 to find last character
    j reverse_string_loop

reverse_string_loop:
    beq $t8, $t9, end_for_all # check if it has reached the halfway point
    lb $t1, 0($t7)     # load last character into $t1
        lb $t2, 0($t3)     # load current character into $t2
        sb $t1, 0($t3)     # store last character at current location
        sb $t2, 0($t7)     # store current character at last location
    add $t3, $t3, 1 
    sub $t7, $t7, 1
    add $t8, $t8, 1

我对 MIPS 中的存储和加载如何工作只有有限的了解,所以我猜问题就是这样。

它应该反转字符串,但目前它没有对测试字符串做任何事情。我没有写主要内容,但如果有帮助的话,这就是它的结构:

### reverse_string
##

li  $v0, 4
la $a0, STR_reverse_string
syscall

la $a0, STR_str
jal reverse_string

la $a0, STR_str
jal print_test_string


lw  $ra, 0($sp) # POP return address
addi    $sp, $sp, 4


jr  $ra

当我尝试运行它时弹出这些错误:

PC=0x00000004 处发生异常 读取文本中的错误地址:0x00000005

控制台说一些关于错误指令地址的信息,但我不确定发生在哪里。

assembly mips mips32 qtspim spim
1个回答
0
投票

您没有正确调用字符串长度。函数调用在汇编中非常复杂。

首先,您必须将字符串长度传递给返回地址。返回地址是一项功能,允许从不同的调用者、调用链的不同级别、甚至从同一调用者的不同调用站点调用同一函数,并且仍然能够返回到正确的调用者。返回地址通常使用

jal
指令传递,该指令将返回地址捕获到 $ra 中,供该函数稍后使用以返回到正确的调用者。我们没有看到返回地址在 C 或汇编之外的其他语言中具体化,但是,几乎所有汇编语言都让您以某种方式处理返回地址的概念。

我们可以在代码中看到您使用的是

j
而不是
jal
。异常中的 PC=0004 是另一个迹象,表明没有好的返回地址传递到字符串长度中。

其次,当跨越调用边界时,应遵守寄存器的使用情况。被调用函数可以使用一些寄存器而无需关注(调用破坏),而其他寄存器则可以使用,但必须将其原始值返回给调用者(调用保留)。相反,调用者不能依赖调用破坏的寄存器来幸存函数调用,但他们可以依赖调用保留的寄存器来幸存。为了使这样的系统发挥作用,所有职能都必须遵守规则。可以针对自定义场景省略/优化这些规则,尽管通常这样做是为了性能,而不一定是为了学习标准调用约定时的课程作业。

© www.soinside.com 2019 - 2024. All rights reserved.