Gauss Elimination Method Assembly MIPS

1.3k views Asked by At

The program should take into account the following functionality: The 2D array with the system to solve is passed to the program as an existing variable memory. - The data is of type double float. -The program should save the result in another variable. -The program should show the system of linear equations , before being resolved and in the end shouldshow the solution.

I did this code that shows the matrix:

.text

ldc1 $f30, double.zero($0) 
ldc1 $f28, double.um($0)
ldc1 $f26, ajuste.ID($0) 

la $a0,comeco 
li $v0,4 
syscall 

la $a1,matrizA 
jal build

la $a1, matrizAinv 
lw $a2, importante($0)
jal buildID 

la $a0,imprimirA 
li $v0,4 
syscall 

la $a1,matrizA
jal printmatrix 

la $a0,matrizA 
lw $a1,importante($0)
la $a2,matrizA2
jal copia_matriz 

la $a0,imprimirID 
li $v0,4
syscall

la $a1,matrizAinv
lw $a2,importante($0)
jal printmatrix 

li $v0,10 #Fim
syscall

build:
la $a0, dimensao 
li $v0, 4 
syscall 

li $v0, 5 
syscall 

sw $v0, importante($0) 
move $t0, $v0 

move $t2, $zero 
move $t3, $zero 
li $t5, 8 

main.cycle: 
beq $t3, $t0, continue

second.cycle:
beq $t2, $t0, third.cycle 
la $a0, element 
li $v0, 4 
syscall 

move $a0, $t3 
li $v0, 1 
syscall

la $a0, comma 
li $v0, 4 
syscall 

move $a0, $t2 
li $v0, 1 
syscall

li $v0, 7 
syscall

sdc1 $f0, 0($a1) 

add $a1, $a1, $t5

la $a0, enter 
li $v0, 4 
syscall

addi $t2, $t2, 1 #faz j++

j second.cycle 

third.cycle: 
addi $t3, $t3, 1 
move $t2, $zero 

j main.cycle 

continue:
jr $ra

buildID:
move $t2,$zero #i=0
move $t3,$zero #j=0

first.loop:
beq $t2,$a2,continue 

second.loop:
beq $t3,$a2,controle.conts 
bne $t2,$t3,element.zero 
sdc1 $f28,0($a1) 

end.second.loop:
add $a1,$a1,$t5 
addi $t3,$t3,1
j second.loop

element.zero: 
sdc1 $f30,0($a1) 

j end.second.loop

controle.conts:
addi $t2,$t2,1 
move $t3,$zero

j first.loop 

copia_matriz:
move $t0,$0 
move $t1,$0 

loop:

beq $t0,$a1,fim_copia_matriz 
beq $t1,$a1,incrementa.zera 

ldc1 $f1,0($a0) 
sdc1 $f1,0($a2) 

addi $a0,$a0,8 
addi $a2,$a2,8
addi $t1,$t1,1

j loop

incrementa.zera:
addi $t0,$t0,1 
move $t1,$0 

j loop

fim_copia_matriz:
jr $ra

printmatrix:
move $t0,$a2
move $t1,$a2

move $t2, $zero #reset i
move $t3, $zero #reset j

main.cycle3: #main cycle that print the matrix (first for)

beq $t2, $a2, exit3 #if i equal the number of lines of the matrix jump to exit3

la $a0, bar #load the addr of barleft into $a0
li $v0, 4 #4 is the print_string syscall
syscall #do the syscall

second.cycle3: #second cycle that print the matrix (second for)

la $a0, tab #load the addr of tab into $a0
li $v0, 4 #4 is the print_string syscall
syscall

beq $t3, $t0, third.cycle3 #if j equal the number of columms of the matrix go to the third cycle

mul $t4, $t0, $t2 #ColC*i
add $t4, $t4, $t3 #ColC*i+j
sll $t4, $t4, 3 #(ColC*i+j)*8

add $t5, $a1, $t4 #go to the element C[i][j]

ldc1 $f12, 0($t5)

li $v0, 3 #3 is the print_double syscall
syscall #do the syscall

move $t4, $zero #reset the index of the element
move $t5, $zero #reset the adress of the element

addi $t3, $t3, 1 #do j++

j second.cycle3 #continue the while with j++

third.cycle3: #third cycle that builds the matrix

addi $t2, $t2, 1 #do i++

la $a0, bar #load the addr of barright into $a0
li $v0, 4 #4 is the print_string syscall
syscall #do the syscall

la $a0, enter #load the addr of enter into $a0
li $v0, 4 #4 is the print_string syscall
syscall #do the syscall

move $t3, $zero #reset j

j main.cycle3 #continue the while with i++

exit3: #after print the matrix, return to main

la $a0, enter #load the addr of enter into $a0
li $v0, 4 #4 is the print_string syscall
syscall #do the syscall

jr $ra #return to main

I don't know how to apply the Gauss method . can you guys help me?

1

There are 1 answers

1
Ung-Lau On

See if it helps. cheers

### Text segment
    .text

main:
    la  $a0, matrix_3x3
    li  $a1, 3
    jal     print_matrix
    nop
    jal     gauss_reduct
    nop
    jal     print_matrix
    nop
    la  $a2, solution
    jal     gauss_solve
    nop
    jal     print_solution
    nop

exit:   
    li  $v0, 10
    syscall


gauss_reduct:
    addiu   $sp,  $sp, -24
    sw  $ra,  20($sp)
    sw      $s2,  16($sp)
    sw  $s1,  12($sp)
    sw  $s0,  8($sp) 
    sw  $a1,  4($sp) 
    sw  $a0,  0($sp)

    add $t3, $a0, $zero
    addi    $t4, $a1, -1
    addi    $t5, $a1, 0

    add $t2, $zero, $zero
gauss_reduct_ciclok:
    beq $t2, $t5, gauss_reduct_end
    nop

    add $t1, $zero, $zero
gauss_reduct_cicloj:
    beq $t1, $t5, gauss_reduct_fim_ciclo_j
    nop

    beq $t1,$t2,gauss_reduct_cicloj_continue
    nop

    move    $a0, $t1
    move    $a1, $t2
    jal fetchaddress
    nop
    move    $s1, $v0

    ldc1    $f6,($s1)

    move    $a0, $t2
    move    $a1, $t2
    jal fetchaddress
    nop
    move    $s1, $v0

    ldc1    $f8,($s1)

    div.d   $f4,$f6,$f8

    add $t0,$zero,$zero

    move    $a0, $t1
    move    $a1, $t0
    jal fetchaddress
    nop
    move    $s1, $v0

    move    $a0, $t2
    move    $a1, $t0
    jal fetchaddress
    nop
    move    $s2, $v0

gauss_reduct_cicloi:
    bgt $t0, $t5,gauss_reduct_fim_ciclo_i
    nop

    ldc1    $f6,($s1)
    ldc1    $f8,($s2)

    mul.d   $f8,$f8,$f4
    sub.d   $f6,$f6,$f8
    sdc1    $f6,($s1)
    addiu   $t0,$t0,1

    addiu   $s1,$s1,8
    addiu   $s2,$s2,8

    j   gauss_reduct_cicloi
    nop

gauss_reduct_fim_ciclo_i:

gauss_reduct_cicloj_continue:
    addiu   $t1,$t1,1
    j   gauss_reduct_cicloj
    nop

gauss_reduct_fim_ciclo_j:
    addiu   $t2,$t2,1
    j   gauss_reduct_ciclok
    nop

gauss_reduct_end:
    lw  $ra,  20($sp)
    lw  $s2,  16($sp)
    lw  $s1,  12($sp)
    lw  $s0,  8($sp)
    lw  $a1,  4($sp)
    lw  $a0,  0($sp)
    addiu   $sp,  $sp, 24

    jr  $ra
    nop

gauss_solve:
    addiu   $sp,  $sp, -24
    sw  $ra,  20($sp)
    sw      $s2,  16($sp)
    sw  $s1,  12($sp)
    sw  $s0,  8($sp) 
    sw  $a1,  4($sp) 
    sw  $a0,  0($sp)

    add $t3, $a0, $zero
    addi    $t0, $a1, -1
    addi    $t5, $a1, 0

    sll $s1, $t4, 3
    addu    $s1, $s1, $a2

    addi    $t0, $t4, 0
gauss_solve_cicloi:
    blt $t0, $zero, gauss_solve_end
    nop

    # v0 = &A[i][n]
    move    $a0, $t0
    move    $a1, $t5
    jal fetchaddress
    nop

    # $f6 = A[i][n]
    ldc1    $f6,($v0)

    # X[i] = A[i][n]
    sdc1    $f6,($s1)

    addi    $t1, $t0, 1

    sll $s2, $t1, 3
    add $s2, $s2, $a2

gauss_solve_cicloj:
    beq $t1, $t5, gauss_solve_fim_cicloi
    nop

    # v0 = &A[i][j]
    move    $a0, $t0
    move    $a1, $t1
    jal fetchaddress
    nop

    ldc1    $f8,($v0)
    ldc1    $f4,($s2)
    mul.d   $f8,$f8,$f4

    sub.d   $f6,$f6,$f8
    sdc1    $f6,($s1)

    addi    $t1,$t1,1
    addi    $s2, $s2, 8
    j   gauss_solve_cicloj
    nop

gauss_solve_fim_cicloi:

    # v0 = &A[i][i]
    move    $a0, $t0
    move    $a1, $t0
    jal fetchaddress
    nop

    # $f8 = A[i][i]
    ldc1    $f8,($v0)

    # x[i] = x[i] / A[i][i];
    div.d   $f6,$f6,$f8
    sdc1    $f6,($s1)

    subi    $t0,$t0,1
    subi    $s1, $s1, 8
    j   gauss_solve_cicloi
    nop

gauss_solve_end:
    lw  $ra,  20($sp)
    lw  $s2,  16($sp)
    lw  $s1,  12($sp)
    lw  $s0,  8($sp)
    lw  $a1,  4($sp)
    lw  $a0,  0($sp)
    addiu   $sp,  $sp, 24

    jr  $ra
    nop

fetchaddress:
    addiu   $t5,$t5,1
    multu   $a0, $t5
    subiu   $t5,$t5,1
    mflo    $v0
    add $v0, $v0, $a1
    sll $v0, $v0, 3
    add $v0, $v0, $t3
    jr  $ra
    nop


print_matrix:
    addiu   $sp,  $sp, -24
    sw  $ra,  20($sp)
    sw  $s2,  16($sp)
    sw  $s1,  12($sp)
    sw  $s0,  8($sp) 
    sw  $a2,  4($sp) 
    sw  $a0,  0($sp)

    move    $s2,  $a0
    move    $s1,  $zero
loop_s1:
    addi    $a2,$a1,1
    move    $s0,  $zero
loop_s0:
    l.d $f12, 0($s2)
    li  $v0,  3
    syscall
    la  $a0,  spaces
    li  $v0,  4
    syscall

    addiu   $s2,  $s2, 8

    addiu   $s0,  $s0, 1
    blt $s0,  $a2, loop_s0
    nop
    la  $a0,  newline
    syscall
    addiu   $s1,  $s1, 1
    blt $s1,  $a1, loop_s1
    nop
    la  $a0,  newline
    syscall

    lw  $ra,  20($sp)
    lw  $s2,  16($sp)
    lw  $s1,  12($sp)
    lw  $s0,  8($sp)
    lw  $a2,  4($sp)
    lw  $a0,  0($sp)
    addiu   $sp,  $sp, 20

    jr  $ra             # return
    nop


print_solution:
    addiu   $sp,  $sp, -24
    sw  $ra,  20($sp)
    sw      $s2,  16($sp)
    sw  $s1,  12($sp)
    sw  $s0,  8($sp) 
    sw  $a2,  4($sp) 
    sw  $a0,  0($sp)

    move    $s1,  $zero
    move    $s2,  $a2

print_solution_loop_s0:
    ldc1    $f12, ($s2)
    li  $v0,  3
    syscall

    addiu   $s2,  $s2, 8
    addiu   $s1,  $s1, 1
    la  $a0,  newline
    li  $v0,  4
    syscall
    blt $s1,  $a1, print_solution_loop_s0
    nop

    lw  $ra,  20($sp)
    lw  $s2,  16($sp)
    lw  $s1,  12($sp)
    lw  $s0,  8($sp)
    lw  $a2,  4($sp)
    lw  $a0,  0($sp)
    addiu   $sp,  $sp, 20

    jr  $ra
    nop

### End of text segment

### Data segment 
    .data

### String constants
spaces:
    .asciiz "   "
newline:
    .asciiz "\n"

## Input matrix: (4x4) ##
matrix_4x4: 
    .double  1.0
    .double  -2.0
    .double  1.0
    .double  3.0

    .double  1.0

    .double  2.0
    .double  -2.0
    .double  -2.0
    .double  -2.0

    .double  5.0

    .double 1.0
    .double -0.25
    .double 4.0
    .double 7.0

    .double  -7.0

    .double 1.0
    .double 1.0
    .double 1.0
    .double 1.0

    .double  3.0

solution:
    .double 0.0
    .double 0.0
    .double 0.0
    .double 0.0

matrix_3x3:
    .double  2.0
    .double  1.0
    .double  -3.0

    .double  -1.0

    .double  -1.0
    .double  3.0
    .double  2.0

    .double  12.0

    .double 3.0
    .double 1.0
    .double -3.0

    .double  0.0

### End of data segment