2016-02-25 3 views
3

У меня есть вложенный цикл цикла с несколькими условиями для преобразования с использованием MIPS. Мой конкретный вопрос: как я сломаю эту строку из кода C, чтобы завершить эту инструкцию в 1 ветви в преобразовании MIPS? ->if((a[i] > 0) && (b[j] > 0))Вложенные в Loop множественные условия Mips

* Я обновил код, чтобы разбить условие if. Я получаю сообщение об ошибке при работе на Марсе. Ошибка:

строка 28: время выполнения исключение в 0x00400074: адрес выборки не выровнен по границе слова 0x10010069

код C находится здесь:

int i, j, M, N, count; 
    int a[]; 
    int b[]; 

    for(i=0; i<M; i++) { 
    for(j=0; j<N; j++) { 
     if((a[i] > 0) && (b[j] > 0)) { 
      count = count + 1; 
     } 
     } 
    } 

То, что я здесь:

.data 
a: .space 100 # Declare a array with 100 bytes of data 
b: .space 100 # Declare b array with 100 bytes of data 
i: .word 0 # Declare i counter 
j: .word # Declare j counter 

.text 

addi $t0, $zero, 10 # $t0 variable with score 10 
addi $s1, $zero, 0 # $s1 variable with array index 0 
sw $t0, a($s1) # Store 10 into a array at location 

addi $t1, $zero, 15 # $t0 variable with score 15 
addi $s2, $zero, 0 # $s2 variable with array index 0 
sw $t1, b($s2) # Store 15 into b array at location 0 

lw $t2, i($zero) # Initialize loop index i to 0 
lw $t3, j($zero) # Intialize loop index j to 0 
addi $s2, $zero, 5 # Initialize M to 5 
addi $s3, $zero, 5 # Initialize N to 5 
addi $s4, $zero, 0 # Initialize count to 0 

OuterLoop: beq $t2, $s2, Exit # i=M Exit the loop 
    lw $t0, a($s1) # Load value from a array 
    bgt $t0, 0, InnerLoop # if a[i] > 0 

InnerLoop: beq $t3, $s3, Exit # j=N Exit the loop 
    lw $t1, b($s2) # Load value from b array 
    bgt $t1, 0, Increment # if b[j] > 0 

Increment: addi $s4, $s4, 1 # Increment count by 1 
    addi $t2, $t2, 1 # Increment i by 1 
    addi $t3, $t3, 1 # Increment j by 1 
    j OuterLoop  

Exit: 
+5

Вы понимаете, что можете вытащить 'a [i]> 0' из внутреннего цикла? – EOF

+0

@EOF, что вы имеете в виду? – Kay

+3

Вы можете переписать циклы как 'for (i = 0, i 0) для (j = 0; i 0 ; ' – EOF

ответ

1

Я думаю, что if((a[i] > 0) && (b[j] > 0)) не может быть выполнено в одной ветви, потому что второй операнд && не следует оценивать, когда первый операнд является истинным (отличным от нуля).

Это пример MIPS кода, стоящего на if((a[i] > 0) & (b[j] > 0)) count = count + 1; (не тестировался)

# assuming that i = $t2, j = $t3, count = $s4 
    sll $t4, $t2, 2 # calculate offset of a[i] 
    lw $t5, a($t4) # load a[i] 
    sll $t4, $t3, 2 # calculate offset of b[j] 
    lw $t6, b($t4) # load b[j] 
    slt $t4, $zero, $t5 # $t4 = (a[i] > 0) 
    slt $t7, $zero, $t6 # $t7 = (b[j] > 0) 
    and $t4, $t4, $t7 # $t4 = (a[i] > 0) & (b[j] > 0) 
    beq $t4, $zero, NotTrue # skip increment if the condition is false 
    sll $zero, $zero, 0 # nop: prevent increment from being executed when the condition is false 
    addi $s4, $s4, 1 # count = count + 1 
NotTrue: 

UPDATE: С коррекцией других ошибок, код должен быть таким:

.data 
a: .space 100 # Declare a array with 100 bytes of data 
bb: .space 100 # Declare b array with 100 bytes of data 

.text 
main: 
    addi $t0, $zero, 10 # $t0 variable with score 10 
    addi $s1, $zero, 0 # $s1 variable with array index 0 
    sw $t0, a($s1) # Store 10 into a array at location 

    addi $t1, $zero, 15 # $t0 variable with score 15 
    addi $s2, $zero, 0 # $s2 variable with array index 0 
    sw $t1, bb($s2) # Store 15 into bb array at location 0 

    addi $t2, $zero, 0 # Initialize loop index i to 0 

    addi $s2, $zero, 5 # Initialize M to 5 
    addi $s3, $zero, 5 # Initialize N to 5 
    addi $s4, $zero, 0 # Initialize count to 0 

OuterLoop: beq $t2, $s2, Exit # i=M Exit the loop 

    addi $t3, $zero, 0 # Intialize loop index j to 0 
InnerLoop: beq $t3, $s3, ExitInnerLoop # j=N Exit the loop 

    sll $t4, $t2, 2 # calculate offset of a[i] 
    lw $t5, a($t4) # load a[i] 
    sll $t4, $t3, 2 # calculate offset of b[j] 
    lw $t6, bb($t4) # load b[j] 
    slt $t4, $zero, $t5 # $t4 = (a[i] > 0) 
    slt $t7, $zero, $t6 # $t7 = (b[j] > 0) 
    and $t4, $t4, $t7 # $t4 = (a[i] > 0) & (b[j] > 0) 
    beq $t4, $zero, NoIncrement # skip increment if the condition is false 
    nop # prevent increment from being executed when the condition is false 
    addi $s4, $s4, 1 # Increment count by 1 
NoIncrement: 

    addi $t3, $t3, 1 # Increment j by 1 
    j InnerLoop 
    nop 
ExitInnerLoop: 
    addi $t2, $t2, 1 # Increment i by 1 
    j OuterLoop 
    nop 

Exit: 
    # exit program 
    addi $v0, $zero, 10 
    syscall 

I изменил метку b на bb, потому что мой QtSpim жаловался на это, используя код операции как метку.

Смежные вопросы