2016-05-10 11 views
1

私はユーザーに番号を尋ねてその番号を格納し、そのサイズのベクトルを作成して配列に格納する番号をユーザーに尋ねなければならないこれまで私はこれを持っているが、私は継続するのか分からない:配列を作成し、昇順と降順でソートする[MIPS]

.data 
string1: .asciiz "\nIntroduce size of array\n" 
string2: .asciiz "\nIntroduce next number\n" 
string3: .asciiz "\nBye\n" 

array: .word 

.text 
main: 
la $t4, array  #store the direction of the array 

li $v0, 4 
la $a0, string1 
syscall 
li $v0, 5 
syscall 
move $t0, $v0  #t0 = vector size 

asknum: 
li $v0, 4 
la $a0, string2 
syscall 
li $v0, 5 
syscall 
move $t5, $v0  #t5 = num introduced 
sw $t5, 4($t4)  #save number in the array, the program crashes here 
add $t2, $t2, 1 
bne $t2, $t0, asknum 

la $a0, cadena3 
li $v0,4 
syscall 
li $v0,10 
syscall 

私は数(私はそれが間違って格納してると思います)と私を保存しようとすると、プログラムがクラッシュした理由を私は知りません正直なところ、MIPSの配列でどのように配列をソートするのか分かりません。何か助けていただければ幸いです。

+0

あなたは、単一のためのスペースを予約しましたが'array'で単語(つまり4バイト)を読み込み、' array + 4'( '4($ t4) 'を通して)に書き込みを試みます。あなたが割り当てていないメモリに書き込まないでください。 – Michael

答えて

0

最初のものは番号を記憶してから次の番号のために4を付け加えていますu増分インデックスuはインデックスを上書きしません。

二つ目

1

簡単な修正を変更することである

ちょうどCのような、C++スタイルのこの

のli $のt7,0 配列($のT7)を試してみてください。

array: .word 

に:

.align 4 
array: .space 1000 

(つまり)1000/4または250となります。

もう1つのバグ:arrayの最初の要素を埋めることは決してありませんでした。あなたはarray[1]を記入していました。すべて値がそこに保存されていました。だから、変更:

sw $t5,4($t4) 

の中へ:

sw $t5,0($t4) 
addiu $t4,$t4,4 

別[マイナー]バグが明示的に設定することなくゼロ値を持つように$t2に頼っていることです。だから、ここでは、クリーンアップコードちょうどasknum:

li $t2,0 

前にこれを追加します。私は[無償スタイルのクリーンアップをご容赦ください]ユーザーの数に制限チェックを追加しました:

.data 
string1: .asciiz  "Introduce size of array: " 
string2: .asciiz  "Introduce next number: " 
string3: .asciiz  "\nBye\n" 

    .align 4 
array:  .space  1000 

    .text 

main: 
    # prompt user for array size 
    li  $v0,4 
    la  $a0,string1 
    syscall 

    li  $v0,5 
    syscall 
    move $t0,$v0     # remember user's count 

    li  $t1,250     # get max size -- user's answer too large? 
    bgt  $t0,$t1,main   # yes, ask again 

    la  $t4,array    # get the address of the array 
    li  $t2,0     # set index 

asknum: 
    # prompt user for number 
    li  $v0,4 
    la  $a0,string2 
    syscall 

    # get the array value and store it 
    li  $v0,5 
    syscall 
    sw  $v0,0($t4)    # save number in the array 

    addi $t4,$t4,4    # advance array pointer 
    addi $t2,$t2,1    # advance array index 
    bne  $t2,$t0,asknum   # more to do? if yes, loop 

    la  $a0,string3 
    li  $v0,4 
    syscall 

    li  $v0,10 
    syscall 

UPDATE:

は、あなたがの番号にアクセスする方法を私に説明することができますアレイ?私はこれを使用してそれらを印刷しようとしているが、それは0のすべての時間を印刷しています:

li  $s0,0xFFFF0010 
    li  $s1,0xFFFF0011 
    lw  $t8,4($t4)    # get the first element of the array 
    div  $t3,$t8,10 

配列の簡単な印刷のために、私はこのコードはあなたをどのように役立つかわかりません。周囲のコードのコンテキストがなければ、コードが何をしているのかを推測することは難しいです。

printf("%d",num)に相当することをしようとしているようですが、既に画面に整数を出力するためのシステムコールがあります。私はそれを使うだろう。しかし、...あなたが本当に自分自身をロールバックする必要があるなら、それを行うためのコードが含まれています。

アレイの印刷は、アレイの入力と似ています。

私は前のサンプルコードを修正しました。配列の入力は関数になりました。 arrend [見てください]

これが機能したら、それをコピーして貼り付け、新しいものに再加工するのは簡単なことでした関数arrprtは、配列を出力します。

手動でsyscall 1の機能を実行するには、prtint機能を追加しました。 arrprtは、システムコールを使用しますが、それは、prtintを使用するシステムコールをコメントアウトし、prtint

を呼び出すブロックのコメントを解除したい場合はここで新しいコードです:

.data 
msg_siz: .asciiz  "Introduce size of array: " 
msg_num: .asciiz  "Introduce next number: " 
msg_nl:  .asciiz  "\n" 
msg_bye: .asciiz  "\nBye\n" 

    .align 4 
array:  .space  1000 
arrend: 

prtint_hex: .asciiz  "ABCDEF" 
prtint_buf: .space  100 
    .text 

main: 
    jal  asknum     # read in array 
    jal  arrprt     # print array 

    # say goodbye 
    la  $a0,msg_bye 
    li  $v0,4 
    syscall 

    # exit program 
    li  $v0,10 
    syscall 

# asknum -- read in array of numbers 
# 
# RETURNS: 
# s0 -- array count 
# 
# registers: 
# t1 -- maximum array count 
# t2 -- current array index 
# t4 -- array pointer 
asknum: 
    # prompt user for array size 
    li  $v0,4 
    la  $a0,msg_siz 
    syscall 

    # read in user's count 
    li  $v0,5 
    syscall 
    move $s0,$v0     # remember user's count 

    la  $t4,array    # get address of array 

    # get number words of array 
    la  $t1,arrend    # get address of array end 
    sub  $t1,$t1,$t4    # get array byte length 
    srl  $t1,$t1,2    # get array word count 

    blez $s0,asknum    # user's count too small? yes, ask again 
    bgt  $s0,$t1,asknum   # user's count too large? yes, ask again 

    li  $t2,0     # set index 

    # prompt user for number 
asknum_loop: 
    li  $v0,4 
    la  $a0,msg_num 
    syscall 

    # get the array value and store it 
    li  $v0,5 
    syscall 
    sw  $v0,0($t4)    # save number in the array 

    addi $t4,$t4,4    # advance array pointer 
    addi $t2,$t2,1    # advance array index 
    bne  $t2,$s0,asknum_loop  # more to do? if yes, loop 

    jr  $ra      # return 

# arrprt -- print array of numbers 
# 
# arguments: 
# s0 -- array count 
# 
# registers: 
# t6 -- current array index 
# t7 -- array pointer 
arrprt: 
    subiu $sp,$sp,4 
    sw  $ra,0($sp) 

    la  $t7,array    # get address of array 
    li  $t6,0     # set index 

arrprt_loop: 
    # print array value (using syscall) 
    lw  $a0,0($t7)    # get array value 
    li  $v0,1 
    syscall 

    # print array value (using prtint) 
    ###lw  $a0,0($t7)    # get array value 
    ###li  $a1,10     # get number base to use 
    ###jal  prtint 

    # output a newline 
    li  $v0,4 
    la  $a0,msg_nl 
    syscall 

    addi $t7,$t7,4    # advance array pointer 
    addi $t6,$t6,1    # advance array index 
    bne  $t6,$s0,arrprt_loop  # more to do? if yes, loop 

    lw  $ra,0($sp) 
    addiu $sp,$sp,4 
    jr  $ra      # return 

# prtint -- print single integer 
# 
# arguments: 
# a0 -- integer to print 
# a1 -- integer base to use (e.g. 10) 
# 
# registers: 
# t2 -- current array index 
# t3 -- ascii digits pointer 
# t4 -- buffer pointer 
prtint: 
    la  $t4,prtint_buf   # get address of scratch buffer 
    la  $t3,prtint_hex   # get ascii digits pointer 

prtint_loop: 
    div  $a0,$a1     # number/base 
    mflo $a0      # get next number value 
    mfhi $t1      # get remainder 

    addu $t1,$t3,$t1    # get address of ascii digit 
    lb  $t1,0($t1)    # get ascii digit 

    sb  $t1,0($t4)    # store it in buffer 
    addiu $t4,$t4,1    # advance buffer pointer 

    bnez $a0,prtint_loop   # more to do? yes, loop 

    sb  $zero,0($t4)   # store EOS 

    # NOTE: the buffer we just created is _reversed_ (e.g. for a value of 
    # 123, it will be "321"), so we need to reverse it to be useful 

    subiu $t4,$t4,1    # back up to last ascii digit 
    la  $t3,prtint_buf   # point to buffer start 

prtint_revloop: 
    bge  $t3,$t4,prtint_revdone # are we done? yes, fly 

    lb  $t0,0($t3)    # get lhs char 
    lb  $t1,0($t4)    # get rhs char 

    sb  $t0,0($t4)    # store lhs char 
    sb  $t1,0($t3)    # store rhs char 

    addiu $t3,$t3,1    # advance lhs pointer (forward) 
    subiu $t4,$t4,1    # advance rhs pointer (backward) 
    j  prtint_revloop 

prtint_revdone: 
    # get the ascii string value and print it 
    la  $a0,prtint_buf 
    li  $v0,4 
    syscall 

    jr  $ra      # return 
+0

ありがとう、これは本当に役に立ちました – Sefean

+0

配列の番号にアクセスする方法を教えてください。私はこれを使用してそれらを印刷しようとしているが、それは0のすべての時間を印刷しています: のliの$ S0、0xFFFF0010 李$ s1を、0xFFFF0011 のLWの$ T8、4($ T4)\t \t \t#は最初の要素を取得しますの配列 div $ t3、$ t8,10 – Sefean

関連する問題