问题描述
我正在尝试创建一个对程序集中的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
函数指示错误顺序时调用了此方法)–交换了寄存器中的值。