⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        call    GetPageStatus
        pop     eax
        jc      @@15            ;ignore not present tables.
        test    edx,1
        jz      @@005           ;already present.
        call    RawPageLocked   ;locked page?
        jnz     @@05
        dec     d[_LM_Got]              ;reduce available pages.
        jmp     @@05
@@005:  inc     d[_LM_Needed]
@@05:   add     eax,4096
        cmp     eax,d[_LM_BlockEnd]     ;done them all yet?
        jc      @@04
;
;Check if we actually need any more pages to lock this region.
;
        cmp     d[_LM_Needed],0
        jz      @@OK
;
;If VMM isn't active then pages can always be locked assumeing they exist.
;
        cmp     VMMHandle,0
        jnz     @@VMM
        mov     eax,d[_LM_Needed]
        cmp     eax,d[_LM_Got]
        jc      @@OK
        jz      @@OK
        jmp     @@15
;
;VMM is active and pages are required so we need to make sure enough pages are
;left for swapping.
;
@@VMM:  mov     eax,d[_LM_Needed]
        add     eax,16          ;arbitrary safety buffer.
        cmp     eax,d[_LM_Got]
        jc      @@OK
        jz      @@OK
        jmp     @@15
;
;Enough free pages so lock the region.
;
@@OK:   mov     eax,d[_LM_BlockBase]
@@4:    cmp     eax,LinearBase  ;must be in our memory pool.
        jc      @@5
        cmp     eax,LinearLimit
        jnc     @@5
        push    eax
        call    GetPageStatus
        pop     eax
        jc      @@15            ;ignore not present tables.
        test    edx,1           ;is it present?
        jnz     @@6
        ;
@@11:   ;Need to allocate a physical page first.
        ;
        push    eax
        call    UnMapPhysical
        pop     eax
        jc      @@15            ;this shouldn't happen.
        mov     LinearEntry,eax
        shr     LinearEntry,12  ;store page number to allocate at.
        push    eax
        call    MapPhysical             ;map this page in.
        pop     eax
        ;
@@6:    ;Now mark this page as locked.
        ;
        call    RawLockPage
        ;
@@5:    add     eax,4096
        cmp     eax,d[_LM_BlockEnd]     ;done them all yet?
        jc      @@4
        ;
@@10:   clc
        jmp     @@1
        ;
@@15:   stc
        ;
@@1:
        lss     esp,f[esp]
        pushf
        add     d[RawStackPos],RawStackDif
        popf

        popm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
        ret
        assume ds:_cwDPMIEMU
RAWLockMemory   endp


;-------------------------------------------------------------------------------
RAWUnLockMemory proc near
        call    RAWCopyCheck
        ;
        pushm   eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
        mov     ax,KernalDS
        mov     ds,ax
        assume ds:_cwRaw
        ;

        push    ebx
        push    ecx
        push    edx
        xor     ebx,ebx
        mov     bx,ss
        mov     ecx,esp
        pushf
        cli
        mov     edx,d[RawStackPos]
        sub     d[RawStackPos],RawStackDif
        popf
        mov     ax,KernalSS
        mov     ss,ax
        mov     esp,edx
        add     ecx,4+4+4
        pushm   ebx,ecx
        sub     ecx,4+4+4
        push    es
        mov     es,bx
        mov     edx,es:[ecx]
        mov     ebx,es:[ecx+4+4]
        mov     ecx,es:[ecx+4]
        pop     es

        shl     ebx,16
        mov     bx,cx
        shl     esi,16
        mov     si,di
        add     esi,ebx
        and     ebx,0FFFFFFFFh-4095     ;round down to nearest page.
        mov     d[_LM_BlockBase],ebx
        add     esi,4095
        and     esi,0FFFFFFFFh-4095     ;round up to next page.
        dec     esi
        mov     d[_LM_BlockEnd],esi     ;store address of last page.
        ;
        ;Now run through all pages in this range un-locking them.
        ;
        mov     eax,d[_LM_BlockBase]
@@4:    cmp     eax,LinearBase  ;must be in our memory pool.
        jc      @@5
        cmp     eax,LinearLimit
        jnc     @@5
        push    eax
        call    GetPageStatus
        pop     eax
        jc      @@5             ;ignore not present tables.
        test    edx,1           ;is it present?
        jz      @@5
        call    RawUnLockPage   ;unlock the page.
@@5:    add     eax,4096
        cmp     eax,d[_LM_BlockEnd]     ;done them all yet?
        jc      @@4
        clc
@@1:

        lss     esp,f[esp]
        pushf
        add     d[RawStackPos],RawStackDif
        popf

        popm    eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
        ret
        assume ds:_cwDPMIEMU
RAWUnLockMemory endp


;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
RAWGetMemoryMax proc near
;
;Work out biggest memory block remaining.
;
        call    RAWCopyCheck
        ;
        pushm   eax,ecx,edx,esi,edi,ebp,ds,es
        mov     ax,KernalDS             ;make data addresable.
        mov     ds,ax
        assume ds:_cwRaw

        push    ebx
        push    ecx
        push    edx
        xor     ebx,ebx
        mov     bx,ss
        mov     ecx,esp
        pushf
        cli
        mov     edx,d[RawStackPos]
        sub     d[RawStackPos],RawStackDif
        popf
        mov     ax,KernalSS
        mov     ss,ax
        mov     esp,edx
        add     ecx,4+4+4
        pushm   ebx,ecx
        sub     ecx,4+4+4
        push    es
        mov     es,bx
        mov     edx,es:[ecx]
        mov     ebx,es:[ecx+4+4]
        mov     ecx,es:[ecx+4]
        pop     es

        mov     ax,KernalZero
        mov     es,ax
        ;
        ;Look in existing memory first.
        ;
        mov     edx,LinearBase  ;Get starting point.
        mov     ecx,LinearLimit
        sub     ecx,edx         ;Get memory present.
        shr     ecx,12          ;Get pages.
        shr     edx,12          ;Get page number.
        xor     edi,edi         ;Clear flag.
        xor     ebp,ebp         ;Clear biggest so far.
        ;
@@l0:   ;Look for a bigest block of free memory.
        ;
        mov     eax,es:d[(1024*4096*1022)+edx*4] ;Get page details.
        and     eax,MEM_MASK
        cmp     eax,MEM_FREE            ;Free block?
        jnz     @@l2
        or      edi,edi         ;Got any yet?
        jnz     @@l1
        mov     esi,edx         ;Get base page number.
@@l1:   inc     edi
        cmp     edi,ebp         ;Biggest yet?
        jc      @@l3
        mov     ebx,esi         ;Get base.
        mov     ebp,edi         ;Get size.
        jmp     @@l3
@@l2:   xor     edi,edi
@@l3:   inc     edx             ;Next page.
        dec     ecx
        jnz     @@l0
        ;
        ;See if biggest block found is the last block in the map.
        ;
        xor     edx,edx         ;reset end of chain value.
        or      edi,edi         ;last block free?
        jz      @@l4
        cmp     ebx,esi         ;same base?
        jnz     @@l4
        mov     edx,ebp         ;setup extra block size.
        mov     ebp,0           ;reset normal block size.
        jmp     @@l5
        ;
@@l4:   ;Get size of the last block in the memory map.
        ;
        mov     eax,LinearBase
        mov     esi,LinearLimit
        shr     esi,12
        dec     esi
        shr     eax,12
        mov     ecx,esi
        sub     ecx,eax
@@l6:   jecxz   @@l5
        mov     eax,es:d[(1024*4096*1022)+esi*4] ;Get page details.
        and     eax,MEM_MASK
        cmp     eax,MEM_FREE            ;Free block?
        jnz     @@l5
        dec     esi
        inc     edx
        dec     ecx
        jmp     @@l6
        ;
@@l5:   ;See what extra memory we can get hold of.
        ;
        mov     ebx,edx
        call    PhysicalGetPages        ;Get extra memory available.
        mov     ecx,ebx         ;Save origional value.
        add     ebx,edx         ;update extra memory value.
        ;
        ;See how many pages of real memory would be lost to page tables.
        ;
        mov     eax,LinearLimit
        shr     eax,12
        add     eax,edx
        shr     eax,10
        mov     edx,LinearLimit
        shr     edx,12
        dec     edx
        shr     edx,10
        sub     eax,edx
        add     eax,eax         ;Page + Det
        sub     ebx,eax
        ;
        ;See what extra memory the VMM can get hold of.
        ;
        cmp     VMMHandle,0
        jz      @@l8
        mov     ebx,ecx
        pushm   ebx,ebp
        ;
        ;Get free disk space remaining.
        ;
        mov     dl,VMMName              ;get drive letter for this media.
        sub     dl,'A'          ;make it real.
        inc     dl              ;adjust for current type select.
        mov     ah,36h          ;get free space.
        int     21h             ;/
        xor     edx,edx
        cmp     ax,-1           ;invalid drive?
        jz      @@l7
        mul     cx              ;Get bytes per cluster.
        mul     bx              ;Get bytes available.
        shl     edx,16
        mov     dx,ax
@@l7:   ;
        ;Get current swap file size.
        ;
        push    edx
        mov     bx,VMMHandle
        mov     ax,4202h
        xor     cx,cx
        mov     dx,cx
        int     21h
        shl     edx,16
        mov     dx,ax
        pop     eax
        add     edx,eax
        and     edx,not 65535
        shr     edx,12
        popm    ebx,ebp
        ;
        ;Work out how much of the VMM space is extra.
        ;
        mov     eax,LinearLimit
        sub     eax,LinearBase
        shr     eax,12
        sub     edx,eax
        add     ebx,edx

        ;
@@l8:   ;Check which block is bigger and exit.
        ;
        push    ecx
        mov     eax,ebx
        shl     eax,12
        mov     ecx,LinearLimit
        sub     ecx,LinearBase
        sub     eax,ecx
        js      @@l89
        cmp     eax,MaxMemLin
        jc      @@l89
        mov     ebx,MaxMemLin
        sub     ebx,ecx
        shr     ebx,12
@@l89:  pop     ecx

        cmp     ebx,ebp
        jnc     @@l9
        mov     ebx,ebp
@@l9:   shl     ebx,12
        clc

        lss     esp,f[esp]
        pushf
        add     d[RawStackPos],RawStackDif
        popf

        popm    eax,ecx,edx,esi,edi,ebp,ds,es
        ret
        assume ds:_cwDPMIEMU
RAWGetMemoryMax endp


;-------------------------------------------------------------------------------
;
;Extend the linear memory map by allocateing physical memory if available or
;virtual memory if not, or even a combination of the two.
;
;On Entry:
;
;ECX    - Pages to extend by.
;
;On Exit:
;
;Carry set on error else memory map extended.
;
ExtendLinearMemory proc near
        pushad
        pushm   ds,es
        mov     ax,KernalDS
        mov     ds,ax
        assume ds:_cwRaw
        mov     ax,KernalZero
        mov     es,ax
        mov     ebp,ecx

        mov     eax,ecx
        shl     eax,12
        dec     eax
        add     eax,LinearLimit
        dec     eax
        sub     eax,LinearBase
        cmp     eax,MaxMemLin
        jnc     @@error

        ;
        ;Try extending useing physical memory first.
        ;
@@f0:   mov     eax,LinearLimit ;get new entry number.
        shr     eax,12          ;page number.
        mov     LinearEntry,eax
        shr     eax,10          ;/1024 for page dir entry.
        mov     edi,PageDirLinear       ;get page table address.
        mov     eax,es:d[edi+eax*4]     ;this page present?
        test    eax,1           ;do we have a page table?
        jnz     @@f1            ;keep going till we do.
;
;No page table so make sure we can get 2 pages (page and det)
;
        call    PhysicalGetPages
        cmp     edx,2
        jc      @@virtual
;
;both pages available so go to it.
;
@@f2:   call    PhysicalGetPage ;get a page.
        jc      @@error         ;it lied.
        mov     eax,LinearLimit ;get new entry number.
        shr     eax,12          ;page number.
        mov     LinearEntry,eax
        push    LinearEntry
        call    MapPhysical             ;use this page for page table.
        call    PhysicalGetPage ;get a page.
        pop     LinearEntry
        jc      @@error         ;it lied.
        call    MapPhysical             ;use this page for page table.
        ;
@@f1:   call    PhysicalGetPage ;get a page.
        jc      @@Virtual               ;use virtual memory.
        mov     eax,LinearLimit ;get new entry number.
        shr     eax,12          ;page number.
        mov     LinearEntry,eax
        call    MapPhysical             ;use this page for page table.
        ;
        ;Update details.
        ;
        mov     eax,LinearLimit
        shr     eax,12
        mov     es:d[(1024*4096*1022)+eax*4],0
        inc     FreePages
;       dec     medAllocPages
        inc     TotalPages
        add     LinearLimit,4096        ;bump up the end of the memory map.
        dec     ebp             ;update the counter.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -