User:Johnburger/Demo/Exec/Alloc/RAM: Difference between revisions
From OSDev Wiki
< User:Johnburger | Demo
Jump to navigation
Jump to search
m (moved JohnBurger:Demo/Exec/Alloc/RAM to User:Johnburger/Demo/Exec/Alloc/RAM: Actually move this into the User's namespace)
m (Fix links to moved pages)
Line 9:
Line 9:
This does what it says: zeroes the passed-in number of bytes starting from the passed-in pointer.
This does what it says: zeroes the passed-in number of bytes starting from the passed-in pointer.
== <code>[[(削除) JohnBurger (削除ここまで):Demo/Demo|Demo]]/[[(削除) JohnBurger (削除ここまで):Demo/Exec/Exec|Exec]]/[[(削除) JohnBurger (削除ここまで):Demo/Exec/Alloc/Alloc|Alloc]]/RAM.inc</code> ==
== <code>[[(追記) User (追記ここまで):(追記) Johnburger/ (追記ここまで)Demo/Demo|Demo]]/[[(追記) User (追記ここまで):(追記) Johnburger/ (追記ここまで)Demo/Exec/Exec|Exec]]/[[(追記) User (追記ここまで):(追記) Johnburger/ (追記ここまで)Demo/Exec/Alloc/Alloc|Alloc]]/RAM.inc</code> ==
<source lang="asm">
<source lang="asm">
;
;
Latest revision as of 09:27, 29 August 2017
This module contains two functions:
Exec.Alloc.RAM
This function allocates the passed-in number of bytes, and returns its linear address. Note that this RAM is not yet accessible: you need a Descriptor for that! But at least you now have the Base and Size parameters to create one.
Please note that this is a naïve implementation: it merely adds the requested size to the current top of RAM, and returns the previous value. It is intelligent enough to jump the 640 kiB to 1 MiB device/ROM/BIOS hole, but it doesn't even know where the ultimate top of RAM is! That has been left as an exercise for the reader...
Exec.Alloc.RAM.Zero
This does what it says: zeroes the passed-in number of bytes starting from the passed-in pointer.
Demo/Exec/Alloc/RAM.inc
; ; Exec/Alloc/RAM.inc ; ; This module provides RAM-related functions, such as Allocating and Zeroing ; blocks of RAM. It could use the RAM Map discovered from the BIOS during Boot, ; but that's been left as an exercise for the reader! ; ; Instead, the allocator merely keeps track of the last allocated address as a ; "high water mark", returning zero if that mark becomes greater than what's ; available. Of course, this naïve implementation merely keeps giving more and ; more - with enough intelligence to skip from RAMTop to the 1 MiB mark. ;............................................................................... ; This function allocates a block of RAM from the available pool. ; Note that it doesn't allocate a Descriptor for it, since it doesn't know ; what type it'll be, nor which Table to put it in. ; ; Also note that this implementation is NOT thread-safe. It assumes that only ; one Task will ever be accessing it at the same time. To work around that, ; either some kind of lock will be required, or atomic operations such as used ; in the 80486 (such as XADD) should be used. ; ; Input: DS = Data ; ECX = Size requested ; Output: EAX = Address of allocated RAM, or zero if insufficient. ; ECX preserved Exec.Alloc.RAM: MOVEAX,[Data.RAM]; Get current high-water mark .Retry: LEAEDX,[EAX+ECX+0Fh]; Get Top, rounded to paragraph ANDEDX,~0Fh; Well, it is now! CMPEDX,[Data.RAMTop]; Too far? JBE.Save; Not yet... MOVEAX,0010_0000h; Skip to 1 MiB MOVDWORD[Data.RAMTop],-1; And pretend the rest is ours! JMP.Retry; And try again .Save: MOV[Data.RAM],EDX; Save new high-water mark .End: RET ;............................................................................... ; This function zeroes out the block of passed-in RAM. ; Input: ES = Segment to zero ; ECX = Size to zero ; EDI = Where to zero ; Output: ES and ECX preserved. ; EAX and EDI? Not so much! Exec.Alloc.RAM.Zero: PUSHECX; As promised... CLD; Work forwards XOREAX,EAX; Store zeroes SHRECX,2; Do DWORDs initially REPSTOSD; Zero out whole DWORDs at a time MOVECX,[ESP]; Recover saved value ANDECX,03h; Mask off DWORDs already done REPSTOSB; Make up any last bytes POPECX RET