Metropoli BBS
VIEWER: malloc.asm MODE: TEXT (ASCII)
;****************************************************************************
; Filename: MALLOC.ASM
;   Author: Peter Andersson
;  Version: 0.0
;  Created: 1994.12.25
;  Updated: -
;****************************************************************************
; Copyright Peter Andersson, 1994-1995.
; All rights reserved.
;****************************************************************************
; Function: PVOID @malloc(ULONG blocksize);
;    Input: Eax, blocksize - size of block to allocate
;   Output: pointer to the allocated memory or NULL
;  Comment: PALallocate allocates a memory block from the global heap memory.
;           It returns a pointer to the allocated memory block or NULL if not
;           enough memory is available.
;****************************************************************************

        Include STDDEF.INC
        Include "MEMORY.INC"

        Codeseg

Proc    malloc ,1
                TestZ   Eax                                                     ; If zero size is requested then exit
                Jz      @@Exit01
                Push    Ebx
                Add     Eax,Size AllocBlock                                     ; Add the header size
                Adjust  Eax,MEMALIGN                                            ; Align the requested block size
                GetSize Edx,Eax
@@Next01:       Mov     Ebx,[Edx+FreeBlock.NextFree]                            ; Get the bit block pointer
                Mov     Ecx,[Ebx+FreeBlock.BlockSize]                           ; Get the block size
                Jecxz   @@Next03                                                ; If the block size is zero then abort the loop
                Sub     Ecx,Eax                                                 ; Check the block size and
                Jae     @@Next06                                                ; jump if it's big enough
@@Next02:       Mov     Ebx,[Ebx+FreeBlock.NextFree]                            ; Get the next free pointer
                Mov     Ecx,[Ebx+FreeBlock.BlockSize]                           ; Get the block size
                Jecxz   @@Next03                                                ; If the block size is zero then abort loop
                Sub     Ecx,Eax                                                 ; Check the block size and
                Jae     @@Next06                                                ; jump if it's big enough
                Mov     Ebx,[Ebx+FreeBlock.NextFree]                            ; Get the next free pointer
                Mov     Ecx,[Ebx+FreeBlock.BlockSize]                           ; Get the block size
                Jecxz   @@Next03                                                ; If the block size is zero then abort loop
                Sub     Ecx,Eax                                                 ; Check the size and
                Jb      @@Next02                                                ; don't jump if it's big enough
                Jmp     @@Next06
        Align   4
@@Next03:       Add     Edx,Size FreeBlock                                      ; Get next pointer from the free pointer list
                Cmp     Edx,Offset BlockTableEnd                                ; Reached the end?
                Jne     @@Next01                                                ; No, jump and do another lap
                Pop     Ebx
                Clear   Eax                                                     ; Return a NULL pointer
                Ret
        Align   4
@@Next06:       Cmp     Ecx,Size FreeBlock+MEMALIGN                             ; Jump if it can can't split the block
                Jb      @@Next08
                Mov     [Ebx+AllocBlock.BlockSize],Eax                          ; Store the new block size
                Add     Eax,Ebx                                                 ; Calculate a new pointer to the free block
                Mov     Edx,[Ebx+FreeBlock.NextFree]                            ; Save the old NextFree pointer
                Mov     [Eax+FreeBlock.BlockSize],Ecx                           ; Fix the free header
                Mov     [Eax+FreeBlock.PrevBlock],Ebx                           ; Make the free header
                Add     Ecx,Eax                                                 ; Get pointer to the next block
                Mov     [Ecx+AllocBlock.PrevBlock],Eax
                Mov     Ecx,[Ebx+FreeBlock.PrevFree]
                Mov     [Edx+FreeBlock.PrevFree],Ecx
                Mov     [Ecx+FreeBlock.NextFree],Edx
                Mov     Ecx,[Eax+FreeBlock.BlockSize]
                GetSize Edx,Ecx
                Mov     Ecx,[Edx+FreeBlock.NextFree]                            ; Get the old pointer and insert it into
                Mov     [Eax+FreeBlock.PrevFree],Edx                            ; the new free block list
                Mov     [Ecx+FreeBlock.PrevFree],Eax
                Mov     [Ebx+AllocBlock.Ident],ALLOCID                          ; Mark the block as allocated
                Mov     [Edx+FreeBlock.NextFree],Eax
                Mov     [Eax+FreeBlock.NextFree],Ecx
                Lea     Eax,[Ebx+Size AllocBlock]                               ; Return pointer to to the allocated block
                Pop     Ebx
                Ret
        Align   4
@@Next08:       Mov     Ecx,[Ebx+FreeBlock.NextFree]                            ; Remove block from the free pointer list
                Mov     Edx,[Ebx+FreeBlock.PrevFree]
                Mov     [Ebx+AllocBlock.Ident],ALLOCID                          ; Mark the block as allocated
                Mov     [Edx+FreeBlock.PrevFree],Ecx
                Mov     [Ecx+FreeBlock.NextFree],Edx
                Lea     Eax,[Ebx+Size AllocBlock]                               ; Return pointer to the allocated block
                Pop     Ebx
@@Exit01:       Ret
Endp

        End

[ RETURN TO DIRECTORY ]