aboutsummaryrefslogtreecommitdiff
path: root/linked_list.inc
blob: 6e0e0e44f0b6943e157bb1f138d4382dc6c12b30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
%ifndef LINKED_LIST_INC
%define LINKED_LIST_INC
%ifndef ALLOC_INC
%include "alloc.inc"
%endif

struc	LinkedListNode
ll_next:	resq	1
ll_value:	resq	1
endstruc

struc	DoublyLinkedListNode
dll_next:	resq	1
dll_prev:	resq	1
dll_value:	resq	1
endstruc

%macro	lln_alloc	0
	alloc	LinkedListNode_size
	mov	qword [rax + ll_next],	0
%endmacro

%macro	dll_alloc	0
	alloc	DoublyLinkedListNode_size
	mov	qword [rax + dll_next],	0
	mov	qword [rax + dll_prev],	0
%endmacro

%macro	lln_free	0-1	rax
	free	%1,	LinkedListNode_size
%endmacro

%macro	dll_free	0-1	rax
	free	%1,	DoublyLinkedListNode_size
%endmacro

%macro	ll_seek	0-1	rax
	mov	rax,	[%1 + ll_next]
%endm

_dll_seek_backward:
	mov	rax,	[rax + dll_prev]
	ret

_dll_seek_forward:
	mov	rax,	[rax + dll_next]
	ret

%macro	dll_seek	0-2	rax,"forward"
%if "%1" != "%rax"
	mov	rax,	%1
%endif
%if %2 == "forward"
	call _dll_seek_forward
%elif %2 == "backward"
	call _dll_seek_backward
%else
	%error "Direction not specified!"
%endif
%endm

_dll_end:
.loop:
	mov	rcx,	[rax + dll_next]
	cmp	rcx,	0
	je	.end
	call	_dll_seek_forward
	jmp	.loop
.end:
	ret

%macro	dll_end	0-1	rax
%if "%1" != "rax"
	mov	rax,	%1
%endif
	call	_dll_end
%endm

%macro	ll_push	2
	;; %1 = Current Linked List Node
	;; %2 = Value to push (Must fit in a register, larger must be pushed as pointer to the underlying structure)
	lln_alloc
	mov	qword [%1 + ll_next],	rax
	mov	qword [rax + ll_value],	%2
%endm

%macro	dll_push	2
	;; %1 = Current Doubly Linked List Node
	;; %2 = Value to push (Must fit in a register, larger must be pushed as pointer to the underlying structure)
	dll_alloc
	mov	rcx,	[%1 + dll_next]
	cmp	rcx,	0
	je	%%skip
	mov	qword [rcx + dll_prev],	rax
%%skip:
	mov	qword [%1 + dll_next],	rax
	mov	qword [rax + dll_next],	rcx
	mov	qword [rax + dll_value],	%2
	mov	qword [rax + dll_prev],	%1
%endm

_dll_free:
	push	rbp
	mov	rbp,	rsp
	push	rbx

	dll_end
.free_loop:
	mov	rbx,	[rax + dll_prev]
	dll_free
	mov	rax,	rbx
	cmp	rbx,	0
	jne	.free_loop
	pop	rbx
	mov	rsp,	rbp
	pop	rbp
	ret
%endif