I'm implementing a linked list reversal in 64 bit assembly x86 for an assignment. Now, the node is a struct with three elements. First element is a union of int and char. Second element is a pointer to next node. Third element is an int, that holds a random value for testing.
We have a reverse function in C that takes reverse_list and passes in the head pointer and the offset to rdi and rsi respectively. The offset is the offset of the next node pointer from the beginning of the node (which I believe is 4 based on size of union).
So it's like
reverse_list(head, offset);
then that pops into
.intel_syntax noprefix
.text
.global reverse_list
reverse_list:
push rbx
mov rax, 0x0
mov rbx, rax
mov rcx, rax
mov rdx, rax
mov rax, [rdi]
cmp rax, 0
je null_ret
add rax, rsi
mov rbx, rax
while_start:
#while (headptr)
cmp rbx, 0x0
je while_done
#nextptr = (void *) (*((unsigned long *) headptr));
mov rcx, [rbx]
# *(unsigned long *) headptr = (unsigned long) new_headptr;
mov [rbx], rdx
#new_headptr = headptr
mov rdx, rbx
#headptr = nextptr
mov rbx, rcx
jmp while_start
while_done:
mov rax, rdx
sub rax, rsi
null_ret:
pop rbx
ret
My question is why when I add offset (rsi) to rax, it adds the offset to the value inside of the memory as well (example, address and int inside both change from one operation) and then when I try to dereference the value, I'm not getting the next pointer, just a segmentation fault.