使用ASMx64语言对C链表进行排序

问题描述

我正在尝试创建一个对程序集中的C链表进行排序的函数,但是它不起作用,我看不到如何解决此问题,我已经花了好几个小时了,如果有人可以帮助它会很好。 所以我要创建的函数原型是:

void ft_list_sort(t_list **begin_list,int (*cmp)());

我正在处理的链表只是一个简单的基本列表:

typedef struct s_list {
    void            *data;
    struct s_list   *next;
} t_list;

这是我带注释的函数的汇编代码

global ft_list_sort

section .text
ft_list_sort:
    mov r8,[rdi]              ;put begin pointer in r8
    mov r10,rsi                ;put cmp function in r10

main_loop:
    cmp  r8,0                 ;check if current list is null
    je   exit                   ;if null we are at the end of list so exit
    mov  r9,[r8 + 8]          ;put current list -> next in r9
    push r9                     ;save the value in the stack
    jmp  sort_loop              ;jump to our second loop

main_loop_after:
    pop  r8                     ;current list = current list -> next
    jmp  main_loop

sort_loop:
    cmp  r9,0                 ;check if loop list is null
    je   main_loop_after        ;if null we are at the end of list so jump back in main loop
    mov  rdi,[r8]              ;put current list data in rdi
    mov  rsi,[r9]              ;put loop list data in rsi
    call r10                    ;call cmp function
    cmp  rax,0                 ;check the result
    ja   swap                   ;if above zero jump to swap

sort_loop_after:
    mov  rdx,[r9 + 8]
    mov  r9,rdx               ;loop list = loop list -> next
    jmp  sort_loop              ;go back to begin of loop

swap:
    mov  rdx,rdi
    mov  rdi,rsi               ;swap rsi and rdi (current list data and loop list data)
    mov  rsi,rdx
    jmp  sort_loop_after        ;go back to the loop

exit:
    ret

然后我用这个主程序运行函数

#include <stdio.h>
#include <stdlib.h> 
#include <string.h>
#include <errno.h>

typedef struct s_list 
    void            *data;
    struct s_list   *next;
} t_list;

void                ft_list_push_front(t_list **begin_list,void *data);
int                 ft_list_size(t_list *begin_list);
void                ft_list_sort(t_list **begin_list,int (*cmp)());

t_list *lstnew(void *data) {
    t_list *newlist = malloc(sizeof(t_list));

    if (!newlist)
        return (NULL);
    newlist->data = data;
    newlist->next = NULL;
    return (newlist);
}

void lst_disp(t_list *lst) {
    while (lst) {
        printf("%d\n",(int)lst->data);
        lst = lst->next;
    }
}

void lst_clear(t_list **lst) {
    t_list *head = (*lst)->next;
    while (*lst) {
        free(*lst);
        *lst = head;
        if (head)
            head = head->next;
    }
}

int int_comp(void *n1,void* n2)
{
    return ((int)n1 - (int)n2);
}

int main(void) {
    t_list *list = lstnew((void*)1);
    ft_list_push_front(&list,(void*)10); //This function is to add a member to the list
    ft_list_push_front(&list,(void*)3);
    ft_list_push_front(&list,(void*)20);
    ft_list_push_front(&list,(void*)5);
    ft_list_push_front(&list,(void*)42);
    printf("before\n");
    lst_disp(list);
    printf("after\n");
    ft_list_sort(&list,&int_comp);
    lst_disp(list);
    lst_clear(&list);
    return (0);
}

它不会崩溃,但是该功能不执行任何操作。 输出

before
42
5
20
3
10
1
after
42
5
20
3
10
1

我试图在我的(int)n1 - (int)n2函数中打印int_comp的值,并且它存在段错误,所以我猜测swap:的寄存器值有问题,但是我不知道什么,谢谢您的帮助。 对于编译,我使用makefile,因为我将其与其他函数一起编译为库。 因此,为了仅此文件

nasm -f elf64 ft_list_sort.s
ar rcs libasm_bonus.a ft_list_sort.o
gcc main.c libasm_bonus.a

如果要查看我推送的my entire project on github生成文件

解决方法

正如@NateEldridge所指出的那样,您的汇编代码实际上从未将任何内容写入内存。

问题的核心似乎在于这部分:

swap:
    mov  rdx,rdi
    mov  rdi,rsi               ;swap rsi and rdi (current list data and loop list data)
    mov  rsi,rdx
    jmp  sort_loop_after        ;go back to the loop

而不是交换列表中的节点,而是在内存中(这似乎是您想要做的,因为您在cmp函数指示错误顺序时调用了此方法)–交换了寄存器中的值。