2016-04-05 12 views
1

自分のコードの.ktext部分に自分自身のエラー処理を作成しました。算術オーバーフローが発生したときに私のプログラムは正常にそこに行きますが、eretコードを使ってコードに戻す必要があるのに、正しく戻りません。返ってきたら、クリーンな部分にジャンプし、レジスタを消去しますが、プログラムを作成しようとすると、正しく印刷されないか再開されません。誰も私の方法の欠陥を教えてもらえますか?カーネルでユーザーテキストに戻って例外を処理した後

NOTE私はそれが実際にプログラムを再起動しないが、文字列の私の.DATA部分のどれもが正しく出力されないされている出力では、彼らはシンボルとして出力されていることに気付きました。ここでNOTE

は私のコードです: カーネルは、それが戻って、それは、私がゼロに$ S6を設定することを見て、すべてのレジスタをきれいに当時の私の最初のジャンプ以外の場所にジャンプし、例外を処理した後、プログラム。これは、プログラムを再起動し、ユーザーに小さな入力を求める不正な方法ですか?私の目標は、このタイプのエラー処理でプログラムすることです。

## 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" 

答えて

1

バグが多数ありました。私は、(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が一定バグを修正します。あなたはそれに必要なものを見つけなければなりません。