0

グループ割り当てのために友人とCコードを使用して数値をソートするためのアセンブラーサブルーチンをリンクしようとしていますが、それを機能させるのに問題があります。ソートアルゴリズム(Shellsort)は以前に別のプログラムとしてテストされており、機能するはずです。

mysortメソッドを使用して、配列を変更するルーチンを呼び出しています。

void mysort (uint32_t array[], uint32_t len);

入力番号をファイルから配列に読み込みます。

len = read(f, array, ARRAY_SIZE*4);

ソートルーチンを次のように呼び出します。

 mysort(array, len>>2);

最後に、配列をファイルに書き戻します。問題は、出力が元の数値を同じ順序で含む配列であり、本来のように並べ替えられていないことです。Intel-64で関数パラメータが渡される方法であるため、RCXレジスタを介して配列へのポインタを配列に渡します。Cソースコードは先生から提供されたものなので、アセンブラコードに何か問題があったのではないかと思われます。

何かアドバイスをいただければ幸いです。前もって感謝します!

これが私たちのルーチンです:

section .text

global mysort

mysort:
    push rbp
    mov rbp,rsp
    sub rsp, 8
    mov r10, rcx    ; r10 -> pointer to array
    mov r11, rdx    ; r11 -> length
; The gaps
    add rsp, 800
    mov r13, 10
    mov [rsp], r13
    mov r13, 4
    mov [rsp+8], r13
    mov r13, 1
    mov [rsp+16], r13
    xor rax, rax             ; l := 0
gaploop:
    mov rbx, [rsp+4*rax]   ; rbx -> current gap value
    mov rcx, rbx             ; rcx -> i
insertionsort_outerloop:
    cmp rcx, r11    ; compare i with n
    jge endouterloop
    mov edx, [r10+4*rcx];edx -> temp
    mov rsi, rcx        ;rsi -> j
insertionsort_innerloop:
    mov rdi, rsi    ;
    sub rdi, rbx    ;rdi -> j-gap
    mov r8d, [r10+4*rdi]
    cmp rsi, rbx    ; compare j with gap
    jl endofloop    ; jump to end of loop if j < gap
    cmp r8d, edx    ; compare a[j-gap] with temp
    jna endofloop   ; jump to end of loop if a[j-gap] not greater than temp
    mov [r10+4*rsi], r8d
    sub rsi, rbx
    jmp insertionsort_innerloop 
endofloop:
    mov [r10+4*rsi], edx        ; a[j] := temp
    inc rcx     ; i++
    jmp insertionsort_outerloop
endouterloop:
    inc rax     ; l++
    cmp rax, 1  ; cmp eax with length of gaps
    jle gaploop
    mov rsp,rbp
    pop rbp
    ret 

そしてCコード:

#define ARRAY_SIZE 32768
void mysort (uint32_t array[], uint32_t len);

int main(int argc, char *argv[])
{
    int f,n;
    uint32_t array[ARRAY_SIZE];
    uint64_t len;
    if (argc < 2) {
        printf("Usage: %s input_file output_file\n", argv[0]);
        exit (0);
    }
    printf("Opening %s\n", argv[1]);
    f = open(argv[1], O_RDONLY);
    printf("Input file opened\n");
    len = read(f, array, ARRAY_SIZE*4);
    printf("File size is %u bytes (%lu numbers)\n", len, len/4);
    close (f);
    printf("Sorting...");
    mysort(array, len>>2);
    printf("done\n");
    printf("Opening %s for writing\n", argv[2]);
    f = open(argv[2], O_WRONLY | O_CREAT, 0644);
    printf("File descriptor %d; errno = %d\n", f, errno);
    n = write(f, array, len);
    printf("Written %d bytes; errno = %d\n", n, errno);
    close(f);
    return(0);
}
4

1 に答える 1

0

Microsoft の呼び出し規約に従っているようですが、Windows を使用していますか?

いずれにせよ、これはひどく間違っているように見えます: add rsp, 800. スペースを割り当てるつもりだったのでしょうsubか。(ただしsub、最初に が既にあるので、そこで値を調整するだけでかまいません)。

それでも問題が解決しない場合は、デバッガーを使用してコードをステップ実行し、問題のある場所を確認してください。

于 2013-01-25T22:56:48.240 に答える