flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > memory allocation tricks. |
Author |
|
smiddy 31 Oct 2011, 03:04
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). |
|||
31 Oct 2011, 03:04 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.