flat assembler
Message board for the users of flat assembler.

Index > OS Construction > memory allocation tricks.

Author
Thread Post new topic Reply to topic
me239



Joined: 06 Jan 2011
Posts: 200
me239
Ok, so I finally understand the fat12 system fine. Now I need to work on memory allocation. I was looking Bootprog and I saw it loaded high in the ram and reserved space for the fat tables and root directory. Does anyone have any examples on some memory access tricks.
Post 14 Jun 2011, 23:49
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 559
smiddy
Here's something I write a few years ago, enjoy:

Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AssignMemory - Assigns memory based on request.
;;                The details of which haven't been worked out. Currently this
;;                displays memory available based on the bitmap. When fully
;;                functioning it will have an algorythm encompassing both the
;;                bitmap and the memory information table above the bitmap.
;;
;;                This function currently only displays available memory from
;;                the bitmap. Will travers both bitmap and memory info to
;;                arbitrate needs for requests.
;;
;; X DONE X       Need to fix assignment of block with enough and over flowing
;;                the next block.
;;
;;                Make a table that will hold the handles and their respective
;;                locations.
;;
;; Input:   EAX = Size of memory requested
;;          EBX = Pointer to text to be placed in memory description
;;
;; Output:  EAX = The handle of the memory being used (0 if no memory)
;;          EBX = Starting location of memory block requested
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MemoryNeeded            dd 0
ApplicationInformation  dd 0
ReturnHandle            dd 0
TheSize                 dd 0
OldSize                 dd 0
HandlesGiven            dd 0                ; Initially no handles given

AssignMemory:

    push ecx
    push edx
    push esi

    mov [MemoryNeeded],eax                  ; Save blocks requested
    mov [ApplicationInformation],ebx        ; Save offset of string containing application information

        mov eax,dword ADDRESS_MEMORY_INFO
        add eax,OSDA_LINEAR
        push es
        mov bx,08h                                              ; Save linear segment
        mov es,bx
    mov ebx,[es:eax]
    mov eax,0

.MainLoop:

    mov al,[es:ebx + 12]                       ;Get type of memory (need free)
    cmp al,1
    je .CheckSize
    add ebx,dword MEMORY_INFO_STRUCTURE_SIZE
    mov eax,[es:ebx + 4]                       ; Save ending memory address of this chunk
    cmp eax,0ffffffffh                      ; Is it at the top of memory?
    je .ErrorNoFreeRAM                      ; Yes, jump to the error
    jmp .MainLoop
    
.CheckSize:

    mov eax,[MemoryNeeded]                  ; Find amount of memory needed (I can optimize this a bit)
    cmp eax,[es:ebx + 8]                       ; Check the size of this free area
    jb .AssignIt1                            ; If below or equal, give it up.
    je .AssignIt2
    add ebx,dword MEMORY_INFO_STRUCTURE_SIZE
    mov eax,[es:ebx + 4]                       ; Save ending memory address of this chunk
    cmp eax,0ffffffffh                      ; Is it at the top of memory?
    je .ErrorNoFreeRAM                      ; Yes, jump to the error
    jmp .MainLoop
    
.AssignIt1:

    inc dword [HandlesGiven]                ; Increment handles given out...
    push ebx                                ; Store current record pointer
    mov ebx,[HandlesGiven]                  ; Save new handle into EBX
    mov [ReturnHandle],ebx                  ; Save hande give into ReturnHandle
    pop ebx                                 ; Restore current record pointer
    mov ecx,[ReturnHandle]                  ; Put the return handle into ECX
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE - 4],ecx  ; Save handle to current record
    call InsertMemoryInformation            ; Insert >> Should insert one record and move the rest up one

    mov eax,[MemoryNeeded]
    mov [es:ebx + 8],eax                       ; Save assigned request size into structure
    add eax,[es:ebx]                           ; Add size to starting address
    sub eax,1                               ; Subtract 1 from it 
    mov [es:ebx + 4],eax                       ; Save ending address
    inc eax                                 ; Add 1
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE],eax  ; Save new address of original 
    mov [es:ebx + 12],byte 2                   ; Mark memory area as being used
    push ebx
    add ebx,13                              ; Increment EBX to string save area
    mov edx,100                             ; Tell procedure the string size
    mov esi,[ApplicationInformation]        ; Save the ApplicationInformation pointer in ESI
    call CopyStringZeroFill32               ; Copy and zero fill
    pop ebx
    add ebx,dword MEMORY_INFO_STRUCTURE_SIZE    ; Increment EBX to old record
    mov eax,[MemoryNeeded]
    mov [TheSize],eax
    mov eax,[es:ebx + 8]                       ; Get original size
    sub eax,[TheSize]                       ; Subtract the new size from the old one
    mov [es:ebx + 8],eax                       ; Save the new original
    mov eax,[ReturnHandle]
    jmp .Done
    
.AssignIt2:

    inc dword [HandlesGiven]
    push ebx
    mov ebx,[HandlesGiven]
    mov [ReturnHandle],ebx                  ; Give up the handle into Memory Information Structure
    pop ebx
    mov ecx,[ReturnHandle]
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE - 4],ecx  ; Save handle to structure
    
    mov [es:ebx + 12],byte 2                   ; Mark memory area as being used
    add ebx,13                              ; Increment EBX to string save area
    mov edx,100                             ; Tell procedure the string size
    mov esi,[ApplicationInformation]        ; Save the ApplicationInformation pointer in ESI
    call CopyStringZeroFill32               ; Copy and zero fill
    
    mov eax,[ReturnHandle]
    sub ebx,13
    mov ecx,[es:ebx]
    mov ebx,ecx                             ; Return starting address of block
    jmp .Done

.ErrorNoFreeRAM:

    mov eax,0
    
.Done:

        pop es
    pop esi
    pop edx
    pop ecx
    
    ret
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GetFreeBitMap - Subfunction to AssignMemory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GetFreeBitMap:
    
    mov eax,0
    mov ebx,ADDRESS_MEMORY_MAP_OFFSET
    mov ecx,[ebx]
    mov ebx,ecx
    add ecx,262144
    
.LoopToPoop:

    cmp byte [ebx],0FFh
    jne .AddThem
    jmp .MoveOn

.AddThem:

    mov dl,byte [ebx]
    mov dh,dl
    cmp dl,0
    je .AddAll
    and dh,11000000b
    cmp dh,0
    ja .Next1
    add eax,4096
    
.Next1:
    
    mov dh,dl
    and dh,00110000b
    cmp dh,0
    ja .Next2
    add eax,4096
    
.Next2:

    mov dh,dl
    and dh,00001100b
    cmp dh,0
    ja .Next3
    add eax,4096

.Next3:

    mov dh,dl
    and dh,00000011b
    cmp dh,0
    ja .MoveOn
    add eax,4096
    jmp .MoveOn

.AddAll:

    add eax,16384
    
.MoveOn:
    
    inc ebx
    cmp ebx,ecx
    ja .Done
    jmp .LoopToPoop
    
.Done:
    
    call ToDecimal32
    call AddCommas32

    mov esi,AmountFreeMessage
    call PrintString32

    mov esi,CommaBuffer32
    call PrintString32
    
    mov esi,AmountBytes
    call PrintString32

    ret
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; InsertMemoryInformation - Subfunction to AssignMemory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SaveEBXPlace    dd 0
    
InsertMemoryInformation:

    push eax
    push ebx
    push ecx
    push edx
    
    mov [SaveEBXPlace],ebx              ; Save current location pointing to

.MainLoop:

    add ebx,dword MEMORY_INFO_STRUCTURE_SIZE    ; Got to next record
    mov eax,[es:ebx + 4]                   ; Save ending Address of this record
    cmp eax,0ffffffffh                  ; Is this the last record?
    je .StartCopy                       ; Yes, goto .StartCopy
    jmp .MainLoop                       ; Nope, goto next record
    
.StartCopy:

    mov ecx,0                           ; Zero counter
    
.CopyLoop:

    mov dl,[es:ebx + ecx]                  ; Copy byte from current record
    mov [es:ebx + ecx + MEMORY_INFO_STRUCTURE_SIZE],dl ; Copy bytes to next record
    inc ecx                             ; Increment to next byte
    cmp ecx,dword MEMORY_INFO_STRUCTURE_SIZE    ; Are we done with this record?
    je .DoNext                          ; Yes, goto DoNext
    jmp .CopyLoop                       ; Nope, continue loop
    
.DoNext:

    sub ebx,dword MEMORY_INFO_STRUCTURE_SIZE    ; Backup one record
    cmp ebx,[SaveEBXPlace]              ; Is this new record below where inserted?
    jb .Done                            ; Yes, goto .Done
    jmp .StartCopy                      ; No, goto .StartCopy
    
.Done:

    pop edx
    pop ecx
    pop ebx
    pop eax
    
    ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; CopyStringZeroFill32 - copies entire string and zero; if zero is before size
;;                      then it will fill the rest with zeros.
;;
;; Needs:   ebx = base address to place string
;;          edx = size of string to copy
;;          esi = base address of string
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CopyStringZeroFill32:

    push eax
    push ebx
    push ecx
    push edx
    push esi
    
    push es
    mov ax,08h
    mov es,ax
    
    mov ecx,0           ; Zero counter
    
.CopyString:

    cmp ecx,edx         ; See if they are the same
    je .Done
    mov al,[esi]
    mov [es:ebx + ecx],al
    inc esi
    inc ecx
    cmp al,0
    jne .CopyString
    jmp .ZeroFill
    
.ZeroFill:

    cmp ecx,edx
    je .Done
    mov [es:ebx + ecx],byte 0
    inc ecx
    jmp .ZeroFill
    
.Done:

        pop es
    pop esi
    pop edx
    pop ecx
    pop ebx
    pop eax
    
    ret
        
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; UnAssignMemory - Removes a previously assigned memory.
;;
;; This needs to be reaccomplishd to find the handle of the memory to release
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

HandleToRemove          dd 0
MemoryRemoved           dd 0
NeedToCheckAgain        db 0

UnAssignMemory:

    mov [HandleToRemove],eax
    mov [MemoryRemoved],ebx
        
        push es
        mov bx,08h                                              ; Save linear segment
        mov es,bx
        
    cmp eax,0                               ; Check for zero handle, can't be unassigned
    je .Done
    
.DoAgain:
    
    mov [NeedToCheckAgain],byte 0
    mov eax,dword ADDRESS_MEMORY_INFO
    add eax,OSDA_LINEAR

    mov ebx,[es:eax]
    mov eax,0

.MainLoop:

    mov eax,[es:ebx + MEMORY_INFO_STRUCTURE_SIZE - 4]; Get handle number
    cmp eax,[HandleToRemove]                ; Check for right handle
    je .CheckRecords                        ; If yes, check the previous record
    add ebx,dword MEMORY_INFO_STRUCTURE_SIZE; If no, put EBX to next record
    mov eax,[es:ebx + 4]                       ; Save ending memory address of this chunk
    cmp eax,0ffffffffh                      ; Is it at the top of memory?
    je .Done                                ; Yes, jump to the error
    jmp .MainLoop                           ; No, move on to the next record

.CheckRecords:

;    mov esi,UnAssignMemoryMessage          ; Here for DEBUG purposes.
;    call PrintString32
    
    mov dl,[es:ebx - MEMORY_INFO_STRUCTURE_SIZE + 12]  ; Save previous records type
    cmp dl,1                                ; Is it a free record?
    je .MoveEBXBack                         ; Yes, then move EBX back one record
    mov dl,[es:ebx + MEMORY_INFO_STRUCTURE_SIZE + 12]  ; Save next records type
    cmp dl,2                                ; Is next record a assigned memory area?
    je .JustFreeBlock                       ; Yes, then goto .JustFreeBlock
    cmp dl,1                                ; Is next record a unassigned memory area?
    je .CombineNextRecord                   ; Yes, goto .CombineNextRecord

    jmp .Done
    
.MoveEBXBack:

    sub ebx,MEMORY_INFO_STRUCTURE_SIZE  ; Put EBX back one record, then combine records
    mov [NeedToCheckAgain],byte 1       ; Have to check record after block too

.CombineNextRecord:

    mov ecx,[es:ebx + 8]               ; Get current record's size
    add ecx,[es:ebx + MEMORY_INFO_STRUCTURE_SIZE + 8] ; Add record's both sizes together
    mov [es:ebx + 8],ecx               ; Save new size in current record
    add ecx,[es:ebx]                   ; Add starting address to size for next address
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE],ecx ; Save start of next record (that is combined)
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE + 4],ecx ; Save ending of next record (make it the same)
    dec ecx                         ; Subtract 1 from starting from next record for ending address this record
    mov [es:ebx + 4],ecx               ; Save ending address of this record
    mov [es:ebx + 12],byte 1           ; Update this record as Free
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE + 12],byte 2  ; Next record is no longer free
    mov [es:ebx + MEMORY_INFO_STRUCTURE_SIZE + 8],dword 0  ; Next record size is now zero

    push ebx                        ; Save record location
    add ebx,13                      ; Move location to string save area in record
    mov edx,100                     ; String record size
    mov esi,FREEString32            ; Pointer to free string in ESI
    call CopyStringZeroFill32       ; Copy free string into this record
    pop ebx                         ; Restore current record pointer
    
.CopyRecord:

    mov ecx,0                       ; Zero out ECX for counting
    add ebx,MEMORY_INFO_STRUCTURE_SIZE  ; Move to the next record (where to copy to)

.InnerLoop:

    mov al,[es:ebx + ecx + MEMORY_INFO_STRUCTURE_SIZE] ; Get next-next record one byte at a time to next record
    mov [es:ebx + ecx],al              ; Save byte into next record from next-next record
    cmp ecx,MEMORY_INFO_STRUCTURE_SIZE  ; Have we hit the limit on the record?
    je .OuterLoop                   ; Yes, go to outer loop
    inc ecx                         ; Increment the ECX counter
    jmp .InnerLoop                  ; And continue saving bytes
    
.OuterLoop:
    
    mov eax,[es:ebx + 4]               ; Save ending address in EAX
    cmp eax,0ffffffffh              ; Is it the end of addressable memory?
    je .Done                        ; Yes, we're done
    jmp .CopyRecord                 ; Nope, do another record.

.JustFreeBlock:

    mov [es:ebx + 12],byte 1           ; Update record type to free
    add ebx,13                      ; Move EBX to where string storage occurs in record
    mov edx,100                     ; Save size of field in EDX
    mov esi,FREEString32            ; Save pointer to Free Memory String
    call CopyStringZeroFill32       ; Place string in data field
    
.Done:

    mov al,[NeedToCheckAgain]       ; Move variable into AL
    cmp al,1                        ; Do we need to check again?
    je .DoAgain                     ; Yes, do it again
    
    pop es
    
    ret                  
    


There is quite a bit that is cryptic, so ask away. Also, this was meant for 32-bit flat model (no paging).
Post 31 Oct 2011, 03:04
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.