欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

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
        ;
        push    eax
        push    edx
        push    ebp
        push    ds
        push    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
        push    ebx
        push    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      mem1_error
mem1_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.
        ;

mem1_l0:        repne   scasd

        ;
        ;Nothing found means extend end of memory map.
        ;
        jnz     mem1_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      mem1_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     mem1_l1
        mov     edx,ecx

        ;
        ;Scan specified number of entries to see if their all free.
        ;
mem1_l1:
        push    ecx
        push    edi
        mov     ecx,edx
        repe    scasd           ;Scan for free pages.
        pop     edi
        pop     ecx
        jnz     mem1_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     mem1_ExtendEnd
        jmp     mem1_l2

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

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


        ;
        ;Last block is free so use it as the basis for extension.
        ;
mem1_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     mem1_Extend
        ;
mem1_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
        ;
mem1_Extend:    ;Memory map needs extending so get on with it.
        ;
        call    ExtendLinearMemory      ;Try and extend memory map.
        jnc     mem1_MarkMemRet         ;Mark the block as used.
        ;
        ;Not enough memory so report failure.
        ;
        stc
        jmp     mem1_exit
        ;
mem1_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     DWORD PTR es:[(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     mem1_exit
        ;
mem1_error:     stc
        ;
mem1_exit:

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

        pop     es
        pop     ds
        pop     ebp
        pop     edx
        pop     eax
        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
        ;
        push    eax
        push    edx
        push    ebp
        push    ds
        push    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
        push    ebx
        push    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      mem2_error
        ;
        ;Check for a valid address.
        ;
        test    esi,4095                ;all memory on page boundaries.
        jnz     mem2_error
        cmp     esi,LinearBase
        jc      mem2_error
        cmp     esi,LinearLimit
        jnc     mem2_error
        shr     esi,12          ;Get page number.
        mov     eax,DWORD PTR es:[1024*4096*1022+esi*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_START
        jnz     mem2_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      mem2_l1
mem2_l0:        mov     eax,DWORD PTR es:[(1024*4096*1022)+edx*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_END
        jnz     mem2_l1
        inc     ebp
        inc     edx
        dec     ecx
        jnz     mem2_l0
        ;
mem2_l1:        ;Shrinking or expanding?
        ;
        pop     ecx
        cmp     ecx,ebp
        jz      mem2_RetNewAddr
        jnc     mem2_Bigger
        ;
mem2_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
        ;
mem2_s0:        and     DWORD PTR es:[(1024*4096*1022)+edx*4],not MEM_MASK
        or      DWORD PTR es:[(1024*4096*1022)+edx*4],MEM_FREE
        and     DWORD PTR es:[(1024*4096*1023)+edx*4],not (1 shl 6)
        inc     edx
        dec     ecx
        jnz     mem2_s0
        call    EMUCR3Flush
        jmp     mem2_RetNewAddr
        ;
mem2_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.
        ;
mem2_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      mem2_Extend
        ;
        ;See if the next block is free.
        ;
        mov     eax,DWORD PTR es:[(1024*4096*1022)+edx*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_FREE
        jnz     mem2_NewBlock           ;no hope so get a new block.
        ;
        ;Check how big this next block is.
        ;
        mov     edi,ebp         ;use current size as basis.
mem2_b1:        mov     eax,DWORD PTR es:[(1024*4096*1022)+edx*4]
        and     eax,MEM_MASK
        cmp     eax,MEM_FREE
        jnz     mem2_NewBlock           ;No hope so get a new block.
        inc     edi
        cmp     edi,ecx         ;Got enough yet?
        jz      mem2_MarkAndRet
        inc     edx
        dec     ebx
        jnz     mem2_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      mem2_error
        jmp     mem2_MarkAndRet
        ;
mem2_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      mem2_error
        ;
mem2_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
        ;
mem2_mr0:       and     DWORD PTR es:[(1024*4096*1022)+edx*4],not MEM_MASK
        or      DWORD PTR es:[(1024*4096*1022)+edx*4],MEM_END
        inc     edx
        dec     ecx
        jnz     mem2_mr0
        jmp     mem2_RetNewAddr
        ;
mem2_NewBlock:  ;Nothing for it but to try and allocate a new block of memory.
        ;
        push    ecx
        push    ebp
        push    esi
        shl     ecx,12
        mov     ebx,ecx
        shr     ebx,16
        call    RawGetMemory
        pushf
        shl     ebx,16
        mov     bx,cx
        popf
        pop     esi
        pop     ebp
        pop     ecx
        jc      mem2_error
        ;
        ;Copy current block to new block.
        ;
        pushad
        mov     ecx,ebp
        shl     ecx,12
        shl     esi,12
        mov     edi,ebx
        push    ds
        push    es
        pop     ds
        shr     ecx,2

⌨️ 快捷键说明

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