;****************************************************************************
; Filename: RESIZE.ASM
; Author: Peter Andersson
; Version: 0.0
; Created: 1995.01.26
; Updated: -
;****************************************************************************
; Copyright Peter Andersson, 1994-1995.
; All rights reserved.
;****************************************************************************
; Function: PVOID @resize(PVOID blockptr,ULONG blocksize);
; Input: Eax, blockptr - pointer to the block to be resized
; Edx, blocksize - new size of the block
; Output: pointer to resized block or NULL if it failed
; Comment: @resize tries to resize a previously allocated block. If it
; fails you must allocate a new block and copy the block to the
; new block. OBSERVE: The new block size can't be zero, use
; @free to release a block!
;****************************************************************************
Include STDDEF.INC
Include "MEMORY.INC"
Codeseg
Proc resize ,2
TestZ Eax ; Do not allow any NULL pointers...
Jz @@Exit01
TestZ Edx ; ...and do not allow any zero length requests
Jz @@Exit01
Push Ebx
Lea Ebx,[Eax-Size AllocBlock]
Cmp [Ebx+AllocBlock.Ident],ALLOCID ; Check the allocation block identifier
Jne @@Exit02
Adjust Edx,MEMALIGN ; Align the request length
Add Edx,Size AllocBlock ; Add the block header size to the AllocBlock
Mov Ecx,[Ebx+AllocBlock.BlockSize] ; Get the current block size
Sub Edx,Ecx ; and check if it is big enough
Ja @@Next01 ; Jump if too small
Neg Edx
Cmp Edx,Size FreeBlock+MINBLOCK ; Check if it can be split?
Jb @@Next02 ; Jump if can't be split
Add Ecx,Ebx ; Get the next block
Cmp [Ecx+AllocBlock.Ident],ALLOCID ; Check if the next block is allocated
Je @@Next03 ; Jump if it is allocated
Mov Eax,[Ecx+FreeBlock.NextFree] ; Remove the block from the free list
Mov Ebx,[Ecx+FreeBlock.PrevFree]
Mov [Eax+FreeBlock.PrevFree],Ebx
Mov [Ebx+FreeBlock.NextFree],Eax
Mov Ebx,[Ecx+FreeBlock.PrevBlock]
Mov Eax,[Ebx+AllocBlock.BlockSize]
Mov Ecx,[Ecx+FreeBlock.BlockSize]
Sub Eax,Edx
Add Ecx,Edx
Jmp @@Next04
Align 4
@@Next03: Mov Eax,[Ebx+FreeBlock.BlockSize]
Sub Eax,Edx
Mov Ecx,Edx
@@Next04: Mov [Ebx+AllocBlock.BlockSize],Eax
Add Eax,Ebx
Mov [Eax+FreeBlock.PrevBlock],Ebx
Mov [Eax+Ecx+AllocBlock.PrevBlock],Eax
Mov [Eax+FreeBlock.BlockSize],Ecx ; Fix header
GetSize Edx,Ecx
Mov Ecx,[Edx+FreeBlock.NextFree] ; Add it to the free list
Mov [Edx+FreeBlock.NextFree],Eax
Mov [Eax+FreeBlock.PrevFree],Edx
Mov [Eax+FreeBlock.NextFree],Ecx
Mov [Ecx+FreeBlock.PrevFree],Eax
@@Next02: Lea Eax,[Ebx+Size AllocBlock]
Pop Ebx
Ret
Align 4
@@Next01: Add Ecx,Ebx
Cmp [Ecx+AllocBlock.Ident],ALLOCID ; Check the next block's identifier
Je @@Exit02 ; Jump if it is allocated
Cmp Edx,[Ecx+AllocBlock.BlockSize] ; Check the free block's size
Jb @@Exit02 ; Jump if the block wasn't big enough
Mov Ebx,[Ecx+FreeBlock.NextFree] ; Remove the block from the free list
Mov Eax,[Ecx+FreeBlock.PrevFree]
Mov [Ebx+FreeBlock.PrevFree],Eax
Mov [Eax+FreeBlock.NextFree],Ebx
Mov Ebx,[Ecx+FreeBlock.PrevBlock]
Mov Ecx,[Ecx+FreeBlock.BlockSize]
Mov Eax,[Ebx+AllocBlock.BlockSize]
Add Eax,Edx
Sub Ecx,Edx
Jmp @@Next04
Align 4
@@Exit02: Clear Eax
Pop Ebx
@@Exit01: Ret
Endp
End