📄 memory.asm
字号:
jnz @@UseProposed
jmp @@8
;
@@80: cmp ecx,LinearBase
jnc @@80_0
mov ecx,LinearBase
sub ecx,4096
@@80_0: add ecx,4096
cmp ecx,LinearLimit ;End of memory map yet?
jc @@NoWrap
mov ecx,LinearBase
;
@@NoWrap: mov eax,ecx
shr eax,12 ;get page number.
test fs:d[edi+eax*4],1 ;this page present?
jz @@ScanLoop
test fs:d[ebp+eax*4],MEM_LOCK_MASK shl MEM_LOCK_SHIFT
jnz @@ScanLoop
;
inc CompareCount
;
;Check against recent stack.
;
pushm ecx,edi
mov eax,ecx
mov edi,offset RecentMapStack
mov ecx,PageStackSize
repnz scasd
popm ecx,edi
jz @@IsRecent
shr eax,12 ;get page number again.
test fs:d[edi+eax*4],1 shl 6
jz @@GotPage
;
cmp ProposedPresentFlag,0
jz @@SetProposed
cmp ProposedRecentFlag,0
jz @@UseProposed?
@@SetProposed: mov ProposedPresentFlag,-1
mov ProposedPage,ecx
mov CompareCount,0
mov ProposedRecentFlag,0
jmp @@ScanLoop
;
@@UseProposed?: mov eax,NoneLockedPages
shr eax,2
cmp eax,4096
jc @@UP0
mov eax,4096
@@UP0: cmp CompareCount,eax
jc @@UseProposed
jmp @@ScanLoop
;
@@IsRecent: cmp ProposedPresentFlag,0
jnz @@ProposedRecent?
mov ProposedPresentFlag,-1
mov ProposedPage,ecx
mov ProposedRecentFlag,-1
mov CompareCount,0
jmp @@ScanLoop
;
@@ProposedRecent?:
cmp ProposedRecentFlag,0
jnz @@LookedEnough?
mov eax,NoneLockedPages
shr eax,2
cmp eax,4096
jc @@PR0
mov eax,4096
@@PR0: cmp CompareCount,eax
jnc @@UseProposed
jmp @@ScanLoop
;
@@LookedEnough?:
mov eax,NoneLockedPages
cmp CompareCount,eax
jnc @@UseProposed
jmp @@ScanLoop
;
@@UseProposed: mov ecx,ProposedPage
;
@@GotPage: mov PageingPointer,ecx
;
mov eax,ecx
shr eax,12 ;get page number again.
shl eax,2
add edi,eax
;
;Check if it needs to go to the swap file.
;
test fs:d[edi],1 shl 6 ;is it dirty?
jz @@5 ;no need to write it if not.
;
;Flush this page to disk.
;
push edi
mov esi,BreakAddress
mov al,fs:[esi]
mov fs:b[esi],0
push eax
;
sub edi,1024*4096*1023 ;get page table entry number.
shr edi,2 ;page number.
shl edi,12 ;get linear address.
push edi
mov esi,edi
pushm ds,es
mov edi,PageBufferLinear ;copy it to somewhere we can deal with it.
mov ax,KernalZero
mov ds,ax
mov es,ax
mov ecx,4096/4
rep movsd
popm es,ds
pop edi
;
sub edi,LinearBase
mov ebp,edi
mov dx,di
shr edi,16
mov cx,di
mov ax,4200h
mov bx,VMMHandle
mov edi,offset PageInt
mov Real_EBX[edi],ebx
mov Real_EAX[edi],eax
mov Real_EDX[edi],edx
mov Real_ECX[edi],ecx
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
push ds
pop es
call EMURawSimulateInt ;move to right place.
;
test Real_Flags[edi],1
stc
jnz @@error_anyway
mov edx,Real_EDX[edi]
mov eax,Real_EAX[edi]
shl edx,16
mov dx,ax
cmp edx,ebp
jnz @@force_error
;
mov edi,offset PageInt
mov ax,VMMHandle
mov Real_EBX[edi],eax
mov ax,PageBufferReal
mov Real_DS[edi],ax
mov Real_EAX[edi],4000h
mov Real_EDX[edi],0
mov Real_ECX[edi],4096
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
call EMURawSimulateInt ;write it to disk.
test Real_Flags[edi],1
stc
jnz @@error_anyway
mov eax,Real_EAX[edi]
cmp ax,4096
jz @@error_anyway
@@force_error: stc
@@error_anyway: ;
mov esi,BreakAddress
pop eax
mov fs:[esi],al
;
pop edi
jc @@8
or fs:d[edi],1 shl 11 ;signal it living on disk.
;
@@5: ;Now remove it from the page table and exit.
;
and fs:d[edi],0FFFFFFFFh-1 ;mark as not present.
mov edx,fs:[edi] ;get page entry.
mov ecx,edx
and edx,0FFFFFFFFh-4095 ;lose flag bits.
shr ecx,10
and ecx,1 ;preserve user flags.
call EMUCR3Flush
;
;Update number of un-locked physical pages present.
;
dec NoneLockedPages
;
clc
jmp @@9
;
@@8: stc ;failed to find free page.
;
@@9: popm eax,ebx,esi,edi,ebp,ds,es,fs
ret
assume ds:_cwDPMIEMU
UnMapPhysical endp
;-------------------------------------------------------------------------------
;
;Lock page indicated.
;
;On Entry:-
;
;EAX - Linear address to lock.
;
RawLockPage proc near
pushm eax,ebx,esi,es
shr eax,12 ;get page number.
mov bx,KernalZero
mov es,bx
mov esi,1024*4096*1022 ;base of page DET's.
mov ebx,es:[esi+eax*4]
shr ebx,MEM_LOCK_SHIFT
and ebx,MEM_LOCK_MASK
jnz @@WasLocked
;
;Update number of un-locked physical pages present.
;
pushm ax,ds
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
dec NoneLockedPages
assume ds:_cwDPMIEMU
popm ax,ds
;
@@WasLocked: cmp ebx,MEM_LOCK_MASK
jz @@0
add es:d[esi+eax*4],1 shl MEM_LOCK_SHIFT ;lock it.
@@0: popm eax,ebx,esi,es
ret
RawLockPage endp
;-------------------------------------------------------------------------------
RawClearPageLock proc near
pushm eax,ebx,ecx,esi,es
mov bx,KernalZero
mov es,bx
shr eax,12
mov esi,1024*4096*1022 ;base of page alias's.
mov ebx,MEM_LOCK_MASK shl MEM_LOCK_SHIFT
xor ebx,-1
and es:d[esi+eax*4],ebx ;un-lock it.
popm eax,ebx,ecx,esi,es
ret
RawClearPageLock endp
;-------------------------------------------------------------------------------
;
;Un-lock a linear page.
;
;On Entry:-
;
;EAX - Linear address of page to unlock.
;
RawUnLockPage proc near
call RawPageLocked
jz @@9
pushm eax,ebx,esi,es
mov bx,KernalZero
mov es,bx
shr eax,12
mov esi,1024*4096*1022 ;base of page alias's.
sub es:d[esi+eax*4],1 shl MEM_LOCK_SHIFT ;un-lock it.
mov eax,es:d[esi+eax*4]
shr eax,MEM_LOCK_SHIFT
and eax,MEM_LOCK_MASK
jnz @@NotUnLocked
;
;Update number of un-locked physical pages present.
;
push ds
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
inc NoneLockedPages
assume ds:_cwDPMIEMU
pop ds
;
@@NotUnLocked: popm eax,ebx,esi,es
@@9: ret
RawUnLockPage endp
;-------------------------------------------------------------------------------
;
;Check if page lock count is zero.
;
;On Entry:-
;
;EAX - Linear page address.
;
;On Exit:-
;
;Zero set if page count=0.
;
RawPageLocked proc near
pushm eax,ebx,esi,es
mov bx,KernalZero
mov es,bx
shr eax,12 ;get page number.
mov esi,1024*4096*1022 ;base of page alias's.
mov ebx,es:d[esi+eax*4]
shr ebx,MEM_LOCK_SHIFT
and ebx,MEM_LOCK_MASK
popm eax,ebx,esi,es
ret
RawPageLocked endp
;-------------------------------------------------------------------------------
;
;Return page table entry for a particular linear address.
;
;On Entry:-
;
;EAX - linear address.
;
;On Exit:-
;
;Carry set if page table not present else,
;
;EDX - Page table entry.
;
GetPageStatus proc near
pushm eax,ebx,esi,ds,es
push ax
mov ax,KernalDS
mov ds,ax
pop ax
assume ds:_cwRaw
mov bx,KernalZero
mov es,bx
push eax
mov esi,PageDirLinear
shr eax,12 ;get page number.
shr eax,10 ;get dir entry number.
test es:d[esi+eax*4],1 ;page table present?
pop eax
jz @@8
mov esi,4096*1024*1023 ;base of page alias memory.
shr eax,12 ;get page number.
mov edx,es:[esi+eax*4] ;get page details.
clc
jmp @@9
;
@@8: xor edx,edx
stc
@@9: popm eax,ebx,esi,ds,es
ret
assume ds:_cwDPMIEMU
GetPageStatus endp
;-------------------------------------------------------------------------------
;
;The Exception 14 handler. This gets a shout whenever a not present page table is encountered by
;the processor. We check if the faulting address is within our range, passing to old handler if
;its not, re-aranging memory if it is.
;
VirtualFault proc far
pushm eax,ecx,edx,ds
mov ax,DpmiEmuDS
mov ds,ax
mov eax,ExceptionCR2
mov cx,KernalDS
mov ds,cx
assume ds:_cwRaw
cmp eax,LinearBase ;address below our memory space?
jc @@OldExit
cmp eax,LinearLimit ;address above our memory space?
jnc @@OldExit
;
push eax ;save the linear address.
call UnMapPhysical ;retrieve a physical page to use.
pop eax
jc @@Disk_Error ;This should only happen on disk errors.
shr eax,12
push LinearEntry
mov LinearEntry,eax ;setup linear address we want to map.
call MapPhysical ;map new page into faulting linear address space.
pop LinearEntry
jc @@Disk_Error ;This should only happen on disk errors.
;
popm eax,ecx,edx,ds
assume ds:nothing
test cs:DpmiEmuSystemFlags,1 ;check exit size.
assume ds:_cwRaw
jz @@Use32Bit3
db 66h
retf ;16 bit exit.
@@Use32Bit3: ;
retf
;
@@disk_error: jmp @@OldExit
;
assume ds:nothing
@@OldExit: popm eax,ecx,edx,ds
jmp cs:f[OldExcep14] ;32 bit chaining.
OldExcep14 df ?
assume ds:_cwDPMIEMU
VirtualFault endp
;-------------------------------------------------------------------------------
;
;Allocate a block of DOS memory & provide a selector to access it with.
;
RawGetDOSMemory proc near
pushm ecx,esi,edi,ebp,ds,es
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
;
cmp bx,-1 ;maximum?
jz @@0
inc ebx ;para extra for us.
@@0: ;
push ebx
mov edi,offset MemIntBuffer
push ds
pop es
mov Real_EAX[edi],4800h ;get memory.
mov Real_EBX[edi],ebx ;memory size.
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
call EMURawSimulateINT ;allocate it.
pop ecx
mov eax,Real_EAX[edi] ;get result.
mov ebx,Real_EBX[edi]
test Real_Flags[edi],1
jz @@1
or bx,bx ;nothing available?
jz @@9
dec ebx ;leave space for us!
jmp @@9
;
@@1: ;Now try and allocate enough selectors.
;
pushm eax,ecx
dec cx ;lose our para.
shr cx,12 ;get number of 64k chu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -