home *** CD-ROM | disk | FTP | other *** search
- TITLE MEM.ASM
-
- ;****************************************************************
- ;* MEM.ASM - Assembly mem-fill and mem-copy routines *
- ;****************************************************************
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; (C) Copyright Microsoft Corp. 1991. All rights reserved.
- ;
- ; You have a royalty-free right to use, modify, reproduce and
- ; distribute the Sample Files (and/or any modified version) in
- ; any way you find useful, provided that you agree that
- ; Microsoft has no warranty obligations or liability for any
- ; Sample Application Files which are modified.
- ;
- ; Unless you got this from the MM Sys BBS, it may not be the most
- ; current version. We are continually improving our samples and
- ; their documentation. Call the BBS at 206 936-4082.
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ?PLM=1 ; PASCAL Calling convention is DEFAULT
- ?WIN=1 ; Windows calling convention
- ?386=0 ; Use 386 code?
-
- .xlist
- include cmacros.inc
- include windows.inc
- .list
-
- externA __WinFlags ; in KERNEL
- externA __AHINCR ; in KERNEL
- externA __AHSHIFT ; in KERNEL
-
- ; The following structure should be used to access high and low
- ; words of a DWORD. This means that "word ptr foo[2]" -> "foo.hi".
-
- LONG struc
- lo dw ?
- hi dw ?
- LONG ends
-
- FARPOINTER struc
- off dw ?
- sel dw ?
- FARPOINTER ends
-
- EAXtoDXAX macro
- shld edx,eax,16 ; move HIWORD(eax) to dx
- endm
-
- DXAXtoEAX macro
- ror eax,16 ; xchg HIWORD(eax) and LOWORD(eax)
- shrd eax,edx,16 ; move LOWORD(edx) to HIWORD(eax)
- endm
-
- ; -------------------------------------------------------
- ; DATA SEGMENT DECLARATIONS
- ; -------------------------------------------------------
-
- ifndef SEGNAME
- SEGNAME equ <_TEXT>
- endif
-
- createSeg %SEGNAME, CodeSeg, word, public, CODE
-
- sBegin Data
- sEnd Data
-
- sBegin CodeSeg
- assumes cs,CodeSeg
- assumes ds,DATA
-
- ;---------------------------Public-Routine------------------------------;
- ; muldiv32
- ;
- ; multiples two 32 bit values and then divides the result by a third
- ; 32 bit value with full 64 bit presision
- ;
- ; lResult = (lNumber * lNumerator) / lDenominator
- ;
- ; Entry:
- ; lNumber = number to multiply by nNumerator
- ; lNumerator = number to multiply by nNumber
- ; lDenominator = number to divide the multiplication result by.
- ;
- ; Returns:
- ; DX:AX = result of multiplication and division.
- ; Error Returns:
- ; none
- ; Registers Preserved:
- ; DS,ES,SI,DI
- ;-----------------------------------------------------------------------;
- assumes ds,nothing
- assumes es,nothing
-
- cProc muldiv32,<PUBLIC,FAR>,<>
- ParmD ulNumber
- ParmD ulNumerator
- ParmD ulDenominator
- cBegin
- .386
- mov eax,ulNumber
- mov edx,ulNumerator
- mov ebx,ulDenominator
-
- imul edx ; edx:eax = (ulNumber * ulNumerator)
- idiv ebx ; eax = (ulNumber * ulNumerator) / ulDenominator
-
- EAXtoDXAX ; covert eax to dx:ax for 16 bit programs
- .286
- cEnd
-
- ;---------------------------Public-Routine------------------------------;
- ; MemFill
- ;
- ; fills memory with a bunch of bytes
- ;
- ; Entry:
- ; lpMem LPSTR to memory to fill
- ; cbMem DWORD count of bytes to fill
- ; bFill BYTE byte to fill
- ;
- ; Returns:
- ; nothing
- ; Error Returns:
- ; None
- ; Registers Preserved:
- ; BP,DS,SI,DI
- ; Registers Destroyed:
- ; AX,BX,CX,DX,FLAGS
- ; Calls:
- ; nothing
- ; History:
- ;
- ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
- ; Created.
- ;-----------------------------------------------------------------------;
-
- cProc MemFill,<FAR,PUBLIC,NODATA>,<>
- ParmD lpMem
- ParmD cbMem
- ParmB bFill
- cBegin
- .386
- push edi
-
- cld
- mov bl, byte ptr bFill ; repeat the byte through EAX
- mov bh, bl
- mov ax,bx
- shl eax,16
- mov ax,bx
-
- les di, lpMem
- movzx edi,di
- mov ebx,cbMem
-
- mov ecx,edi
- neg ecx
- and ecx,0011b
- sub ebx,ecx
- rep stos byte ptr es:[edi] ; note can optimize WORD/DWORD writes
- db 67H ; Fix strange 386 bug
- mov ecx,ebx
- shr ecx,2
- rep stos dword ptr es:[edi]
- db 67H ; Fix strange 386 bug
- mov ecx,ebx
- and ecx,0011b
- rep stos byte ptr es:[edi]
- db 67H ; Fix strange 386 bug
-
- mf386_exit:
- pop edi
- .286
- cEnd
-
- ;---------------------------Public-Routine------------------------------;
- ; MemCopy
- ;
- ; copy memory
- ;
- ; Entry:
- ; lpSrc HPSTR to copy from
- ; lpDst HPSTR to copy to
- ; cbMem DWORD count of bytes to move
- ;
- ; NOTE: overlapped copies will work
- ;
- ; Returns:
- ; destination pointer
- ; Error Returns:
- ; None
- ; Registers Preserved:
- ; BP,DS,SI,DI
- ; Registers Destroyed:
- ; AX,BX,CX,DX,FLAGS
- ; Calls:
- ; nothing
- ; History:
- ;-----------------------------------------------------------------------;
-
- cProc MemCopy,<FAR,PASCAL,PUBLIC,NODATA>,<ds>
- ParmD lpDst
- ParmD lpSrc
- ParmD cbMem
- cBegin
- .386
- push edi
- push esi
- cld
-
- mov ecx,cbMem
- jecxz mc386_exit
-
- movzx edi,di
- movzx esi,si
- lds si,lpSrc
- les di,lpDst
- ;
- ; calculate differance of pointers in "selector" space
- ;
- mov ax,si ; DX:AX = lpSrc
- mov dx,ds
-
- mov bx,es ; BX = selector of ptr B
-
- mov cx,__AHSHIFT ; number of selector bits per 64K 'segment'
- shr dx,cl ; linearize ptr A
- shr bx,cl ; linearize ptr B
- ;
- ; DX and BX contain normalized selectors
- ;
- mov ecx,cbMem
-
- sub ax,di
- sbb dx,bx ; do long subtraction.
- jnc mc_copy_forward
-
- add ax,cx
- adc dx,cbMem.hi
- jnc mc_copy_forward ; carry, so >0, thus they do hit.
-
- std
- add edi,ecx
- add esi,ecx
-
- sub edi,4
- sub esi,4
-
- push ecx
- shr ecx,2 ; get count in DWORDs
- rep movs dword ptr es:[edi], dword ptr ds:[esi]
- db 67H ; Fix strange 386 bug
- add edi,3
- add esi,3
- pop ecx
- and ecx,3
- rep movs byte ptr es:[edi], byte ptr ds:[esi]
- db 67H ; Fix strange 386 bug
- jmp mc386_exit
-
- mc_copy_forward:
- push ecx
- shr ecx,2 ; get count in DWORDs
- rep movs dword ptr es:[edi], dword ptr ds:[esi]
- db 67H
- pop ecx
- and ecx,3
- rep movs byte ptr es:[edi], byte ptr ds:[esi]
- db 67H
- nop
- mc386_exit:
- cld
- pop esi
- pop edi
- mov dx,lpDst.sel ; return destination address
- mov ax,lpDst.off
- .286
- cEnd
-
- sEnd
-
- sEnd CodeSeg
- end
-