Mips过程:循环无限,PC出现异常



看到网站上的主题,但我没能解决我的问题。我注意到过程中的代码落入了for的无穷大,在QTSpim中,我看到所涉及的寄存器是$s0$s1$t2$t4

在几个周期之后,消息CCD_ 5然后是CCD_。这是代码,我不知道哪里出错了,我试着在没有过程的情况下写它,它运行得很完美。

.data
string: .asciiz "Hello Simon"
string2: .asciiz ""
.text
.globl main
Delete_space:
addi $sp, $sp, -16
sw $s0, 0($sp)
sw $s1, 4($sp)
add $t8, $a0, $zero
lenght_string:
lb $t0, 0($t8)
beqz $t0, for #t8 contain the lenght of string
add $t8, 1
j lenght_string
for:
add $s0, $zero, $zero #i=0
add $s1, $zero, $zero #j=0
condition:
slt $t1, $s0, $t8 #i< lenght_string
beq $t1, $zero, endfor

consequence:
add $t2, $t8, $s0
lb $t3, 0($t2)
bne $t3, ' ', op1
beq $t3, ' ', else
addi $s0, $s0, 1
addi $s1, $s1, 1
j condition
op1:
add $t4, $a1, $s1
sb $t3, 0($t4)
addi $s0, $s0, 1
addi $s1, $s1, 1
j condition
else:
sub $s1, $s1, 1
addi $s0, $s0, 1
addi $s1, $s1, 1
j condition
endfor:
#end 
lw $s1, 4($sp)
lw $s0, 0($sp)
addi $sp, $sp, 16
jr $ra
main:
la $a0, string
la $a1, string2
jal Delete_space
la $a0, string2
li $v0, 4
syscall
li $v0, 10
syscall

我认为您正试图跳过空格将字符从一个字符串复制到另一个字符串。(也许这不是你想要做的——不幸的是,我没有时间详细跟踪代码。)我认为问题是你正在从源字符串复制到一个不属于你的数据区域。

字符串在Assembly中的处理与在高级语言中的处理不同。它们不过是一个字节序列——没有字符串的概念,它会自动扩展以包含您放入的内容。也没有边界检查的概念。

看看这些字符串声明:

.data
string: .asciiz "Hello Simon"
string2: .asciiz ""

您所做的是将string分配给一个包含字节值'H'的内存地址。随后的存储器位置包含CCD_ 9。

然后,将string2分配给一个包含字节值''(空终止符)的内存地址。

如果向string2指向的内存地址写入一个字节,它将替换空终止符。(此时您可能已经遇到了麻烦,因为syscall不知道字符串的结束位置。)如果您将另一个字节写入string2 + 1指向的内存地址,那么您现在正在写入未分配给string2的内存。它可能属于正在存储的其他变量——在这种情况下,您只需覆盖以前存在的内容。这是一个"缓冲区溢出",也是像InternetExplorer这样写得不好的程序被黑客利用的原因。

如果我正确地解释了你的程序的目的,你需要为你的输出创建一个足够大的缓冲区来容纳它

.data
string: .asciiz "Hello Simon"
string2: .asciiz "xxxxxxxxxxx"

最新更新