1

したがって、私の課題では、BubbleSort をアセンブラーで作成することになっています。この Java BubbleSort ループに基づいてアセンブラー コードを作成しました。何らかの理由で、アセンブラは配列 A と B が 1 つの大きな配列であると考え続け、全体を並べ替えようとします。Aで完了したらソートを停止し、Bで最初からやり直すことができないようです。

while (Done == 0) 
{  
  Done = 1;          // 1 represents true.
  i = 0;
  while ( i < N-k)
  { 
    if (A[i] > A[i+1])
    { 
      Help = A[i];
      A[i] = A[i+1];
      A[i+1] = Help;
      Done = 0;          // Not sorted...
    }
    i++;
  }
  k = k + 1;
}

ここにアセンブラコードがあります。書式が少し乱れていますが、まだ読めることを願っています。

Start:
move.l #A, D0
move.l #5, D1
bsr    BubbleSort   * Sort array A

move.l #0, i

Print1: 
move.l #5, D0
move.l i, D5  
cmp.l  i, D0
beq    Start2 **********

move.l #A, A0
move.l i, D0
muls  #4, D0
move.l  0(A0, D0.w), D0
jsr    WriteInt

addi.l  #1, i
bra    Print1

Start2:
move.l #str, A0  ************
move.l #5, D0
jsr    WriteLn

move.l #B, D0
move.l #10, D1
bsr    BubbleSort   * Sort array B

move.l #0, i

Print2:
move.l #10, D0
cmp.l  i, D0
beq    Stop

move.l #B, A0
move.l i, D0
muls  #4, D0
move.l  0(A0, D0.w), D0
jsr    WriteInt

addi.l  #1, i
bra    Print2

*D0 = address of int array to be sorted
*D1 = N

BubbleSort:
movea.l #A, A0
move.l #0, i
move.l #0, D    *Done is 0
move.l D, D2   *pass Done to D2
move.l D1, N  *N is number of elements
move.l #0, k

WhileStart:
cmp.l #0, D2  * compare if D2 == 0
BNE WhileEnd  *if not 0, go to WhileEnd
move.l #1, D2   * D2=1
move.l #0, i  * i = 0
move.l i, D3    *pass i to D3
move.l k, D4    * pass k to D4
move.l N, D7    * pass N to D7
sub.l D4,D7     * D7 = N-k

WhileStart2:
cmp.l D7, D3    *Compare i with N-k
BGE   WhileEnd2 
move.l i, D3
muls #4 D3
move.l 0(A0, D3.w), D5  *D5 = A[i]
move.l i, D4  
add.l #1, D4    *i+1
muls #4, D4
move.l 0(A0, D4.w), D6  *D6 = A[i+1]

IfStart:
cmp.l D6, D5    *compare A[i] with A[i+1]
BLE IfEnd
move.l D5, 5000 * pass A[i] to memory location 5000
move.l D6, 0(A0, D3.w) *A[i] = A[i+1]
move.l 5000, 0(A0, D4.w)  *A[i+1] = whatever was at location 5000 (old A[i])
move.l #0, D2       * D2=0 again
move.l i, D3     * passing i to D3
bra IfEnd   *End of If loop

IfEnd:
move.l i, D3    *i++
add.l #1, D3
move.l D3, i
bra WhileStart2    *Go back and compare i with N-k

WhileEnd2:
move.l k, D4    *k = k + 1
add.l #1, D4
move.l D4, k
bra WhileStart  * go back

WhileEnd:
rts *** I have added a rts to make sure your function returns....
4

1 に答える 1

1

これがM68Kの組み立てです。ここに参考文献があります: http://wpage.unina.it/rcanonic/didattica/ce1/docs/68000.pdf

あなたのコードには 2 つのセマンティック バグがあります。

1) バブル ソート ルーチン内で、呼び出し元が D0 に配置した値を使用することはありません。実際には、最初のステートメントで配列のアドレスを A にハードコーディングしています。

    movea.l #A, A0

これにより、配列 B がソートされなくなります。これを次のものに置き換えることをお勧めします。

    move.l D0, A0

2) 要素のアドレス指定には、余分な係数 2 が含まれます。たとえば、このスニペットでは、A0 から離れたインデックス レジスタとして D4 を使用しています。

    muls #4, D4
    move.l 0(A0, D4.w), D6  *D6 = A[i+1]

「Address Register Indirect with Index」アドレッシング モード ( http://www.freescale.com/files/archives/doc/ref_manual/M68000PRM.pdfのセクション 2.2.8 ) は、既にインデックス レジスタ (D4) の内容をスケーリングします。 32 ビットのオペランド サイズ (つまり、move.l の ".l") と 16 ビットのインデックス レジスタ仕様 (つまり、D4.w の ".w") に基づいて、2 ずつ。そのため、muls 命令は 2 だけを乗算する必要があります。なお、muls 命令を省略して、"D4.w" を "D4.l" に変更することもできます。

配列へのすべてのアクセスで、この同じ x2 インデックス エラーが発生しているようです。A と B が隣接するメモリ位置で宣言されていると仮定すると、この x2 インデックス エラーにより、A に対して呼び出されたときにソート ルーチンが B の要素にアクセスし、もちろんプロセス内の両方の配列に何らかの部分的な順序付けが課せられます。これは、ソート ルーチンが A と B の両方を同時にソートしているように見えます。

于 2015-09-10T07:56:04.377 に答える