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("%dn", (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("beforen");
lst_disp(list);
printf("aftern");
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_comp函数中打印(int)n1 - (int)n2的值,但它出现了错误,所以我猜swap:中的寄存器值有问题,但我不知道是什么,谢谢你的帮助。对于编译,我使用makefile,因为我将它与其他函数一起编译为库。所以为了这个文件:

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

如果你想看makefile,我在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函数指示错误的顺序时您会调用它(,而是交换寄存器中的值。

最新更新