1 ;----------------------------------------------------------;
2 ; BOS kernel Christoffer Bubach, 2003-2005. ;
3 ;----------------------------------------------------------;
5 ; functions to allocate/free mem. ;
7 ;----------------------------------------------------------;
18 ;------------------------------------------------------;
20 ; in: ebx = first free memory ;
21 ; ecx = total memory size ;
22 ;------------------------------------------------------;
31 mov ecx, [prev_pointer]
35 mov ecx, [next_pointer]
43 ;------------------------------------------------------;
45 ; in: ebx = wanted size in bytes ;
46 ; out: eax = 0 if failed ;
47 ; ebx = pointer to memory ;
48 ;------------------------------------------------------;
57 mov [prev_pointer], ecx
63 mov [next_pointer], ecx
69 mov eax, [next_pointer]
87 ;----------------------------------------------;
88 ; no other block exists; add new free block ;
89 ; with the reminding space as free, and move ;
90 ; "first free" to that block.. ;
91 ;----------------------------------------------;
92 mov ecx, eax ; move address to ecx and
93 add ecx, ebx ; add size. ecx=end requested
94 mov dword [ecx], 0 ; set new header's prev to 0
96 sub edx, ebx ; remaining space in edx
97 mov [ecx+4], edx ; save it to new header
98 mov dword [ecx+8], 0 ; no next pointer..
100 mov [first_free], ecx
101 mov ebx, eax ; eax is unchanged from loop
104 ;----------------------------------------------;
105 ; no next block exists, make a new header at ;
106 ; the end of the requested size with the ;
107 ; reminder of the free space, and update the ;
108 ; prev header's next pointer.. ;
109 ;----------------------------------------------;
111 mov ecx, eax ; move address to ecx and
112 add ecx, ebx ; add size. ecx=end requested
113 mov edx, [prev_pointer] ; set prev for new header
114 mov [ecx], edx ; set new header's prev to 0
116 sub edx, ebx ; remaining space in edx
117 mov [ecx+4], edx ; save it to new header
118 mov dword [ecx+8], 0 ; no next pointer..
120 mov [prev_pointer+8], ecx
121 mov ebx, eax ; eax is unchanged from loop
125 ;----------------------------------------------;
126 ; both next and previous blocks exists, make a ;
127 ; new header at the end of the requested size ;
128 ; with the reminder of the free space, move ;
129 ; data from next block to the new one but add ;
130 ; size so it gets right, then update all prev/ ;
131 ; next pointers for total 3 blocks.. puh.. ;
132 ;----------------------------------------------;
134 cmp [prev_pointer], 0
137 mov ecx, eax ; move address to ecx and
138 add ecx, ebx ; add size. ecx=end requested
139 mov edx, [prev_pointer] ; set prev for new header
140 mov [ecx], edx ; set new header's prev
143 mov ebx, [next_pointer+4]
144 add edx, ebx ; remaining space in edx
145 mov [ecx+4], edx ; save it to new header
146 mov edx, [next_pointer] ; address to next block
149 mov dword [edx], ecx ; update next-next's prev..
150 mov dword [ecx+8], edx ; address to next pointer.
152 mov [prev_pointer+8], ecx
153 mov ebx, eax ; eax is unchanged from loop
158 mov [prev_pointer+8], ecx
159 mov ebx, eax ; eax is unchanged from loop
163 ;----------------------------------------------;
164 ; we allocated the first free block, do the ;
165 ; same as above, except ignore the prev block ;
166 ; part, and move the "first free". ;
167 ;----------------------------------------------;
169 mov ecx, eax ; move address to ecx and
170 add ecx, ebx ; add size. ecx=end requested
171 mov dword [ecx], 0 ; set new header's prev to 0
174 mov ebx, [next_pointer+4]
175 add edx, ebx ; remaining space in edx
176 mov [ecx+4], edx ; save it to new header
177 mov edx, [next_pointer] ; address to next block
180 mov dword [edx], ecx ; update next-next's prev..
181 mov dword [ecx+8], edx ; address to next pointer.
183 mov [first_free], ecx ; zero and update first free.
184 mov ebx, eax ; eax is unchanged from loop
190 mov [prev_pointer+8], ecx
191 mov ebx, eax ; eax is unchanged from loop
195 ;-----------------------------------------;
196 ; requested == size ;
197 ; I prefered coding this one.. ;) ;
198 ;-----------------------------------------;
200 cmp [next_pointer], 0
202 cmp [prev_pointer], 0
203 jne .prev_but_no_next2
205 mov ebx, eax ; eax is unchanged from loop
209 mov dword [prev_pointer+8], 0
210 mov ebx, eax ; eax is unchanged from loop
214 cmp [prev_pointer], 0
215 je .next_but_no_prev2
216 mov ecx, [prev_pointer] ; update prev and next's
217 mov edx, [next_pointer] ; headers to bypass this
218 mov [ecx+8], edx ; chunk.
220 mov ebx, eax ; eax is unchanged from loop
224 mov ecx, [eax+8] ; get address of next header
225 mov dword [ecx], 0 ; set prev in next header to
226 mov [first_free], ecx ; zero and update first free.
227 mov ebx, eax ; eax is unchanged from loop
237 ;------------------------------------------------------;
239 ; in: ebx = pointer to mem ;
240 ; ecx = size in bytes ;
241 ;------------------------------------------------------;
248 cmp ebx, [first_free]
253 ;-----------------------------------------------------------;
254 ; the block we want to free is somewhere in between ;
255 ; two other free blocks or after the last free block. ;
256 ; search for the "ebx"-address, so we know where the new ;
257 ; prev/next pointers are, and then can check if we should ;
259 ;-----------------------------------------------------------;
260 mov eax, [first_free] ; "current" free block
261 mov edx, [eax+8] ; next free block
264 cmp edx, 0 ; check if the "next"
265 je .found_end_of_ram ; free exists..
267 cmp ebx, edx ; is ebx "below" edx?
268 jb .found_between ; found ebx in between
270 mov eax, edx ; update pointers for
271 mov edx, [eax+8] ; another loop.
274 ;------------------------------------------;
275 ; the block is between two other blocks ;
276 ;------------------------------------------;
278 mov [ebx], eax ; create header
282 mov [eax+8], ebx ; update prev header
283 mov [edx], ebx ; update next header
285 ; now check if we can merge blocks....
288 jne .merge_only_first
295 ; we can merge with both prev & next
296 mov ecx, [ebx+4] ; get size from "current"
297 add [eax+4], ecx ; and add it to "prev".
298 mov ecx, [edx+4] ; get size from "next"
299 add [eax+4], ecx ; and add it to "prev".
300 mov ecx, [edx+8] ; get the new next
301 mov [eax+8], ecx ; pointer, and store it.
310 mov ecx, [ebx+4] ; get size from "current"
311 add [eax+4], ecx ; and add it to "prev".
312 mov [edx], eax ; update prev and next
313 mov [eax+8], edx ; pointers for the two..
328 ;----------------------------------------------;
329 ; the block is after all existing free ones ;
330 ;----------------------------------------------;
332 mov [ebx], eax ; create header
336 mov [eax+8], ebx ; update prev header
338 ; now check if we can merge the blocks....
349 ;--------------------------------------------;
350 ; the block is before any other free ones ;
351 ;--------------------------------------------;
354 mov [ebx+4], ecx ; create the
355 mov edx, [first_free] ; new header
358 mov edx, ebx ; check if the
359 add edx, [ebx+4] ; first_free matches
360 cmp edx, [first_free] ; current pos + size?
361 je .merge_first_free ; if so, merge the two
363 cmp [first_free], 0 ; else check if
364 je .cont1 ; first_free exists
365 mov edx, [ebx+8] ; if it does, update
366 mov [edx], ebx ; it's prev pointer.
368 mov [first_free], ebx ; else/and set new
369 jmp .end ; first free and quit
371 .merge_first_free: ; merge the two first
372 mov edx, [ebx+8] ; add the size of the
373 mov ecx, [edx+4] ; second block to the
374 add [ebx+4], ecx ; new one.
375 mov ecx, [edx+8] ; get the next pointer
376 mov [ebx+8], ecx ; from the old block,
379 mov [ecx], ebx ; update this + next..
381 mov [first_free], ebx ; update first_free