[英]Printing an hourglass in mips32
我在解決這個問題時遇到問題。 我想使用 mips32 打印沙漏。 n
是用戶提供的 integer 作為輸入,沙漏必須打印在n
行中。 例如,對於n = 5
,output 為:
*****
***
*
***
*****
這是我第一部分的代碼(沙漏的三角形頂部)。 問題是它只打印第一行星星然后退出。 通過在 Mars 中逐行運行我的代碼,我了解到每次運行loop3
時都會運行backToLoop1
label 的第一行。 所以它會導致程序在第一行之后結束。 我真的不明白為什么會這樣。
.data
newLine: .asciiz "\n"
.text
main:
li $v0, 5 # read n
syscall # call sysetem
addi $t2, $v0, 0 # moves n to $t2
li $t0, 1 # i= 1
loop1:
blt $t2, $t0, Exit # if n<i exit
la $a0, newLine # go to next line
addi $v0, $0, 4 # 4 represents printing string
syscall # call system
# loop2 bounds
li $t1, 1 # k= 1
subi $t3, $t0, 1 # $t3= i-1 upper bound for loop2
# loop3 bounds
li $t5, 1 # j= 1
addi $t6, $t2, 1 # t6= n+1
sub $t6, $t6, $t0 # $t6= n+1-i upper bound for loop3
loop2:
blt $t3, $t1, loop3
li $a0, ' ' # load space to $a0
la $v0, 11 # 11 represents printing character
syscall # call system
addi $t1, $t1, 1 # k++
ble $t1, $t3, loop2 # if <= i-1 loop2 again
loop3:
blt $t6, $t5, backToLoop1 # back to loop1
li $a0, '*' # load star to $a0
la $v0, 11 # 4 represents printing character
syscall # call system
addi $t5, $t5, 1 # j++
ble $t5, $t6, loop3 # if j <= n-i+1 loop3 again
backToLoop1:
addi $t0, $t0, 1 # i++
ble $t0, $t2, loop1 # if i<=n loop1 again
blt $t2, $t0, Exit
Exit: # Terminate the program
li $v0, 10 # 10 represents exit
syscall # call system
你有一個好的開始。 但是,似乎沒有明確的策略來傾斜沙漏的右側。 理想情況下,我們可以編寫邏輯來處理繪制下半部分,而無需復制大部分邏輯。
對於這種模式,我的默認方法是使用兩個指針,左邊從 0 開始,右邊從 n - 1 開始。它們表示每行星號字符的索引范圍。 每行迭代,遞減右指針並遞增左指針,本質上是在 n × n 網格上繪制“X”模式。
這種策略使我們達到了 95% 的目標。 最后一步是如果left > right
則臨時交換左右指針,這可以處理繪制下半部分而不會產生太多意大利面條。
.data
prompt: .asciiz "enter a number: "
.text
main:
la $a0 prompt # collect n
li $v0 4
syscall
li $v0 5
syscall
move $s3 $v0 # n
li $s0 0 # left index
move $s1 $s3 # right index = n - 1
addi $s1 $s1 -1
row_loop:
bltz $s1 exit # while right-- >= 0
li $s2 0 # column index
col_loop:
beq $s2 $s3 row_loop_done # for 0..n
# if left > right, swap temporarily
move $t0 $s0
move $t1 $s1
blt $t0 $t1 pick_char
move $t2 $t0
move $t0 $t1
move $t1 $t2
pick_char:
# '*' if left <= i <= right else ' '
blt $s2 $t0 pick_space
bgt $s2 $t1 pick_space
li $a0 42 # print '*'
j print_char
pick_space:
li $a0 32 # print ' '
print_char:
li $v0 11
syscall
addi $s2 $s2 1 # column index++
j col_loop
row_loop_done:
li $a0 10 # print newline
li $v0 11
syscall
addi $s1 $s1 -1 # right--
addi $s0 $s0 1 # left++
j row_loop
exit:
li $v0 10
syscall
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.