rdos/kernel/heap.asm

85 lines
1.4 KiB
NASM

heap_size:
; 1 step here means 1 byte heap alloc table + 16 byte heap data
; 0x0400 = 1kB table, 16kb data
dw 0x0400
heap_init:
push ax ; byte value (0)
push cx ; loop counter
push di ; target ptr
push es
mov ax, cs
mov es, ax
xor ax, ax
mov cx, [heap_size]
mov di, heap
rep stosb ; rep makes this loop cx times, incrementing di, writing al
pop es
pop di
pop cx
pop ax
ret
; in ax number of bytes to alloc
; out ds:di
malloc:
push cx ; number of blocks to allocate
push bp ; base offset for block table
push es
; transfer 12 MSB from ax to cx
add ax, 0x000F
mov cl, 0x04
shr ax, cl
mov cx, ax
mov bp, heap
mov di, 0x0000
mov ax, ds
mov es, ax
xor ah, ah ; we use ax for reading from al once
jmp .firstblock
.testlength:
push cx
push di
add di, bp ; scasb doesn't add bp on its own
repe scasb
pop di
pop cx
je .found
; find next free item
mov al, 0x01
.nextblock:
add di, ax
.firstblock:
mov al, [bp+di]
cmp al, 0x00
jne .nextblock
cmp cx, 0x0001 ; fast case: 1 block allocation, skip test if length fits
jne .testlength
.found:
mov [bp+di], cl
mov cl, 0x04
shl di, cl
add di, bp
add di, [heap_size]
pop es
pop bp
pop cx
ret
; in ds:di begin of data block to free (di trashed)
free:
push cx
push bp
mov bp, heap
sub di, [heap_size]
sub di, bp
mov cl, 0x04
shr di, cl
mov byte [bp+di], 0x00
pop bp
pop cx
ret