2

アセンブリ言語 (Linux、64 ビット、yasm) でバブルソート アルゴリズムの関数を実装しています。この関数は C ファイル内から呼び出され、配列と配列サイズがそれぞれ rdi と rsi を介してアセンブリに渡されます。

  xor rax, rax
  xor rbx, rbx
  xor r14, r14                  ; r14 : int j = 0
  xor r15, r15                  ; r15 : boolean swapped
  inc r15                       ; swapped = true    (=> swapped = 1)

  while:  
    cmp r15, 1                  ; while (swapped)   (=> check if  swapped == 1)
    jne end_while   

    dec r15                     ; swapped = false   (=> swapped = 0)
    inc r14                     ; j++    
    mov rdx, rsi                ; rdx = size
    sub rdx, r14                ; size - j
    xor rcx, rcx                ; int i = 0

  for:
    cmp rcx, rdx                ; i < size - j
    je end_for

    mov rax, [rdi+rcx*4+4]      ; rax = rdi+rcx*4+4 => arr[i+1]
    mov rbx, [rdi+rcx*4]        ; rbx = rdi+rcx*4   => temp = arr[i]

    cmp rbx, rax                ; if(arr[i] > arr[i+1])
    jng done_if

    mov  [rdi+rcx*4], rax       ; arr[i] = arr[i+1]
    mov  [rdi+rcx*4+4], rbx     ; arr[i+1] = temp        
    inc r15                     ; swapped = true (=> swapped = 1)

    done_if:

    inc rcx                     ; ++i
    jmp for

  end_for:  
  end_while:
    ret

配列は整数のみをソートします。私は Java でバブルソートをコーディングし、そこでテストしました。問題なく動作します。ただし、配列 {9,8,7,6,5,4,3,2,1,0} を C ファイル経由で渡すと、出力は {8,8,8,8,8,8,8, 8,8,9}。gdb でデバッグしましたが、まだ問題がどこにあるのかわかりません。for ループの構築は正常に機能します (rcx と rdx は正しく機能します)。配列要素へのアクセス方法に問題があるようです。アドバイスをいただければ幸いです。

4

1 に答える 1

1

問題は、どこでもクワッドワード (64 ビット整数) を使用しているのに、配列がダブルワード (32 ビット整数) でいっぱいになっていることです。特に、使用していた部分mov rax, [rdi+rcx*4+4]を に変更しmovl eax, [rdi+rcx*4+4]、他のmov指示も同様に に変更する必要がありmovlます。

于 2014-10-29T08:53:19.463 に答える