繁体   English   中英

在 mips32 中打印沙漏

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM