2016-04-05 13 views
1

Ich habe meine eigene Fehlerbehandlung im .ktext Teil meines Codes erstellt. Mein Programm läuft ordnungsgemäß, wenn ein arithmetischer Überlauf auftritt, aber wenn ich möchte, dass es über den Code eret zum Code zurückkehrt, kehrt es jedoch nicht ordnungsgemäß zurück. Wenn es zurückkehrt, springt es zum sauberen Teil, bereinigt die Register, druckt aber nicht richtig oder startet nicht neu, wie ich versucht habe, es zu programmieren. Kann mir bitte jemand den Fehler meiner Methode mitteilen?Nach der Behandlung der Ausnahme im Kernel Rückkehr zum Benutzertext

HINWEIS Ich habe festgestellt, dass in der Ausgabe tatsächlich das Programm neu gestartet wird, aber keiner meiner .data-Teil der Strings korrekt ausgegeben wird, sie werden als Symbole ausgegeben. HINWEIS

Hier ist mein Code: , nachdem der Kernel die Ausnahme behandelt es zurück in die Zugabestelle springt, wo es sieht dann, dass ich $ s6 auf Null gesetzt und reinigt alle Register springt dann zurück zum Anfang meiner Programm. Ist das die falsche Art, das Programm neu zu starten und den Benutzer nach einer kleineren Eingabe zu fragen? Mein Ziel ist es, diese Art der Fehlerbehandlung zu programmieren.

## Daniel Revie 
## 2/8/2016 



.data 0x10000000 
.align 2 
Array1: .word 0:9 
str1: .asciiz "This is assignment 6 \n" 
str2: .asciiz "The value of a[" 
str5: .asciiz "] is: " 
str3: .asciiz "Arithmetic overflow" 
str4: .asciiz "Enter n: " 
str6: .asciiz "Arithmetic Overflow" 
clean: .asciiz "clean occurs" 

.text 0x00400000 
.align 2 
.globl main 

main: 



Restart: 

## Print str1 
li $v0, 4   # load 4 to $v0 to begin printing 
la $a0, str1  # load address of string to be printed 
syscall 

## Print str4 
li $v0, 4 
la $a0, str4 
syscall 

## Read in N 
li $v0, 5 
syscall 
move $t6, $v0 
addi $t6, 1 
addi $s6, $t6, -1 

li $s6, 1 


## assign array values 
addi $t0, $zero 0 # value 0 
addi $t1, $zero 1 # value 1 
addi $t2, $zero 2 # value 2 
addi $t3, $zero 4 # value N = 4 
#addi $t6, $zero 10 # End value a[9] is the 10th element 

## byte addressing issue 
mul $a0, $t0, $t3 # $t0 *4 
mul $a1, $t1, $t3 # $t1 *4 
mul $a2, $t2, $t3 # $t2 *4 

## store first 3 elements of the array 
sw $t0, Array1($a0) # a[0] = 0 
sw $t1, Array1($a1) # a[1] = 1 
sw $t1, Array1($a2) # a[2] = 1 

addi $v1 $zero 4 # get value 4 

addi $t4, $zero 3 
## begin loop algoirthm to generate rest of array values 
Loop: 


## End condition 
beq $t4, $t6 END 

## generate n - k 
addi $t0, $t4 -1  # n-1 
addi $t1, $t4 -2  # n-2 
addi $t2, $t4 -3  # n-3 

## byte addressing issue 
mul $t0, $t0, $v1 # $t0 *4 
mul $t1, $t1, $v1 # $t1 *4 
mul $t2, $t2, $v1 # $t2 *4 

## store the values 
lw $a0, Array1($t0) # a[n-1] 
lw $a1, Array1($t1) # a[n-2] 
lw $a2, Array1($t2) # a[n-3] 

## begin addition 
add $t5, $a0 $a1  # a[n-1] + a[n-2] 
beq $s7, $s6, Clean 
add $t5, $t5 $a2  # a[n-1] + a[n-2] + a[n-3] 
beq $s7, $s6, Clean 

## save the result in the proper location 
mul $a3 $t4 $v1  # $a3 = $t4 * 4 
sw $t5, Array1($a3) 

## increment N 
addi $t4, $t4, 1 

## repeat 
j Loop 


END: 
mul $t6, $t6, $v1 # $t6 * 4 
lw $t7, Array1($a3) 

## print str2 
li $v0, 4 
la $a0, str2 
syscall 

## print value of answer 
li $v0, 1 
move $a0, $s6 
syscall 

# print str5 
li $v0, 4 
la $a0, str5 
syscall 

## Print contents of $t7 
addi $a0, $t7, 0 # Move the product to $a0 
li $v0, 1   # code for printing register 
syscall 

j Finish 

Clean: 

li $t0, 0 
li $t1, 0 
li $t2, 0 
li $t3, 0 
li $t4, 0 
li $t5, 0 
li $t6, 0 
li $t7, 0 

li $s0, 0 
li $s1, 0 
li $s2, 0 
li $s3, 0 
li $s4, 0 
li $s5, 0 
li $s6, 0 
li $s7, 0 

li $v0, 0 
li $v1, 0 
li $a0, 0 
li $a1, 0 
li $a2, 0 
li $a3, 0 

j Restart 




Finish: 
## End program 
li $v0, 10 
syscall 



## Begin arithmetic overflow handling 
.ktext 0x80000180 


## Print overflow message 
move $k0,$v0 # Save $v0 value 
move $k1,$a0 # Save $a0 value 
li $v0, 4 
la $a0, kstr1 
syscall 
move $v0,$k0 # Restore $v0 
move $a0,$k1 # Restore $a0 
mfc0 $k0,$14 # Coprocessor 0 register $14 has address of trapping instruction 
addi $k0,$k0,4 # Add 4 to point to next instruction 
mtc0 $k0,$14 # Store new address back into $14 

li $s7, 1 

eret 


.kdata 
kstr1: .asciiz "Arithmetic overflow" 

Antwort

1

Es gab eine Reihe von Fehlern. Ich habe: (1) Ihre Quelle mit "BUG" kommentiert, (2) die Fehler behoben und (3) den Ausnahmealgorithmus geändert.


Hier ist Ihre ursprüngliche Quelle, nur Bug Anmerkungen [bitte unentgeltlichen Stil Bereinigungs verzeihen]:

# Daniel Revie 
# 2/8/2016 

    ###.data 0x10000000   # BUG: does weird things in mars 
    ###.align 2 
    .data 
Array1:  .word  0:9 
str1:  .asciiz  "This is assignment 6 \n" 
str2:  .asciiz  "The value of a[" 
str5:  .asciiz  "] is: " 
str3:  .asciiz  "Arithmetic overflow" 
str4:  .asciiz  "Enter n: " 
str6:  .asciiz  "Arithmetic Overflow" 
clean:  .asciiz  "clean occurs" 

    ###.text 0x00400000 
    .text 
    ###.align 2     # BUG: flagged by assembler 
    .globl main 

main: 

restart: 

    # Print str1 
    li  $v0,4     # load 4 to $v0 to begin printing 
    la  $a0,str1    # load address of string to be printed 
    syscall 

    # Print str4 
    li  $v0,4 
    la  $a0,str4 
    syscall 

    # Read in N 
    li  $v0,5 
    syscall 
    move $t6,$v0 
    ###addi $t6,1     # BUG: flagged -- invalid 
    addi $t6,$t6,1    # FIX: corrected 
    addi $s6,$t6,-1    # BUG: this gets trashed in next inst 

    # BUG: no check is made for t6 exceeding the end of Array1 
    # with large enough N, the stores below will overrun and destroy str1 et. 
    # al. so that on a restart, the first string print will be garbage [as well 
    # as any other messages] 

    li  $s6,1     # BUG: this never changes 

    # assign array values 
    addi $t0,$zero,0    # value 0 
    addi $t1,$zero,1    # value 1 
    addi $t2,$zero,2    # value 2 
    addi $t3,$zero,4    # value N = 4 
    # addi $t6, $zero, 10 # End value a[9] is the 10th element 

    # byte addressing issue 
    mul  $a0,$t0,$t3    # $t0 *4 
    mul  $a1,$t1,$t3    # $t1 *4 
    mul  $a2,$t2,$t3    # $t2 *4 

    # store first 3 elements of the array 
    sw  $t0,Array1($a0)   # a[0] = 0 
    sw  $t1,Array1($a1)   # a[1] = 1 
    sw  $t1,Array1($a2)   # a[2] = 1 

    addi $v1,$zero,4    # get value 4 

    addi $t4,$zero,3 
# begin loop algoirthm to generate rest of array values 
Loop: 

    # End condition 
    beq  $t4,$t6,END 

    # generate n - k 
    addi $t0,$t4,-1    # n-1 
    addi $t1,$t4,-2    # n-2 
    addi $t2,$t4,-3    # n-3 

    # byte addressing issue 
    mul  $t0,$t0,$v1    # $t0 *4 
    mul  $t1,$t1,$v1    # $t1 *4 
    mul  $t2,$t2,$v1    # $t2 *4 

    # store the values 
    lw  $a0,Array1($t0)   # a[n-1] 
    lw  $a1,Array1($t1)   # a[n-2] 
    lw  $a2,Array1($t2)   # a[n-3] 

    # begin addition 
    add  $t5,$a0,$a1    # a[n-1] + a[n-2] 
    beq  $s7,$s6,cleanup 
    add  $t5,$t5,$a2    # a[n-1] + a[n-2] + a[n-3] 
    beq  $s7,$s6,cleanup 

    # save the result in the proper location 
    mul  $a3,$t4,$v1    # $a3 = $t4 * 4 
    sw  $t5,Array1($a3) 

    # increment N 
    addi $t4,$t4,1 

    # repeat 
    j  Loop 

END: 
    mul  $t6,$t6,$v1    # $t6 * 4 
    lw  $t7,Array1($a3) 

    # print str2 
    li  $v0,4 
    la  $a0,str2 
    syscall 

    # print value of answer 
    # BUG -- answer is always 1 
    li  $v0,1 
    move $a0,$s6 
    syscall 

    # print str5 
    li  $v0,4 
    la  $a0,str5 
    syscall 

    # Print contents of $t7 
    addi $a0,$t7,0    # Move the product to $a0 
    li  $v0,1     # code for printing register 
    syscall 

    j  finish 

cleanup: 

    li  $t0,0 
    li  $t1,0 
    li  $t2,0 
    li  $t3,0 
    li  $t4,0 
    li  $t5,0 
    li  $t6,0 
    li  $t7,0 

    li  $s0,0 
    li  $s1,0 
    li  $s2,0 
    li  $s3,0 
    li  $s4,0 
    li  $s5,0 
    li  $s6,0 
    li  $s7,0 

    li  $v0,0 
    li  $v1,0 
    li  $a0,0 
    li  $a1,0 
    li  $a2,0 
    li  $a3,0 

    j  restart 

finish: 
    # End program 
    li  $v0,10 
    syscall 

# Begin arithmetic overflow handling 
    .ktext 0x80000180 

    # Print overflow message 
    move $k0,$v0     # Save $v0 value 
    move $k1,$a0     # Save $a0 value 
    li  $v0,4 
    la  $a0,kstr1 
    syscall 
    move $v0,$k0     # Restore $v0 
    move $a0,$k1     # Restore $a0 
    mfc0 $k0,$14     # Coproc 0 $14 has address of trapping inst 

    # BUG: in the general case, this doesn't do much and hinges on the base 
    # code testing the s7 value we set below 
    # much better to fill $14 with the address of restart 
    addi $k0,$k0,4    # Add 4 to point to next instruction 

    mtc0 $k0,$14     # Store new address back into $14 

    # BUG: this needs a comment to explain _why_ this is a corrective action 
    # we should _not_ have to _infer_ it 
    # BUG: this is a _weak_ response at best 
    li  $s7,1 

    eret 

    .kdata 
kstr1:  .asciiz  "Arithmetic overflow" 

Hier ist der Bug-Fix für den primären, "Show Stopper" Bug:

# Daniel Revie 
# 2/8/2016 

###.data 0x10000000   # BUG: does weird things in mars 
###.align 2 
    .data 

Array1:  .space  10000 
    # BUG -- this was way too short (see below) 
    ###Array1:  .word  0:9 

str1:  .asciiz  "This is assignment 6 \n" 
str2:  .asciiz  "The value of a[" 
str5:  .asciiz  "] is: " 
str3:  .asciiz  "Arithmetic overflow" 
str4:  .asciiz  "Enter n: " 
str6:  .asciiz  "Arithmetic Overflow" 
clean:  .asciiz  "clean occurs" 

###.text 0x00400000 
    .text 
###.align 2     # BUG: flagged by assembler 
    .globl main 

main: 

restart: 

    # Print str1 
    li  $v0,4     # load 4 to $v0 to begin printing 
    la  $a0,str1    # load address of string to be printed 
    syscall 

    # Print str4 
    li  $v0,4 
    la  $a0,str4 
    syscall 

    # Read in N 
    li  $v0,5 
    syscall 
    move $t6,$v0 
    ###addi $t6,1     # BUG: flagged -- invalid 
    addi $t6,$t6,1    # FIX: corrected 

    # BUG: no check is made for t6 exceeding the end of Array1 
    # with large enough N, the stores below will overrun and destroy str1 et. 
    # al. so that on a restart, the first string print will be garbage [as well 
    # as any other messages] 
    # FIX: increase size of Array1 from 10 words to something large enough 
    # this is just a quick fix -- the correct one is to limit N to the size 
    # of Array1 

    li  $s6,1     # BUG: this never changes 

    # assign array values 
    li  $t0,0     # value 0 
    li  $t1,1     # value 1 
    li  $t2,2     # value 2 
    li  $t3,4     # value N = 4 
    # li $t6,10 # End value a[9] is the 10th element 

    # byte addressing issue 
    mul  $a0,$t0,$t3    # $t0 *4 
    mul  $a1,$t1,$t3    # $t1 *4 
    mul  $a2,$t2,$t3    # $t2 *4 

    # store first 3 elements of the array 
    sw  $t0,Array1($a0)   # a[0] = 0 
    sw  $t1,Array1($a1)   # a[1] = 1 
    sw  $t1,Array1($a2)   # a[2] = 1 

    li  $v1,4     # get value 4 

    li  $t4,3 

# begin loop algorithm to generate rest of array values 
loop: 

    # End condition 
    beq  $t4,$t6,done 

    # generate n - k 
    subi $t0,$t4,1    # n-1 
    subi $t1,$t4,2    # n-2 
    subi $t2,$t4,3    # n-3 

    # byte addressing issue 
    mul  $t0,$t0,$v1    # $t0 *4 
    mul  $t1,$t1,$v1    # $t1 *4 
    mul  $t2,$t2,$v1    # $t2 *4 

    # store the values 
    lw  $a0,Array1($t0)   # a[n-1] 
    lw  $a1,Array1($t1)   # a[n-2] 
    lw  $a2,Array1($t2)   # a[n-3] 

    # begin addition 
    add  $t5,$a0,$a1    # a[n-1] + a[n-2] 
    bnez $s7,cleanup 
    add  $t5,$t5,$a2    # a[n-1] + a[n-2] + a[n-3] 
    bnez $s7,cleanup 

    # save the result in the proper location 
    mul  $a3,$t4,$v1    # $a3 = $t4 * 4 
    sw  $t5,Array1($a3) 

    # increment N 
    addi $t4,$t4,1 

    # repeat 
    j  loop 

done: 
    mul  $t6,$t6,$v1    # $t6 * 4 
    lw  $t7,Array1($a3) 

    # print str2 
    li  $v0,4 
    la  $a0,str2 
    syscall 

    # print value of answer 
    # BUG -- answer is always 1 
    li  $v0,1 
    move $a0,$s6 
    syscall 

    # print str5 
    li  $v0,4 
    la  $a0,str5 
    syscall 

    # Print contents of $t7 
    addi $a0,$t7,0    # Move the product to $a0 
    li  $v0,1     # code for printing register 
    syscall 

    j  finish 

cleanup: 

    li  $t0,0 
    li  $t1,0 
    li  $t2,0 
    li  $t3,0 
    li  $t4,0 
    li  $t5,0 
    li  $t6,0 
    li  $t7,0 

    li  $s0,0 
    li  $s1,0 
    li  $s2,0 
    li  $s3,0 
    li  $s4,0 
    li  $s5,0 
    li  $s6,0 
    li  $s7,0 

    li  $v0,0 
    li  $v1,0 
    li  $a0,0 
    li  $a1,0 
    li  $a2,0 
    li  $a3,0 

    j  restart 

finish: 
    # End program 
    li  $v0,10 
    syscall 

# Begin arithmetic overflow handling 
    .ktext 0x80000180 

    # Print overflow message 
    move $k0,$v0     # Save $v0 value 
    move $k1,$a0     # Save $a0 value 
    li  $v0,4 
    la  $a0,kstr1 
    syscall 
    move $v0,$k0     # Restore $v0 
    move $a0,$k1     # Restore $a0 
    mfc0 $k0,$14     # Coproc 0 $14 has address of trapping inst 

    # BUG: in the general case, this doesn't do much and hinges on the base 
    # code testing the s7 value we set below 
    # much better to fill $14 with the address of restart 
    addi $k0,$k0,4    # Add 4 to point to next instruction 

    mtc0 $k0,$14     # Store new address back into $14 

    # BUG: this needs a comment to explain _why_ this is a corrective action 
    # we should _not_ have to _infer_ it 
    # this is a weak/fragile response at best as it only works for two places 
    # above (e.g. this is hardwired) 
    li  $s7,1 

    eret 

    .kdata 
kstr1:  .asciiz  "\nhandler: Arithmetic overflow\n" 

Hier ist ein sauberer Fix fo r die primären Fehler sowie [IMO] ein anderer/besserer Weg, um die Ausnahme zu behandeln:

# Daniel Revie 
# 2/8/2016 

###.data 0x10000000   # BUG: does weird things in mars 
###.align 2 
    .data 
Array1:  .space  1000 
Ae: 
str1:  .asciiz  "This is assignment 6 \n" 
str2:  .asciiz  "The value of a[" 
str5:  .asciiz  "] is: " 
str3:  .asciiz  "Arithmetic overflow" 
str4:  .asciiz  "Enter n: " 
str6:  .asciiz  "Restarting ...\n" 
clean:  .asciiz  "clean occurs" 

strlge:  .asciiz  "count too large -- maximum is " 
strnl:  .asciiz  "\n" 

###.text 0x00400000 
    .text 
###.align 2     # BUG: flagged by assembler 
    .globl main 

main: 

    # show the assignment 
    li  $v0,4     # load 4 to $v0 to begin printing 
    la  $a0,str1    # load address of string to be printed 
    syscall 

    # prompt user 
    li  $v0,4 
    la  $a0,str4 
    syscall 

    # get size of Array1 
    la  $t6,Array1    # get base address of array 
    la  $s6,Ae     # get address of array end 
    sub  $s6,$s6,$t6    # get array size in bytes 
    srl  $s6,$s6,2    # get array count 

    # Read in N 
    li  $v0,5 
    syscall 
    move $t6,$v0 

    bgt  $t6,$s6,toolarge  # is length okay? no, fly 

    addi $t6,$t6,1    # N += 1 

    li  $s6,1     # BUG: this never changes 

    # assign array values 
    li  $t0,0     # value 0 
    li  $t1,1     # value 1 
    li  $t2,2     # value 2 
    li  $t3,4     # value N = 4 
    # addi $t6, $zero, 10 # End value a[9] is the 10th element 

    # byte addressing issue 
    mul  $a0,$t0,$t3    # $t0 *4 
    mul  $a1,$t1,$t3    # $t1 *4 
    mul  $a2,$t2,$t3    # $t2 *4 

    # store first 3 elements of the array 
    sw  $t0,Array1($a0)   # a[0] = 0 
    sw  $t1,Array1($a1)   # a[1] = 1 
    sw  $t1,Array1($a2)   # a[2] = 1 

    li  $v1,4     # get value 4 

    li  $t4,3 

# begin loop algorithm to generate rest of array values 
loop: 

    # End condition 
    beq  $t4,$t6,done 

    # generate n - k 
    subi $t0,$t4,1    # n-1 
    subi $t1,$t4,2    # n-2 
    subi $t2,$t4,3    # n-3 

    # byte addressing issue 
    mul  $t0,$t0,$v1    # $t0 *4 
    mul  $t1,$t1,$v1    # $t1 *4 
    mul  $t2,$t2,$v1    # $t2 *4 

    # store the values 
    lw  $a0,Array1($t0)   # a[n-1] 
    lw  $a1,Array1($t1)   # a[n-2] 
    lw  $a2,Array1($t2)   # a[n-3] 

    # begin addition 
    add  $t5,$a0,$a1    # a[n-1] + a[n-2] 
    ###beq  $s7,$s6,cleanup 
    add  $t5,$t5,$a2    # a[n-1] + a[n-2] + a[n-3] 
    ###beq  $s7,$s6,cleanup 

    # save the result in the proper location 
    mul  $a3,$t4,$v1    # $a3 = $t4 * 4 
    sw  $t5,Array1($a3) 

    # increment N 
    addi $t4,$t4,1 

    # repeat 
    j  loop 

done: 
    mul  $t6,$t6,$v1    # $t6 * 4 
    lw  $t7,Array1($a3) 

    # print str2 
    li  $v0,4 
    la  $a0,str2 
    syscall 

    # print value of answer 
    # BUG -- answer is always 1 
    li  $v0,1 
    move $a0,$s6 
    syscall 

    # print str5 
    li  $v0,4 
    la  $a0,str5 
    syscall 

    # Print contents of $t7 
    addi $a0,$t7,0    # Move the product to $a0 
    li  $v0,1     # code for printing register 
    syscall 

    j  finish 

# tell user to cut down the size 
toolarge: 
    li  $v0,4 
    la  $a0,strlge 
    syscall 

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

    li  $v0,4 
    la  $a0,strnl 
    syscall 

    j  main 

restart: 
    li  $v0,4 
    la  $a0,str6 
    syscall 

cleanup: 
    li  $t0,0 
    li  $t1,0 
    li  $t2,0 
    li  $t3,0 
    li  $t4,0 
    li  $t5,0 
    li  $t6,0 
    li  $t7,0 

    li  $s0,0 
    li  $s1,0 
    li  $s2,0 
    li  $s3,0 
    li  $s4,0 
    li  $s5,0 
    li  $s6,0 
    li  $s7,0 

    li  $v0,0 
    li  $v1,0 
    li  $a0,0 
    li  $a1,0 
    li  $a2,0 
    li  $a3,0 

    j  main 

finish: 
    # End program 
    li  $v0,10 
    syscall 

# Begin arithmetic overflow handling 
    .ktext 0x80000180 

    move $k0,$v0     # Save $v0 value 
    move $k1,$a0     # Save $a0 value 

    # Print overflow message 
    li  $v0,4 
    la  $a0,kstr1 
    syscall 

    # print PC in hex 
    li  $v0,34 
    mfc0 $a0,$14     # Coproc 0 $14 has address of trapping inst 
    syscall 

    # print newline 
    li  $v0,4 
    la  $a0,kstr2 
    syscall 

    la  $a0,restart    # get the restart address 
    mtc0 $a0,$14     # Store new address back into $14 

    move $v0,$k0     # Restore $v0 
    move $a0,$k1     # Restore $a0 

    eret 

    .kdata 
kstr1:  .asciiz  "\nhandler: Arithmetic overflow -- PC = " 
kstr2:  .asciiz  "\n" 

Hinweis: Ich habe nicht die Fehler zu beheben, wo s6 konstant bleibt. Sie müssen herausfinden, was Sie dafür wollen.