2016-12-02 1 views
0

私が取り組んでいるプログラムでは、ユーザからの入力に基づいて配列を分割するサブプログラムを書く必要があります(メイン)。つまり、元の配列が[4.2、-1.2、16.5、12.3、3.7、3.8、3.9]で、ユーザーが6.1をパーティション値として入力した場合、2つの配列は[4.2,1.2,3.7,3.8,3.9]および[16.5,12.3]。私が混乱しているのは、私は2つのループを使う必要があることを知っており、c.lt.dbc1fなどの値を比較しなければならないことを知っていますが、それを正しく行う方法ははっきりしていません。誰もがこれで私を助けることができますか?MIPSアセンブリでアレイをどのように分割するのですか?

はまた、これはサブプログラムの基本的なJISTです:

########################################################### 
#  Subprogram Description 
# 
#  'partition_array' 
# 
# 1. Determine how many values in source are < partition value 
# 2. Allocate two arrays on heap (one w/ values < partition value, 
#  one >= partition value) 
# 3. Copy the values from the source array into appropriate destination array 
# 4. Return base address and length of both 
# 
########################################################### 
#  Arguments In and Out of subprogram 
# 
# $sp source array base address (IN) 
# $sp+4 source array length (IN) 
# $sp+8 partition value, double-precision (IN) 
# $sp+16 "less" array base address (OUT) 
# $sp+20 "less" array length (OUT) 
# $sp+24 "greater" array base address (OUT) 
# $sp+28 "greater" array length (OUT) 
########################################################### 
     .data 

########################################################### 
     .text 
partition_array: 

partition_array_end: 

    jr $ra #return to calling location 
########################################################### 
+0

非効率的な呼び出し規約。 MIPS ABIはすべて、最初のいくつかのパラメータにいくつかのレジスタを使用しています。この種の決定は、手書きの組立てのポイントを総括的に敗北させるでしょう。 – Kaz

+0

@ Kazあなたは私の質問に答えるか、MIPSについて不平を言っていますか? –

答えて

0

私は自分自身でそれを考え出しました。あまりにも困難ではなく、ちょっとだけ計画しています。

########################################################### 
#  Arguments In and Out of subprogram 
# 
# $sp  source array base address (IN) 
# $sp+4 source array length (IN) 
# $sp+8 partition value, double-precision (IN) 
# $sp+16 "less" array base address (OUT) 
# $sp+20 "less" array length (OUT) 
# $sp+24 "greater" array base address (OUT) 
# $sp+28 "greater" array length (OUT) 
########################################################### 
#  Register Usage 
# $t0  array base address 
# $t1  array size 
# $t2  "less" array size 
# $t3  "greater" array size 
# $t4  "less" array base address 
# $t5  "greater" array base address 
# $f4  temporary (double) 
# $f12 partition value 
########################################################### 
     .data 

########################################################### 
     .text 
partition_array: 
    lw $t0, 0($sp) #load array base address 
    lw $t1, 4($sp) #load array size 
    lw $f12, 8($sp) #load partition value 

loop1: 
    blez $t1, continue #branch if reached end of array 

    l.d $f4, 0($t0) #load double @ array address 
    c.lt.d $f4, $f12 #compare and set flag if < partition value 

    bc1t less #branch to "less" array if true 
    bc1f greater #branch to "greater" array if false 

less: 
    addi $t2, $t2, 1 #add to "less" size 
    addi $t0, $t0, 8 #move to next array address 
    addi $t1, $t1, -1 #decrement counter 
    b loop1 

greater: 
    addi $t3, $t3, 1 #add to "greater" size 
    addi $t0, $t0, 8 #move to next array address 
    addi $t1, $t1, -1 #decrement counter 
    b loop1 

continue: 
    li $v0, 9 #create array for "less" 
    sll $a0, $t2, 3 
    syscall 
    move $v0, $t4 #move "less" array base address 

    li $v0, 9 #create array for "greater" 
    sll $a0, $t3, 3 
    syscall 
    move $v0, $t5 #move "greater" array base address 

    sw $t2, 20($sp) #store "less" array size on stack 
    sw $t3, 28($sp) #store "greater" array size on stack 

continue_loop: 
    blez $t1, partition_array_end #branch if reached end of array 

    l.d $f4, 0($t0) #load double @ array address 
    c.lt.d $f4, $f12 #compare and set flag if < partition value 

    bc1t create_less #branch to "less" array if true 
    bc1f create_greater #branch to "greater" array if false 

create_less: 
    s.d $f4, 0($t4) #store double @ array address 
    addi $t0, $t0, 8 #move to next main array address 
    addi $t1, $t1, -1 #decrement counter 
    addi $t4, $t4, 8 #move to next "less" array address 

    b continue_loop 

create_greater: 
    s.d $f4, 0($t5) #store double @ array address 
    addi $t0, $t0, 8 #move to next main array address 
    addi $t1, $t1, -1 #decrement counter 
    addi $t5, $t5, 8 #move to next "less" array address 

    b continue_loop 

partition_array_end: 
    sw $t4, 16($sp) #store "less" array base address on stack 
    sw $t5, 24($sp) #store "greater" array base address on stack 

    jr $ra #return to calling location 
+0

'bc1t less'を削除することができます。なぜなら、より少ないコードに「落ちる」ためです。洗練されたものとして、正論理を使用するには 'c $ f $ f12、$ f4'と' bc1t greater'を使います。同様に、後で 'c.lt.d'の2回目の使用のために。両方の場合、 '=='条件が '<'とは異なって扱われている場合にのみ、 'bc1t/bc1f'ブランチが必要です –

関連する問題