-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlinklistref.asm
More file actions
233 lines (195 loc) · 6.26 KB
/
linklistref.asm
File metadata and controls
233 lines (195 loc) · 6.26 KB
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
;;; Linked lists; my first not entirely trivial assembler program
;;;
;;; Bart Kastermans, www.bartk.nl
section .text
global main ; gcc likes main, ld linkes _start
; but can use ld -e main
; with gcc get linkage for printf
;;; Use printf from libraries
extern printf
;;; Macros for manipulating a node with address in eax, values in ebx
%define usenode mov word [eax+node.used],0x1
%define freenode mov word [eax+node.used],0x0
%define setnodev mov [eax+node.value],bx
%define setnodel mov [eax+node.next],ebx
%define ebxnn mov ebx,[ebx+node.next]
;;; Test newnode and printl
testnn: call newnode
mov bx, 0x5
setnodev
mov [tempn],eax
call newnode
mov bx,0x2
setnodev
mov ebx,[tempn]
setnodel
mov ebx,eax
call printl
ret
;;; Test newlist, addlist, and printl
testnl: mov bx,0x1
call newlist
mov [list1],eax
mov bx,0x2
call addlist
mov eax,[list1]
mov bx,0x3
call addlist
mov eax,[list1]
mov bx,0x4
call addlist
mov ebx,[list1]
call printl
ret
;;; Test running out of space for nodes.
;;; Note that when other tests are run before we'll run out before 0x101
testos: mov edx,0x101 ; plan to assign 0x101 nodes
mov ebx,edx
call newlist
mov [list1],eax ; set up new list head in [list1]
.nn: sub edx,0x1
mov ebx,edx
mov eax,[list1]
call addlist
cmp edx,0x0
jne .nn
ret
main: mov edx,0x5
call seqlist
mov [tempa],eax
mov ebx,[tempa]
call printl
mov ebx,[tempa]
ebxnn
ebxnn
call delnode ; deleting the node after 3rd node
mov ebx,[tempa]
call printl
mov ebx,[tempa]
ebxnn
ebxnn
mov ax,0x9
call insnode
mov ebx,[tempa]
call printl
retsuc: mov ebx,0 ; return value, succes
mov eax,1 ; kernel function to exit program
int 0x80 ; exit program
retfa: mov ebx,1 ; return on fail
mov eax,1
int 0x80
;;; Linked list
;;; In this first attempt just allocate the list and print it
struc node
.used resw 1
.value resw 1
.next resd 1
endstruc
;;; Put in eax the address of next available node
newnode:
mov eax,nodesp ; put nodespace address in eax
.nn: cmp eax,maxnode
jae nospace ; no node can start above maxnode
cmp dword [eax+node.used],0x0 ; check if available
je .nodefound
add eax,onens ; move to next node
jmp .nn
.nodefound:
usenode
ret
;;; Put in eax the address of a new list with value as in ebx
newlist:
call newnode
setnodev
ret
;;; Add value in ebx to end of list in eax
addlist:
cmp dword [eax+node.next],0x0
je .attail ; eax now contains the last node in list
mov eax,[eax+node.next]
jmp addlist
.attail:
mov ecx,eax ; save tail node to set .next on it later
call newnode ; get new node
setnodev ; set value of new node
mov [ecx+node.next],eax ; point previous tail to this new node
ret
;;; Build a list with edx..0 in the nodes (call with edx>0)
seqlist:
mov ebx,edx
call newlist
mov [tempa],eax
.nn: sub edx,0x1
cmp edx,0x0
jbe .done
mov eax,[tempa]
mov ebx,edx
call addlist
jmp .nn
.done: mov eax,[tempa]
mov ebx,0x0
call addlist
mov eax,[tempa]
ret
;;; delete the next node from the list in ebx
delnode:
cmp word [ebx+node.next],0x0
je .done ; no node to remove
mov eax,[ebx+node.next]
freenode
mov eax,[eax+node.next]
mov [ebx+node.next],eax
.done: ret
;;; insert a node with value ax after current node in ebx
insnode:
mov [tempb],ax
mov [tempc],ebx
call newnode
mov bx,[tempb]
setnodev
mov ebx,[tempc]
mov ecx,[ebx+node.next]
mov [ebx+node.next],eax
mov [eax+node.next],ecx
ret
;;; Print nospace message and exit with failure
nospace:
push dword nspmsg
call printf
jmp retfa ; exit program with failure
;;; Print the list with head pointed to by ebx
printl:
cmp ebx,0x0
je .done ; empty list passed
mov eax,0x0 ; zero register so that after next eax contains value
mov ax,[ebx+node.value]
call prteax
mov ebx,[ebx+node.next]
jmp printl
.done: ret
;;; Print the value of eax.
prteax: push eax
push dword msg
call printf
pop eax ; remove arguments from stack
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .data
nonodes equ 0x100 ; max number of nodes
onens equ 0x8 ; space per node (_one_ _n_ode _s_pace)
maxnode equ nodesp+((nonodes-1) * onens)+1
msg db `val: %x\n`, 0x0
nspmsg db `No space left for nodes\n`, 0x0
lista dd 0x0 ; pointer to list a
listb dd 0x0 ; pointer to list b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; According to the Linux Standard Base all memory reserverd is init to zero
section .bss
nodesp: resd nonodes*3 ; reserve space for the nodes
tempa: resd 1
tempb: resd 1
tempc: resd 1
tempn: resd 1
list1: resd 1
list2: resd 1