I have been writing code high and low, all day long to try to get a linked list in x86 assembly. Nothing works, and it is so very frustrating. I am trying to make one that has elements 1, 2, and 3. GDB told me that it was segfaulting in the ret
statement at end
, but didn't provide any more info. Can anyone help me with this? I am assembling on a Mac with Clang.
Here is my code:
.global _main
.text
/*
r12: result
r14: number of elements left in list
r15: stack offset for accessing arguments
*/
make_list:
# # # # #
push rbp
mov rbp, rsp
# # # # #
mov rdi, [rbp + r15]
mov qword ptr [rax], rdi # assign first_node.head
lea r13, [rax + 8] # store address of first_node.tail
# # # # #
mov rdi, 16
sub rsp, 8
call _malloc
add rsp, 8
# # # # #
add r15, 8
sub r14, 1
# # # # #
mov rdi, [rbp + r15]
mov qword ptr [r13], rdi # assign second_node.head
# # # # #
cmp r14, 0
je end
# # # # #
mov rdi, 16
sub rsp, 8
call _malloc
add rsp, 8
# # # # #
jmp make_list # assign second_node.tail to an argument
# # # # #
end:
mov qword ptr [r13 + 8], 0 # second_node.tail = NULL
mov rsp, rbp
pop rbp
ret
# # # # #
_main:
# # # # #
mov rdi, 16
sub rsp, 8
call _malloc
add rsp, 8
lea r12, [rax]
# # # # #
mov r14, 3
mov r15, 16
# # # # #
push 3
push 2
push 1
# # # # #
call make_list
add rsp, 24
# # # # #
mov rdi, 0
mov rax, 0x2000001
syscall
# # # # #
The jmp make_list
instruction is incorrect. You don't want to jump to the start of the function, where you much rbp
again, but to somewhere partway in to your function, after all of your setup.
The multiple push rbp
instructions that don't get popped before the ret
cause the instruction pointer to get an invalid value in it, resulting in your setfault.