在MIPS中处理多个条件

时间:2018-11-21 23:54:51

标签: assembly mips

我正在制作一个MIPS程序,该程序可以读取和解决kakuro难题。目前它可以读取并打印出拼图,但是我在添加错误检查时遇到了一些问题。我必须做很多检查,由于某种原因,程序都没有按预期终止。如果输入中包含的值不合法(合法值将为:0,或范围1-45内的单个线索,或值为99的单个“块”线索),则您的程序必须打印以下错误消息,并且程序必须终止。法律输入的一些示例:

9999 blocking across and down clues
0799 across clue of 7, blocking down clue
9942 blocking across clue, down clue of 42
1208 across clue of 12, down clue of 8

所以,这就是我在C语言中想到的:

acrossClue = num / 100;
downClue = num % 100;
if(num != 0 && (1 > acrossClue || 45 < acrossClue || acrossClue != 99) 
|| (1 > downClue || 45 < downClue || downClue != 99)) {
    printf("Illegal input value, Cross sums terminating\n");
    return 1;
}

下面是我编写的main和read函数的代码。关于将条件和逻辑转移到MIPS的任何建议?它当前不起作用,因为即使输入不正确,它仍然会运行(即使提前终止,readPuzzle也会返回1),即使输入正确,它也会弄乱拼图。我的想法是,如果输入的不是所检查的任何值,那么该输入将是无效的,但是我猜想这行中的某个地方我没有正确检查,并且搞砸了所有内容。有没有人注意到我在readPuzzle中所做的任何检查?

#
# Name:         MAIN PROGRAM
# Description:  Main logic for the program.
#
#               The program reads these values from standard input:
#               1) an integer representing the size of the puzzle
#               2) integers representing values for each cell for the puzzle
#
#               If the dimensions of the board and values of the cells are
#               valid, the program then displays the initial puzzle, attempts
#               to solve it, and displays the solution if there is one.

    .text                           # this is program code
    .align 2                        # instructions must be on word boundaries
    .globl main                     # main is a global label

main:

    # Allocate stack frame

    addi    $sp, $sp,-FRAMESIZE_40
    sw      $ra, 32($sp)
    sw      $s7, 28($sp)
    sw      $s6, 24($sp)
    sw      $s5, 20($sp)
    sw      $s4, 16($sp)
    sw      $s3, 12($sp)
    sw      $s2, 8($sp)
    sw      $s1, 4($sp)
    sw      $s0, 0($sp)

    la      $t0, size

    li      $v0, READ_INT
    syscall
    move    $s0, $v0            # save size n

    blt     $s0, MIN_SIZE, size_error
    bgt     $s0, MAX_SIZE, size_error

    sw      $v0, 0($t0)

    move    $a0, $s0
    jal     readPuzzle

    move    $t7, $v0

    li      $v0, PRINT_INT
    move    $a0, $t7
    syscall

    beq     $v0, $zero, main_done

    la      $s1, puzzle

    li      $v0, PRINT_STRING
    la      $a0, newline
    syscall

    li      $v0, PRINT_STRING
    la      $a0, banner_border
    syscall

    li      $v0, PRINT_STRING
    la      $a0, banner_mid
    syscall

    li      $v0, PRINT_STRING
    la      $a0, banner_border
    syscall

    li      $v0, PRINT_STRING
    la      $a0, newline
    syscall

    li      $v0, PRINT_STRING
    la      $a0, initial
    syscall

    move    $a0, $s0
    move    $a1, $s1
    jal     printPuzzle

    li      $v0, PRINT_STRING
    la      $a0, final
    syscall

    move    $a0, $s0
    move    $a1, $s1
    jal     printPuzzle

    j       main_done

size_error:

    li      $v0, PRINT_STRING
    la      $a0, invalid_size
    syscall

    j       main_done

main_done:

    # Restore stack frame

    lw      $ra, 32($sp)
    lw      $s7, 28($sp)
    lw      $s6, 24($sp)
    lw      $s5, 20($sp)
    lw      $s4, 16($sp)
    lw      $s3, 12($sp)
    lw      $s2, 8($sp)
    lw      $s1, 4($sp)
    lw      $s0, 0($sp)
    addi    $sp, $sp, FRAMESIZE_40
    jr      $ra

# Name:         readPuzzle
#
# Description:  Reads in the puzzle from a file or stdin.
#
# Arguments:    a0      The size n
#
# Returns:      1 if the read was successful, otherwise 0
#

readPuzzle:

    addi    $sp, $sp, -FRAMESIZE_40
    sw      $ra, 32($sp)
    sw      $s7, 28($sp)
    sw      $s6, 24($sp)
    sw      $s5, 20($sp)
    sw      $s4, 16($sp)
    sw      $s3, 12($sp)
    sw      $s2, 8($sp)
    sw      $s1, 4($sp)
    sw      $s0, 0($sp)

    move    $s0, $a0

    mul     $s1, $s0, $s0       # get n * n
    li      $s2, 0
    la      $s3, puzzle
    li      $s4, 4
    li      $s5, 0              # row = 0
    li      $s6, 0              # col = 0
    mul     $s1, $s1, $s4       # get (n * n) * 4 bytes
    li      $t1, 100

    j       read_loop

read_loop:

    beq     $s2, $s1, read_done

    beq     $s5, $s1, reset

    li      $v0, READ_INT
    syscall
    move    $s7, $v0

    beq     $s7, $zero, continue

    div     $s7, $t1

    mflo    $t2                 # acrossClue = num / 100
    mfhi    $t3                 # downClue = num % 100

    seq     $t4, $t2, Block_Value
    seq     $t5, $t3, Block_Value

    seq     $t6, $t4, $t5
    bne     $t6, $zero, continue

    li      $t6, MIN_CLUE   # minimum value = 2
    li      $t7, MAX_CLUE   # maximum value = 45

    slt     $t4, $t2, $t6       # 1 if acrossClue < 2, otherwise 0
    slt     $t5, $t7, $t2       # 1 if acrossClue > 45, otherwise 0
    bne     $t4, $zero, illegal_input
    bne     $t5, $zero, illegal_input

    slt     $t4, $t3, $t6       # 1 if downClue < 2, otherwise 0
    slt     $t5, $t7, $t3       # 1 if downClue > 45, otherwise 0
    bne     $t4, $zero, illegal_input
    bne     $t5, $zero, illegal_input

    j       continue

continue:

    move    $a0, $s5
    move    $a1, $s6
    move    $a2, $s7
    jal     setElement

    addi    $s6, $s6, 1
    addi    $s2, $s2, 4
    j       read_loop

reset:

    addi    $s5, $s5, 1
    li      $s6, 0

illegal_input:

    li      $v0, PRINT_STRING
    la      $a0, invalid_input
    syscall

    li      $v0, 0

    j       read_done

read_done:

    li      $v0, 1

    lw      $ra, 32($sp)
    lw      $s7, 28($sp)
    lw      $s6, 24($sp)
    lw      $s5, 20($sp)
    lw      $s4, 16($sp)
    lw      $s3, 12($sp)
    lw      $s2, 8($sp)
    lw      $s1, 4($sp)
    lw      $s0, 0($sp)
    addi    $sp, $sp, FRAMESIZE_40
    jr      $ra

编辑:我得到了它,以便它可以正确知道何时输入有效或无效,但是当输入值无效时,它仍然不会终止。

0 个答案:

没有答案