[英]Converting from C Loop to MIPS assembly language (bad address error)
我正在編寫一個簡單的MIPS匯編代碼,該代碼可循環訪問字符串中的字符
並找到給定子字符串的實例。
一,C代碼:
for (i=0; i<length(text)-length(sub_string); i++) {
match = TRUE
for (j=0; j<length(sub_string); j++)
if (text[i+j] != sub_string[j]) {
match = False;
break;
}
}
這是我的MIPS代碼的一部分。
.text
# a0: text
# a1: substring
# v0: count
myfunction:
move $s0, $ra
move $a2, $a0
jal strlen
move $t1, $v1 # text_len
move $a2, $a1
jal strlen
move $t2, $v1 # substring_len
sub $t1, $t1, $t2 # text_len - substring_len
li $t0, 0 # i = 0
j i_test
i_body:
li $t3, 1 # match = TRUE
li $t4, 0 # j = 0
j j_test
i_test:
blt $t0, $t1, i_body
move $ra, $s0
jr $ra
j_body:
add $t6, $a0, $t0 # &text[i]
add $t6, $t6, $t4 # &text[i+j]
lb $t6, 0($t6) # text[i+j]
add $t7, $a1, $t4 # &sub_string[j]
lb $t7, 0($t7) # sub_string[j]
beq $t6, $t7, j_skip # if (text[i+j] == sub_string[j])
# if (text[i+j] != sub_string[j])
li $t3, 0 # match = FALSE
j j_break # break
j_test:
blt $t4, $t2, j_body
j_skip:
addi $t4, $t4, 1 # j++
j j_body
j_break:
addi $t0, $t0, 1 # i++
j i_body
strlen:
li $v1, 0 # i = 0
b strlen_test
strlen_body:
addi $v1, $v1, 1 # len++
strlen_test:
add $t0, $a2, $v1 # &str[i]
lb $t0, 0($t0) # str[i]
bne $t0, $0, strlen_body # loop
jr $ra
.globl main
main:
la $a0, text1
la $a1, substring1
jal myfunction
la $a0, text1
jal print_string
li $v0, 10 # Exit
syscall
print_string:
li $v0, 4
syscall
la $a0, newline
li $v0, 4
syscall
jr $ra
.data
text1: .asciiz "Hello, world!"
substring1: .asciiz "lo"
newline: .asciiz "\n"
但是,當我運行這段代碼時,我遇到了一個糟糕的無限循環
地址錯誤:
Exception occurred at PC=0x00400070
Bad address in data/stack read: 0x10021778
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400078
Bad address in data/stack read: 0x10021786
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400070
Bad address in data/stack read: 0x10021779
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400078
Bad address in data/stack read: 0x10021787
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400070
Bad address in data/stack read: 0x1002177a
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400078
Bad address in data/stack read: 0x10021788
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400070
Bad address in data/stack read: 0x1002177b
Exception 7 [Bad address in data/stack read] occurred and ignored
Exception occurred at PC=0x00400078
Bad address in data/stack read: 0x10021789
Exception 7 [Bad address in data/stack read] occurred and ignored
我意識到錯誤的地址錯誤來自第3行和第5行
j_body(加載字節指令)。 我已經初始化了字符串地址,所以我不確定為什么
發生...
這是我的問題:
為什么會出現此無限循環? (我以為我已經為i和j正確實現了for循環)
為什么我收到一個錯誤的地址錯誤?
謝謝 :)
j_test:
blt $t4, $t2, j_body
j_skip:
addi $t4, $t4, 1 # j++
j j_body
j_break:
addi $t0, $t0, 1 # i++
j i_body
如果j_break
的條件失敗,您不應該跳到j_test
嗎? 立即編寫此代碼的方式是,即使j >= strlen(substring)
也要繼續執行“ j循環”的主體。
另外, j_break:
之后的j i_body
可能應該是j i_test
(您增加了i
,所以您將要檢查“ i循環”的條件是否仍然為真)。
在j_body中,您同時使用$ t7來存儲str(i + j)和sub_str(j); 然后通過比較beq $ t7,$ t7,j_body來決定是否退出j_body(僅此一條指令總會始終為true,並將其變為無限循環)。 將sub_str(j)中的字節存儲在$ t8中,並更改beq行以比較$ t7和$ t8。
可能還有更多; 但這肯定必須改變。 更正此問題后,建議運行,並用遇到的任何新錯誤更新您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.