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

📄 memory.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;-------------------------------------------------------------------------------
;
;Get memory using RAW/VCPI.
;
;On Entry:-
;
;BX:CX  - Size of block.
;
;On Exit:-
;
;Carry on error else,
;
;SI:DI  - Handle.
;BX:CX  - Logical address of block.
;
RAWGetMemory    proc    near
        call    RAWCopyCheck
        ;
        pushm   eax,edx,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
        shl     ebx,16          ;get block size as 32-bit.
        mov     bx,cx
        add     ebx,4095                ;round up to next 4k.
        shr     ebx,12
        or      ebx,ebx
        jz      @@error
@@start:        mov     edi,LinearBase  ;Get starting point.
        mov     ecx,LinearLimit
        sub     ecx,edi         ;Get memory present.
        shr     ecx,12          ;Get pages.
        shr     edi,12          ;Get page number.
        shl     edi,2           ;dword per entry.
        add     edi,1024*4096*1022      ;point to page details.
        ;
        ;Look for a big enough block of free memory.
        ;
        xor     eax,eax         ;value to look for.
        cld

        ;
        ;EAX    - zero, what we're looking for.
        ;ECX    - entries to check.
        ;EDI    - address of entries to check.
        ;
        ;EBX    - number of entries we want.
        ;

@@l0:   repne   scasd

        ;
        ;Nothing found means extend end of memory map.
        ;
        jnz     @@ExtendNew

        ;
        ;Point everything back to the matching value.
        ;
        sub     edi,4
        inc     ecx

        ;
        ;Save current position as start of last free block incase
        ;this block extends to the end of memory.
        ;
        mov     esi,edi         ;save last position.

        ;
        ;If we only wanted one page then we're done, this is it!
        ;
        cmp     ebx,1
        jz      @@l2            ;Speed up 4K allocations.

        ;
        ;Set the number of pages to scan. This should be the number of
        ;pages we want but has to be reduced to the number of pages
        ;actually available when the request would go off the end of
        ;memory.
        ;
        mov     edx,ebx
        cmp     ecx,ebx         ;Enough space to check?
        jnc     @@l1
        mov     edx,ecx

        ;
        ;Scan specified number of entries to see if their all free.
        ;
@@l1:   pushm   ecx,edi
        mov     ecx,edx
        repe    scasd           ;Scan for free pages.
        popm    ecx,edi
        jnz     @@l3            ;not enough free entries.

        ;
        ;All the entries were free, now check if we were truncating the
        ;length to stop us running off the end of memory.
        ;
        cmp     edx,ebx         ;Truncated length?
        jnz     @@ExtendEnd
        jmp     @@l2

        ;
        ;One way or another we didn't find the number of entries we were
        ;after so restart the search.
        ;
@@l3:   add     edi,4
        dec     ecx
        jmp     @@l0

        ;
        ;We've found what we wanted without any extra messing around so
        ;hand this over to the marker.
        ;
@@l2:   sub     esi,1024*4096*1022      ;point to page details.
        shr     esi,2
        jmp     @@MarkMemRet


        ;
        ;Last block is free so use it as the basis for extension.
        ;
@@ExtendEnd:    mov     edi,ecx         ;remaining entries.
        sub     esi,(1024*4096*1022)
        shr     esi,2           ;Get start page number.
        mov     ecx,ebx         ;Total pages needed.
        sub     ecx,edi         ;Pages found so far.
        jmp     @@Extend
        ;
@@ExtendNew:    ;Last block not free so new block will start at LinearLimit.
        ;
        mov     ecx,ebx         ;Set pages needed.
        mov     esi,LinearLimit ;New start address.
        shr     esi,12
        ;
@@Extend:       ;Memory map needs extending so get on with it.
        ;
        call    ExtendLinearMemory      ;Try and extend memory map.
        jnc     @@MarkMemRet            ;Mark the block as used.
        ;
        ;Not enough memory so report failure.
        ;
        stc
        jmp     @@exit
        ;
@@MarkMemRet:   ;Got the memory so mark it in use.
        ;
        sub     FreePages,ebx   ;reduce free page count.
        add     medAllocPages,ebx
        ;
        mov     ecx,ebx         ;Get number of pages again.
        mov     edx,esi
        mov     edi,esi         ;Get base page again.
        shl     edi,2
        add     edi,1024*4096*1022
        mov     eax,MEM_END
        rep     stosd
        mov     es:d[(1024*4096*1022)+edx*4],MEM_START
        ;
        ;Now return details to caller.
        ;
        shl     esi,12          ;Convert back to a real address.
        mov     di,si
        shr     esi,16
        mov     cx,di
        mov     bx,si
        clc
        jmp     @@exit
        ;
@@error:        stc
        ;
@@exit:

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

        popm    eax,edx,ebp,ds,es
        ret
        assume ds:_cwDPMIEMU
RAWGetMemory    endp


;-------------------------------------------------------------------------------
;
;Re-size a block of memory.
;
;On Entry:-
;
;SI:DI  - Handle.
;BX:CX  - New block size.
;
;On Exit:-
;
;SI:DI  - New handle.
;BX:CX  - New address.
;
RAWResMemory    proc    near
        call    RAWCopyCheck
        ;
        pushm   eax,edx,ebp,ds,es
        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

        mov     ax,KernalZero
        mov     es,ax
        shl     esi,16
        mov     si,di           ;Get real address.
        shl     ecx,16
        mov     cx,bx
        ror     ecx,16
        add     ecx,4095
        shr     ecx,12          ;Get new block size.
        or      ecx,ecx
        jz      @@error
        ;
        ;Check for a valid address.
        ;
        test    esi,4095                ;all memory on page boundaries.
        jnz     @@error
        cmp     esi,LinearBase
        jc      @@error
        cmp     esi,LinearLimit
        jnc     @@error
        shr     esi,12          ;Get page number.
        mov     eax,es:d[1024*4096*1022+esi*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_START
        jnz     @@error
        ;
        ;Work out the blocks current size.
        ;
        push    ecx
        mov     ebp,1
        mov     edx,esi
        inc     edx
        mov     ecx,LinearLimit
        shr     ecx,12
        sub     ecx,edx
        jz      @@l1
@@l0:   mov     eax,es:d[(1024*4096*1022)+edx*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_END
        jnz     @@l1
        inc     ebp
        inc     edx
        dec     ecx
        jnz     @@l0
        ;
@@l1:   ;Shrinking or expanding?
        ;
        pop     ecx
        cmp     ecx,ebp
        jz      @@RetNewAddr
        jnc     @@Bigger
        ;
@@Smaller:      ;Shrinking the block so get on with it.
        ;
        ;ECX - New size in pages.
        ;EBP - Current size in pages.
        ;ESI - Current start page.
        ;
        mov     edx,esi
        add     edx,ecx         ;move to new block end.
        sub     ebp,ecx         ;get number of pages to lose.
        mov     ecx,ebp
        ;
        add     FreePages,ebp   ;update number of free pages.
        sub     medAllocPages,ebp
        ;
@@s0:   and     es:d[(1024*4096*1022)+edx*4],not MEM_MASK
        or      es:d[(1024*4096*1022)+edx*4],MEM_FREE
        and     es:d[(1024*4096*1023)+edx*4],not (1 shl 6)
        inc     edx
        dec     ecx
        jnz     @@s0
        call    EMUCR3Flush
        jmp     @@RetNewAddr
        ;
@@Bigger:       ;Want to expand the block so get on with it.
        ;
        ;ECX - New size in pages.
        ;EBP - Current size in pages.
        ;ESI - Current start page.
        ;
@@b0:   mov     edx,esi
        add     edx,ebp         ;move to end of this block.
        mov     ebx,LinearLimit
        shr     ebx,12
        sub     ebx,edx         ;get pages to end of memory.
        or      ebx,ebx
        jz      @@Extend
        ;
        ;See if the next block is free.
        ;
        mov     eax,es:d[(1024*4096*1022)+edx*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_FREE
        jnz     @@NewBlock              ;no hope so get a new block.
        ;
        ;Check how big this next block is.
        ;
        mov     edi,ebp         ;use current size as basis.
@@b1:   mov     eax,es:d[(1024*4096*1022)+edx*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_FREE
        jnz     @@NewBlock              ;No hope so get a new block.
        inc     edi
        cmp     edi,ecx         ;Got enough yet?
        jz      @@MarkAndRet
        inc     edx
        dec     ebx
        jnz     @@b1            ;keep trying.
        ;
        ;Reached the end of the memory map so try extending it.
        ;
        pushad
        sub     ecx,edi         ;pages still needed.
        call    ExtendLinearMemory
        popad
        jc      @@error
        jmp     @@MarkAndRet
        ;
@@Extend:       ;Need to extend the memory map to provide a block of free memory
        ;after the current block.
        ;
        pushad
        sub     ecx,ebp         ;pages needed.
        call    ExtendLinearMemory
        popad
        jc      @@error
        ;
@@MarkAndRet:   ;Mark the new memory as in use and exit.
        ;
        ;ECX - New size in pages.
        ;EBP - Current size in pages.
        ;ESI - Current start page.
        ;
        mov     edx,esi
        add     edx,ebp         ;move to start of new memory.
        sub     ecx,ebp         ;pages to mark.
        ;
        sub     FreePages,ecx   ;update number of free pages.
        add     medAllocPages,ecx
        ;
@@mr0:  and     es:d[(1024*4096*1022)+edx*4],not MEM_MASK
        or      es:d[(1024*4096*1022)+edx*4],MEM_END
        inc     edx
        dec     ecx
        jnz     @@mr0
        jmp     @@RetNewAddr
        ;
@@NewBlock:     ;Nothing for it but to try and allocate a new block of memory.
        ;
        pushm   ecx,ebp,esi
        shl     ecx,12
        mov     ebx,ecx
        shr     ebx,16
        call    RawGetMemory
        pushf
        shl     ebx,16
        mov     bx,cx
        popf
        popm    ecx,ebp,esi
        jc      @@error
        ;
        ;Copy current block to new block.
        ;
        pushad
        mov     ecx,ebp
        shl     ecx,12
        shl     esi,12
        mov     edi,ebx
        pushm   ds,es
        pop     ds
        shr     ecx,2
        rep     movsd
        pop     ds
        popad
        ;
        ;Release current block.
        ;
        pushad
        shl     esi,12
        mov     di,si
        shr     esi,16
        call    RawRelMemory
        popad
        ;
        ;Use new block in place of origional.
        ;
        mov     esi,ebx
        shr     esi,12
        ;
@@RetNewAddr:   ;Return possibly new address/handle to caller.

⌨️ 快捷键说明

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