Task

Show how to explicitly allocate and deallocate blocks of memory in your language.

Show access to different types of memory (i.e., heap, stack, shared, foreign) if applicable.




 
; linux x86_64
 
struc block
free: resb 1 ; whether or not this block is free
size: resb 2 ; size of the chunk of memory
next: resb 8 ; the next chunk after this one
mem:
endstruc
 
section .data
hStart: dq 0 ; the beginning of our heap space
break: dq 0 ; the current end of our heap space
 
 
section .text
 
Allocate:
 
  push rdi ; save the size argument
 
  cmp qword [break], 0 ; if breakpoint is zero this
  je firstAlloc        ; is the first call to allocate
 
  mov rdi, qword [hStart] ; else address of heap start
 
  findBlock: ; look for a suitable block of memory
 
    cmp byte [rdi + free], 2
    je newBlock ; end of heap reached, create new block
 
    cmp byte [rdi + free], 0
    je skipBlock ; this block taken
 
    ; this block is free, make
    ; sure it's big enough
    mov bx, word [rdi + size] 
    mov rcx, qword [rsp] ; compare against our size arg
    cmp cx, bx
    jg skipBlock ; keep looking if not big enough
 
    mov byte [rdi + free], 0 ; else mark as taken
    add rdi, mem
    add rsp, 8 ; discard size arg, we didn't need it
    mov rax, rdi ; return pointer to this block
    ret
 
    skipBlock:
      mov rsi, qword [rdi + next] ; load next
      mov rdi, rsi                ' block address
      jmp findBlock
 
    newBlock:
      mov rax, rdi
      add rdi, 1024
      cmp rdi, qword [break]
      jl initAndAllocate
      push rax
      mov rdi, qword [break] ; if we are getting low on
      add rdi, 4096          ; heap space, we ask OS for
      mov rax, 12            ; more memory with brk syscall
      syscall
      cmp rax, qword [break] ; if breakpoint has not increased,
      je allocFail           ; then memory could not be allocated
      mov qword [break], rax 
      pop rax
      jmp initAndAllocate
 
 
  firstAlloc:    ; extra work has to be done on first
    mov rax, 12  ; call to this subroutine
    mov rdi, 0
    syscall
    mov qword [hStart], rax ; init heap start
    add rax, 4096
    mov rdi, rax
    mov rax, 12   ; get heap memory with sys brk
    syscall
    cmp rax, qword [hStart]
    je allocFail
    mov qword [break], rax
    mov rax, qword [hStart]
 
  initAndAllocate:
    mov byte [rax + free], 0  ; mark block free
    pop rdi ; pop size arg off stack
    mov word [rax + size], di ; mark it's size
    lea rsi, [rax + mem + rdi]
    mov byte [rsi + free], 2 ; mark heap end block
    mov qword [rax + next], rsi ; mark next block
    add rax, mem ; return pointer to block's memory space
    ret
 
allocFail: ; exit(1) when allocation fails
  mov rax, 60
  mov rdi, 1
  syscall
  ret
 
; free this block so it can be
; reused in a subsequent call to allocate
Release:
  sub rdi, mem
  mov byte [rdi + free], 1
  ret
 
 