バグが多数ありました。私は、(1)あなたのソースに「BUG」と注釈を付け、(2)バグを修正し、(3)例外アルゴリズムを変更しました。
# 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"
ここでは、主のためのバグ修正だ、「ショーストッパー」バグ:
ここでは、あなたのオリジナルのソースは単なるバグ注釈[無償スタイルのクリーンアップをご容赦ください]、です
# 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"
ここでは、 R主なバグだけでなく、[IMO]例外を処理するために、異なる/より良い方法:
# 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"
注:私はないをしましたがs6
が一定バグを修正します。あなたはそれに必要なものを見つけなければなりません。