📄 memcode.inc
字号:
CALL AddRun ;Does not return error
;EAX still has new linear address
MOV EBX, ppMemRet ;Get address of caller's pointer
MOV [EBX], EAX ;Give em new LinAdd
XOR EAX, EAX ;No error
ALOSPExit: ;
PUSH EAX ;Save last error
PUSH MemExch ;Send a Semaphore msg (so next guy can get in)
PUSH 0FFFFFFF1h ;
PUSH 0FFFFFFF1h ;
CALL FAR PTR _SendMsg ;
POP EAX ;Get original error back (ignore kernel erc)
MOV ESP,EBP ;
POP EBP ;
RETF 8 ;
_AllocOSPage ENDP
;=============================================================================
; AllocPage --
; This is identical to AllocOSPage except it's call gate is set to USER
; level and the PD base value is set to 3072. See the call description
; for AllocOSPage
_AllocPage PROC FAR ;
PUSH EBP ;
MOV EBP,ESP ;
PUSH MemExch ;Wait at the MemExch for Msg
MOV EAX, pRunTSS ;Put Msg in callers TSS Message Area
ADD EAX, TSS_Msg
PUSH EAX
CALL FAR PTR _WaitMsg
CMP EAX,0h ;Kernel Error??
JNE SHORT ALPExit ;Yes! Serious problem...
MOV EAX,n4KPages ;size of request
OR EAX,EAX ;More than 0?
JNZ ALP00 ;Yes
MOV EAX,ercBadMemReq ;Can't be zero!
JMP ALPExit ;
ALP00:
MOV EAX,n4KPages ;size of request
CMP EAX, _nPagesFree ;See if have enuf physical memory
JBE ALP01 ;Yes
MOV EAX, ErcNoMem ;Sorry boss, we're maxed out
JMP SHORT ALPExit
ALP01:
MOV EBX, EAX ;nPages
MOV EAX, 256 ;PD base for USER mem (needed by FindRun)
CALL FindRun
OR EAX, EAX ;(0 = No Runs big enuf)
JNZ SHORT ALP02 ;No Error!
CALL AddUserPT ;Add a new page table (we need it!)
OR EAX, EAX ; 0 = NO Error
JZ SHORT ALP01 ; Go back & try again
JMP SHORT ALPExit ; ERROR!!
ALP02:
CALL AddRun ;Does not return error
MOV EBX, ppMemRet ;Get address of caller's pointer
MOV [EBX], EAX ;Give em new LinAdd
XOR EAX, EAX ;No error
ALPExit: ;
PUSH EAX ;Save last error
PUSH MemExch ;Send a Semaphore msg (so next guy can get in)
PUSH 0FFFFFFF1h ;
PUSH 0FFFFFFF1h ;
CALL FAR PTR _SendMsg ;
POP EAX ;Get original error back (ignore kernel erc)
MOV ESP,EBP ;
POP EBP ;
RETF 8 ;
_AllocPage ENDP
;=============================================================================
; AliasMem --
; This creates alias pages in the current job's PD/PTs if the current
; PD is different than the PD for the job specified. This allows
; system services to access a caller memory for messaging WITHOUT having
; to move data around. The pages are create at USER protection level
; even if they are in OS memory space (a service installed in OS memory).
; Even if the address is only two bytes, if it crosses page boundries,
; we need two pages.
;
; STEPS:
; 1) See if the current PD = Specified Job PD. If so, Exit. (No alias needed).
; 2) Calculate how many entries (pages) will be needed.
; 3) See if they are available.
; 3) Make PTE entries and return alias address to caller.
;
; Procedureal Interface :
;
; AliasMem(pMem, dcbMem, dJobNum, ppAliasRet): dError
;
; pMem is the address to alias.
; dcbMem is the number of bytes needed for alias access.
; JobNum is the job number that pMem belongs to.
; ppAliasRet is the address to return the alias address to.
;
;
;pMem EQU [EBP+24] ;
;dcbMem EQU [EBP+20] ;
;JobNum EQU [EBP+16] ;
;ppAliasRet EQU [EBP+12] ;
_AliasMem PROC FAR ;
PUSH EBP ;
MOV EBP,ESP ;
CALL GetCrntJobNum ;Puts Current Job Num in EAX
MOV EBX, [EBP+16] ;Get Job number for pMem
CMP EAX, EBX ;Are they the same Page Directory??
JNE ALSPBegin ;No, alias it
XOR EAX, EAX ;Yes, No Error
JMP ALSPDone ;Exit, we're done
ALSPBegin:
;Now wait our turn with memory management
; PUSH MemExch ;Wait at the MemExch for Msg
; MOV EAX, pRunTSS ;Put Msg in callers TSS Message Area
; ADD EAX, TSS_Msg
; PUSH EAX
; CALL FAR PTR _WaitMsg
; CMP EAX,0h ;Kernel Error??
; JNE ALSPDone ;Yes! Serious problem...
; We're IN!
ALSP00:
MOV EBX, [EBP+24] ;pMem into EAX
AND EBX, 0FFFh ;MODULO 4096 (remainder)
MOV EAX, [EBP+20] ;dcbMem
ADD EAX, EBX ;Add the remainder of address
ADD EAX, DWORD PTR [EBP+20] ;Add to dcbMem
SHR EAX, 12 ;EAX is nPages-1
INC EAX ;EAX is now nPages we need!
MOV ECX, EAX ;Save nPages in ECX
;Now we find out whos memory we are in to make alias
;EAX is 256 for user space, 0 for OS
;EBX is number of pages for run
CALL GetCrntJobNum ;See if it is OS based service
CMP EAX, 1 ;OS Job?
JE SHORT ALSP011 ;Yes
MOV EAX, 256 ;No, User memory
JMP SHORT ALSP01
ALSP011:
XOR EAX, EAX ;Set up for OS memory space
ALSP01:
MOV EBX, ECX ;Number of pages we need into EBX
CALL FindRun ;EAX has 0 or 256
;EAX is now linear address or 0 if no run is large enough
;EBX still has count of pages
OR EAX, EAX ;Was there enough PTEs?
JNZ ALSP04 ;Yes
CALL GetCrntJobNum ;See if it is OS based service
CMP EAX, 1 ;OS Job?
JE SHORT ALSP03 ;Yes
CALL AddUserPT ;No! Add a new USER page table
JMP SHORT ALSP03
ALSP02:
CALL AddOSPT ;No! Add a new OS page table
ALSP03:
OR EAX, EAX ;0 = NO Error
JZ SHORT ALSP00 ;Go back & try again
JMP SHORT ALSPExit ;ERROR!!
ALSP04:
;EAX has linear address (from find run) Sve in EDI
;EBX still has number of pages to alias
;Set ESI to linear address of pages to alias (from other job)
;Set EDX job number of job we are aliasing
MOV EDI, EAX ;Save alias page address base
MOV ESI, [EBP+24] ;Address to alias
MOV EDX, [EBP+16] ;Job number
CALL AddAliasRun
;Now, take new alias mem and add trailing bits to address
;and return to caller so he knows address (EDI is lin add)
MOV EAX, [EBP+24] ;original pMem
AND EAX, 0FFFh ;Get remaining bits
ADD EDI, EAX
MOV ESI, [EBP+12] ;pAliasRet
MOV [ESI], EDI ;Returned address to caller!
XOR EAX, EAX ;Set to 0 (no error)
;We are done
ALSPExit: ;
; PUSH EAX ;Save last error
; PUSH MemExch ;Send a Semaphore msg (so next guy can get in)
; PUSH 0FFFFFFF1h ;
; PUSH 0FFFFFFF1h ;
; CALL FAR PTR _SendMsg ;
; POP EAX ;Get original error back (ignore kernel erc)
ALSPDone:
MOV ESP,EBP ;
POP EBP ;
RETF 16 ;
_AliasMem ENDP
;=============================================================================
; DeAliasMem --
;
; Procedureal Interface :
;
; DeAliasMem(pAliasMem, dcbAliasBytes, JobNum):ercType
;
; pAliasMem is the address which was given to you from the AliasMem call.
; This zeros out the page entries that were made during the AliasMem
; call. We do not need to go through the OS MEM semaphore exchange
; because we are only zeroing out PTE's one at a time. This
; WOULD NOT interfere with any memory allocation routines.
;
; pAliasMem is the address to DeAlias
; dcbAliasBytes is the size of the original memory aliased
;
;pAliasMem EQU [EBP+20]
;dcbAliasBytes EQU [EBP+16]
;AliasJobNum EQU [EBP+12]
_DeAliasMem PROC FAR ;
PUSH EBP ;
MOV EBP,ESP ;
;Calculate the number of pages to DeAlias
MOV EBX, [EBP+20] ;pMem into EAX
AND EBX, 0FFFh ;MODULO 4096 (remainder)
MOV EAX, [EBP+16] ;dcbMem
ADD EAX, EBX ;Add the remainder of address
ADD EAX, DWORD PTR [EBP+20] ;Add to dcbMem
SHR EAX, 12 ;EAX is nPages-1
INC EAX ;EAX is now nPages we need!
MOV ECX, EAX ;Number of pages into EDI & ECX
MOV EDI,ECX ;Save also in EDI (for compare)
MOV EDX, [EBP+20] ;Linear Mem to DeAlias
DALM01:
MOV EBX, EDX ;Address of next page to deallocate
MOV EAX, [EBP+12] ;Job num into EAX for LinToPhy
CALL LinToPhy ;Call this to get address of PTE into ESI
;Now we have Physical Address in EAX (we don't really need it)
;and pointer to PTE in ESI (We NEEDED THIS).
;See if PTE is an alias, if so just ZERO PTE.
;DO NOT deallocate the physical page
MOV EBX, [ESI] ;Get PTE into EBX
TEST EBX, PRSNTBIT ;Is page present (valid)???
JNZ DALM02 ;Yes, it's page is present
CMP ECX, EDI ;NO! (did we do any at all)
JNE DALM011 ;We did some..
MOV EAX, ErcBadLinAdd ;None at all!
JMP SHORT DALMExit
DALM011:
MOV EAX, ErcBadAlias ;We dealiased what we could,
JMP SHORT DALMExit ;but less than you asked for!
DALM02:
TEST EBX, ALIASBIT ;Is page an ALIAS?
JZ DALM03 ;NO - DO not zero it!
;If we got here the page is presnt and IS an alias
;so we zero out the page.
XOR EAX, EAX ;
MOV [ESI], EAX ;ZERO PTE entry
DALM03:
ADD EDX, 4096 ;Next linear page
LOOP DALM01
;If we fall out EAX = ErcOK already
DALMExit:
MOV ESP,EBP ;
POP EBP ;
RETF 12 ;
_DeAliasMem ENDP
;=============================================================================
; DeAllocPage --
;
; Procedureal Interface :
;
; DeAllocPage(pOrigMem, n4KPages):ercType
;
; pOrigMem is a POINTER which should be point to memory page(s) to be
; deallocate. The lower 12 bits of the pointer is actually ignored
; because we deallocate 4K pages. This will free physical pages unless
; the page is marked as an alias. It will always free linear memory
; providing it is valid. Even if you specify more pages than are valid
; this will deallocate or dealias as much as it can before reaching
; an invalid page.
;
; n4KPages is the number of 4K pages to deallocate
;
pOrigMem EQU [EBP+10h]
n4KPagesD EQU [EBP+0Ch] ;
_DeAllocPage PROC FAR ;
PUSH EBP ;
MOV EBP,ESP ;
PUSH MemExch ;Wait at the MemExch for Msg
MOV EAX, pRunTSS ;Put Msg in callers TSS Message Area
ADD EAX, TSS_Msg
PUSH EAX
CALL FAR PTR _WaitMsg
CMP EAX,0h ;Error??
JNE DAMExit ;Yes!
MOV EDX, pOrigMem ;Linear Mem to deallocate
AND EDX, 0FFFFF000h ;Drop odd bits from address (MOD 4096)
MOV ECX, n4KPagesD ;Number of pages to deallocate
DAP01:
MOV EBX, EDX ;Address of next page to deallocate
CALL GetCrntJobNum ;Leave Job# in EAX for LinToPhy
CALL LinToPhy ;
;Now we have Physical Address in EAX
;and pointer to PTE in ESI.
;See if PTE is an alias, if so just ZERO PTE,
;else deallocate physical page THEN zero PTE
MOV EBX, [ESI] ;Get PTE into EBX
TEST EBX, PRSNTBIT ;Is page present (valid)???
JNZ DAP02 ;Yes, it's page is present
CMP ECX, n4KPagesD ;NO! (did we do any at all)
JNE DAP011 ;We did some..
MOV EAX, ErcBadLinAdd ;None at all!
JMP SHORT DAMExit
DAP011:
MOV EAX, ErcShortMem ;We deallocated what we could,
JMP SHORT DAMExit ;but less than you asked for!
DAP02:
TEST EBX, ALIASBIT ;Is page an ALIAS?
JNZ DAP03 ;Yes, it's an Alias
;If we got here the page is presnt and NOT an alias
;so we must unmark (release) the physical page.
AND EBX, 0FFFFF000h ;get rid of OS bits
CALL UnMarkPage ;
DAP03:
XOR EAX, EAX ;
MOV [ESI], EAX ;ZERO PTE entry
ADD EDX, 4096 ;Next linear page
LOOP DAP01
;If we fall out EAX = ErcOK already
DAMExit:
PUSH EAX ;save Memory error
PUSH MemExch ;Send a dummy message to pick up
PUSH 0FFFFFFF1h ; so next guy can get in
PUSH 0FFFFFFF1h
CALL FAR PTR _SendMsg ;
CMP EAX, 0 ;Kernel error has priority
JNE DAMExit1 ; over memory error
POP EAX ;get Memory error back
DAMExit1:
MOV ESP,EBP ;
POP EBP ;
RETF 8 ;
_DeAllocPage ENDP
;=============================================================================
; QueryMemPages --
;
; Procedureal Interface :
;
; QueryMemPages(pdnPagesRet):ercType
;
; pdnPagesRet is a pointer where you want the count of pages
; left available returned
;
pMemleft EQU [EBP+0Ch]
_QueryPages PROC FAR ;
PUSH EBP ;
MOV EBP,ESP ;
MOV ESI, pMemLeft
MOV EAX, _nPagesFree
MOV [ESI], EAX
XOR EAX, EAX ;No Error
MOV ESP,EBP ;
POP EBP ;
RETF 4 ;
_QueryPages ENDP
;==============================================================================
;
; GetPhyAdd -- This returns the phyical address for a linear address
;
;
; Procedureal Interface :
;
; GetPhyAdd(JobNum, LinAdd, pPhyRet):ercType
;
; LinAdd is the Linear address you want the physical address for
; pPhyRet points to the unsigned long where Phyadd is returned
;
;
;JobNum EQU [EBP+20]
;LinAdd EQU [EBP+16]
;pPhyRet EQU [EBP+12]
;
_GetPhyAdd PROC FAR ;
PUSH EBP ;
MOV EBP,ESP ;
MOV EBX, [EBP+16] ; Linear Address
MOV EAX, [EBP+20] ; Job Number
CALL LinToPhy
MOV ESI, [EBP+12] ; pPhyRet
MOV [ESI], EAX ;
XOR EAX, EAX ; No Error
MOV ESP,EBP ;
POP EBP ;
RETF 12 ;
_GetPhyAdd ENDP
;==============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -