📄 int31h.asm
字号:
mov [esi+04h],eax ; set this block as free
lea edi,[esi+eax+10h] ; get address of next block
cmp edi,cs:mem_top ; check if at top of memory
jae @@0
mov edx,[edi+04h] ; get size of next block
btr edx,31 ; check if block next to us is free
jc @@0 ; if not, jump
lea edx,[eax+edx+10h] ; calculate total size (this+hdr+next)
cmp edx,ebx ; check if enough
jb @@0 ; if not, jump
mov eax,edx ; set this size = (this + next)
mov [esi+04h],eax ; link this and next blocks
jmp int31_allocblock ; and go to the allocation routine
@@0: mov edi,cs:mem_ptr ; get pointer to memory
@@1: mov edx,[edi+04h] ; get block size
btr edx,31 ; check if memory block is used
jc @@2 ; if yes, jump
cmp edx,ebx ; check if block is large enough
jae @@3 ; if yes, allocate block
@@2: lea edi,[edi+edx+10h] ; load address of next memory block
cmp edi,cs:mem_top ; check if at top of memory
jb @@1 ; if not, loop
bts eax,31 ; set this block as used
mov [esi+04h],eax ; restore state of this block
jmp int31fail8013 ; fail: not enough memory
@@3: push esi edi
mov ecx,eax
shr ecx,2
add esi,10h
add edi,10h
rep movs dword ptr es:[edi],ds:[esi]
mov cl,al
and cl,3
rep movs byte ptr es:[edi],ds:[esi]
pop edi esi
call int31_linkfreeblocks
mov esi,edi
mov eax,edx
jmp int31_allocblock ; and go to the allocation routine
;=============================================================================
int31050A:
shl esi,16 ; convert SI:DI to ESI
mov si,di
call int31_checkifmemavail
call int31_checkblocks
call int31_checkhandle
mov ebx,[esi+04h] ; check if block is used
btr ebx,31
jnc int31fail8023
add esi,10h
xchg ebx,esi
mov cx,bx
shr ebx,16
mov di,si
shr esi,16
jmp int31oksinoax
;-----------------------------------------------------------------------------
int31_checkifmemavail: ; check if memory had been allocated
pop bp
push eax
mov eax,cs:mem_ptr
or eax,cs:mem_free
pop eax
jz int31fail8013
jmp bp
;-----------------------------------------------------------------------------
int31_checkblocks: ; check if memory had been overwritten
test cs:pm32_mode,00100000b
jz @@done
push eax esi
mov esi,cs:mem_ptr
@@1: test si,000Fh ; blocks must be para aligned
jnz @@err
mov eax,12345678h ; header id
cmp eax,[esi+00h] ; if no header_id at block start
jnz @@err ; then signal error
cmp eax,[esi+0Ch] ; if no header_id at block end
jnz @@err ; then signal error
mov eax,[esi+04h] ; get block size
btr eax,31 ; reset the used flag
lea esi,[esi+eax+10h] ; load address of next memory block
cmp esi,cs:mem_ptr
jb @@err
cmp esi,cs:mem_top ; check if at top of memory
ja @@err
jb @@1 ; if not, loop
pop esi eax
@@done: ret
@@err: mov ds,cs:seldata
xor eax,eax
mov mem_ptr,eax ; set to zero to prevent looping error
mov mem_free,eax ; when exiting
mov al,83h
jmp dword ptr client_call
;-----------------------------------------------------------------------------
int31_checkhandle:
pop bp ; check for valid handle in ESI
cmp esi,cs:mem_ptr
jb @@1
cmp esi,cs:mem_top
ja @@1
mov eax,12345678h
cmp eax,[esi+00h]
jnz @@1
cmp eax,[esi+0Ch]
jnz @@1
jmp bp
@@1: jmp int31fail8023 ; fail: invalid handle
;-----------------------------------------------------------------------------
int31_testbxcxtoebx: ; convert BX:CX to EBX
pop bp
shl ebx,16
mov bx,cx
test ebx,ebx
jz int31fail8021 ; BX:CX cannot be zero
add ebx,0Fh ; align EBX on para boundary
and bl,0F0h
bt ebx,31
jc int31fail8021 ; cannot allocate that much memory
jmp bp
;-----------------------------------------------------------------------------
int31_getfreemem:
xor eax,eax ; reset free memory size
xor ecx,ecx
mov esi,cs:mem_ptr ; get pointer to memory
@@1: mov edx,[esi+04h] ; get block size
btr edx,31 ; check if memory block is used
jc @@2 ; if yes, jump
add ecx,edx
cmp eax,edx ; pick largest value
ja @@2
mov eax,edx
@@2: lea esi,[esi+edx+10h] ; load addres of next memory block
cmp esi,cs:mem_top ; check if at top of memory
jb @@1 ; if not, loop
ret
;-----------------------------------------------------------------------------
int31_allocblock:
mov ecx,12345678h
movzx edx,cs:id32_process_id
sub eax,ebx ; nextsize=actualsize-allocsize
sub eax,10h ; is nextsize<16 (header size)
jb @@1 ; if yes, do not create next block
lea edi,[esi+ebx+10h] ; EDI = ptr to next block
mov [edi+00h],ecx ; header ID1
mov [edi+04h],eax ; set next block as free/size
mov [edi+08h],edx ; process_ID
mov [edi+0Ch],ecx ; header ID2
@@1: bts ebx,31 ; set this block as used
mov [esi+00h],ecx ; header ID1
mov [esi+04h],ebx ; store this block size in header
mov [esi+08h],edx ; process_ID
mov [esi+0Ch],ecx ; header ID2
call int31_linkfreeblocks
lea ebx,[esi+10h] ; EBX = ptr to memory block (-header)
mov cx,bx
shr ebx,16
mov di,si
shr esi,16
jmp int31oksinoax
;-----------------------------------------------------------------------------
int31_linkfreeblocks:
pushad
mov edi,cs:mem_ptr ; EDI = ptr to 1st block handle
mov ebp,cs:mem_top
mov eax,[edi+04h] ; get 1st block size
btr eax,31
lea esi,[edi+eax+10h] ; ESI = ptr to 2nd block handle
cmp esi,ebp ; check if at top of memory
jae @@done ; if yes, done
mov esi,edi ; ESI=EDI = ptr to 1st block
@@1: mov eax,[esi+04h] ; get block size
btr eax,31 ; check if block is used
jc @@4 ; if yes, jump
xor ebx,ebx ; reset amount of free block memory
xor ecx,ecx ; reset number of free blocks in raw
mov edi,esi ; remember addr of first free block
jmp @@3
@@2: add ecx,10h ; increment number of free blocks
mov eax,[esi+04h] ; get block size
btr eax,31 ; check if block is free
lea ebx,[eax+ebx] ; amount of free memory encountered
jnc @@3 ; if yes, jump
sub ebx,eax
sub ecx,10h
add ebx,ecx
add [edi+04h],ebx
jmp @@4
@@3: lea esi,[esi+eax+10h] ; calculate address of next block
cmp esi,ebp ; check if at top of memory
jb @@2 ; if not, loop
add ebx,ecx
add [edi+04h],ebx
jmp @@done
@@4: lea esi,[esi+eax+10h] ; calculate address of next block
cmp esi,ebp ; check if at top of memory
jb @@1 ; if not, loop
@@done: popad
ret
;=============================================================================
; VIRTUAL MEMORY FUNCTIONS (not supported)
;=============================================================================
;=============================================================================
int310600:
int310601:
int310602:
int310603:
int310702:
int310703:
jmp int31ok
;=============================================================================
int310604:
xor bx,bx
mov cx,1000h
jmp int31okbx
;=============================================================================
; PHYSICAL MEMORY MAPPING FUNCTIONS
;=============================================================================
;=============================================================================
int310800: ; physical memory mapping
shl ebx,16 ; convert BX:CX to EBX
shl esi,16 ; convert SI:DI to ESI
mov bx,cx
mov si,di
cmp ebx,100000h ; check if mapping under 1MB limit
jb int31fail8021 ; if yes, error
test esi,esi ; check if size is zero
jz int31fail8021 ; if yes, error
cmp cs:pmodetype,2 ; check if system is VCPI
jz int310800v ; if yes, do VCPI memory mapping
jmp int31ok ; if under raw/XMS, do nothing
int310800v:
cmp cs:pm32_maxfpages,0 ; check if any linear memory avail.
jz int31fail8012 ; if not, signal error 8012h
push ds
pop es
mov edi,cs:phystablebase ; get base of pagetables
@@0: mov eax,ebx ; EAX = physical address
lea ecx,[esi+0FFFh] ; ECX = size of memory to map
and ax,0F000h
shr ecx,12
mov edx,edi
@@1: cmp edi,cs:phystabletop ; are there any pages mapped left
jae @@3 ; no, go on with mapping
mov ebp,[edi]
and bp,0F000h
cmp eax,ebp ; check if page already mapped
jz @@2 ; if yes, go to check next page
add edi,4 ; increment pointer into pagetables
jmp @@0 ; loop
@@2: add edi,4 ; increment pointer into pagetables
add eax,4096
dec ecx ; decrement amount of pages checked
jnz @@1 ; if there are more left, loop
mov eax,ebx
and ax,0F000h
sub ebx,eax
jmp @@done ; region already mapped, we are done
@@3: mov edi,cs:phystablebase ; get base of pagetables
mov ecx,cs:phystabletop ; get number of available pagetables
sub ecx,edi
shr ecx,2 ; convert to 4KB pages
mov eax,ebx
and ax,0F000h
lea ebp,[ebx+esi+0FFFh] ; EBP = number of required 4KB pages
sub ebp,eax
shr ebp,12
@@4: test ecx,ecx ; check if no linear space left
jz int31fail8021 ; if yes, error
xor eax,eax
repne scas dword ptr es:[edi] ; scan for first free page
lea edx,[edi-4] ; EDX = first free page address
repe scas dword ptr es:[edi] ; scan for amount of free pages
mov eax,edi
sub eax,edx
shr eax,2 ; EAX = free pages available
cmp eax,ebp ; check if enough free pages
jb @@4 ; no, must loop
mov eax,ebx ; EAX = physical address
and ax,0F000h
sub ebx,eax
mov edi,edx ; EDI = address of first free page
mov ecx,ebp
mov al,07h ; set page as user/writeable/present
cmp cs:cputype,3 ; check if CPU is 486+
jbe @@loop ; if not, jump
mov al,1Fh ; set PCD and PWT bits (no page cache)
@@loop: stos dword ptr es:[edi] ; map one 4KB page
add eax,4096 ; go for next page
loop @@loop ; loop until no pages left
or byte ptr [edx+1],2 ; mark start of mapped block
or byte ptr [edi-3],4 ; mark end of mapped block
@@done: sub edx,cs:phystablebase
shl edx,10
add edx,ebx
mov [esp+18h],dx
shr edx,16
or dx,8000h
mov [esp+10h],dx
mov eax,cs:vcpi_cr3
mov cr3,eax
xor eax,eax
mov cr2,eax
jmp int31ok
;=============================================================================
int310801:
cmp cs:pmodetype,2
jz int310801v
jmp int31ok ; if under raw/XMS, do nothing
int310801v:
cmp cs:pm32_maxfpages,0 ; check if any linear memory avail.
jz int31fail8012 ; if not, signal error 8012h
and bx,7FFFh
shl ebx,16
mov bx,cx
shr ebx,10
and bl,0FCh
add ebx,cs:phystablebase
cmp ebx,cs:phystablebase ; check if addr is in range
jb int31fail8025
cmp ebx,cs:phystabletop
jae int31fail8025
test byte ptr [ebx+1],2
jz int31fail8025
@@loop: xor eax,eax ; clear page table entries
xchg eax,[ebx]
add ebx,04h
test ah,04h
jz @@loop
@@1: mov eax,cs:vcpi_cr3
mov cr3,eax
xor eax,eax
mov cr2,eax
jmp int31ok
;=============================================================================
; FPU RELATED FUNCTIONS
;=============================================================================
;=============================================================================
int310E00:
movzx ax,cs:fputype ; get FPU type
shl ax,4
smsw dx
test dl,00000100b ; check EM bit
jz @@1
or al,00000010b
@@1: test al,0F0h
jz @@2
or al,00000100b
@@2: or al,cs:virtualfpu ; put virtual FPU flags in AX
jmp int31okax
;=============================================================================
int310E01:
mov ds,cs:seldata
and bl,00000011b
mov virtualfpu,bl
smsw ax
test bl,00000010b
jz @@1
or al,00000100b
jmp @@2
@@1: and al,11111011b
@@2: lmsw ax
jmp int31ok
;=============================================================================
int31EEFF:
add esp,26h ; adjust stack
pop ds ; restore DS
mov eax,'D32A'
push cs
pop es
mov ebx,offs $+2 ; points to itself
mov ch,cs:pmodetype
mov cl,cs:cputype
mov dx,cs:client_version
jmp int31oknopop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -