【问题标题】:Assembler subroutine to modify a C array用于修改 C 数组的汇编程序子例程
【发布时间】:2013-01-25 21:04:43
【问题描述】:

我正在尝试将用于对数字进行排序的汇编程序子例程与我的朋友与 C 代码链接以进行小组作业,但我们无法使其正常工作。排序算法(Shellsort)之前已经作为一个单独的程序进行了测试,应该可以工作。

我们正在使用 mysort 方法调用修改数组的例程:

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

我们将文件中的输入数字读入数组中:

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

我们这样调用排序例程:

 mysort(array, len>>2);

最后我们将数组写回文件。问题是我们的输出是一个数组,其中包含按相同顺序排列的原始数字,而不是按照应有的顺序进行排序。我们通过 RCX 寄存器将指向数组的指针传递给数组,因为这是在 Intel-64 中传递函数参数的方式。由于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);
}

【问题讨论】:

  • 英特尔有两个 64 位 ABI。你确定你的 C 代码和汇编程序匹配吗?
  • 您可以检查编译器为 C 代码生成的程序集,了解它如何将参数传递给您的函数。
  • 我会调查的,非常感谢。

标签: arrays sorting assembly x86-64 subroutine


【解决方案1】:

你似乎在遵循微软的调用约定,你是在 Windows 上吗?

不管怎样,这看起来大错特错:add rsp, 800。您的意思是 sub 分配一些空间吗? (但您在开始时已经有一个sub,所以您可以在那里调整值。

如果还是不行,使用调试器单步调试代码,看看哪里出错了。

【讨论】:

  • 我不在 Windows 上,这就是它不起作用的原因,我不得不为 Linux 使用不同的寄存器。谢谢。
猜你喜欢
  • 2018-11-26
  • 2010-10-22
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
相关资源
最近更新 更多