2016-04-05 74 views
1

Kodumun .ktext bölümünde kendi hata işlemimi oluşturdum. Programım, bir aritmetik taşma oluştuğunda ancak eret koduyla kodun geri dönmesini istediğimde düzgün bir şekilde geri dönüyor ancak düzgün bir şekilde geri dönmez. Geri döndüğünde, temiz bölüme atlar, yazmaçları temizler, ancak programlamayı denediğim gibi düzgün yazdırmaz veya yeniden başlatılmaz. Merak ettiğim yöntemde bana kusurunu söyleyen var mı?Kernel'de İstisnayı Kullanarak Kullanıcı Metnine Dönüstürdükten Sonra

NOT Çıktıda aslında programın yeniden başlatıldığını, ancak dizelerimdeki .data bölümlerinin hiçbirinin doğru olarak alınmadığını, bunların sembol olarak çıkarıldığını fark ettim. NOT İşte

benim kodudur: Çekirdek geri olsaydı o zaman sıfıra $ s6 set görür ve sonra tüm kayıtlarını temizler ekleme konuma atlar başlangıcına geri atlar durum işleme sonra benim programı. Bu, programı yeniden başlatmanın ve kullanıcıyı daha küçük bir girdi için sormanın yanlış yolu mu? Amacım, bu tür bir hata işleme ile programlamaktır.

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

cevap

1

Bazı hatalar vardı. Ben: (1) "BUG" ile kaynağınızı açıklayın, (2) hataları düzeltin ve (3) istisna algoritmasını değiştirdim.


Burada [karşılıksız tarzı temizleme pardon lütfen] orijinal kaynak, sadece böcek açıklamalar var:

# 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" 
İşte

birincil için hata düzeltme var, "gösteri tıpa" böcek:

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

Burada daha temiz bir düzeltme var r birincil böcek yanı sıra [IMO] farklı/daha iyi bir yolu istisna işlemek için:

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

Not: Ben s6 sabit kaldığı değilhatayı düzeltmek yaptı. Bunun için ne istediğini bulmak zorundasın.