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

📄 eficorecopymem.asm

📁 Next BIOS Source code : Extensible Firmware Interface
💻 ASM
字号:
      TITLE   EfiCoreCopyMem.asm: Optimized memory-copy routine

;------------------------------------------------------------------------------
;
; Copyright (c)  1999 - 2002 Intel Corporation. All rights reserved
; This software and associated documentation (if any) is furnished
; under a license and may only be used or copied in accordance
; with the terms of the license. Except as permitted by such
; license, no part of this software or documentation may be
; reproduced, stored in a retrieval system, or transmitted in any
; form or by any means without the express written consent of
; Intel Corporation.
;
;
; Module Name:
;
;   EfiCoreCopyMem.asm
; 
; Abstract:
; 
;   This is the code that supports IA32-optimized CopyMem service
;
;------------------------------------------------------------------------------

; PROC:PRIVATE
  .686P
  .MMX
  .MODEL SMALL
  .CODE

EfiCoreCopyMem  PROTO  C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD

;------------------------------------------------------------------------------
;  VOID
;  EfiCoreCopyMem (
;    IN VOID   *Destination,
;    IN VOID   *Source,
;    IN UINTN  Count
;    )
;------------------------------------------------------------------------------

EfiCoreCopyMem  PROC  C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
	LOCAL	MmxSave:QWORD

  mov   ecx, Count

  ; First off, make sure we have no overlap. That is to say,
  ;   if (Source == Destination)           => do nothing
  ;   if (Source + Count <= Destination)   => regular copy
  ;   if (Destination + Count <= Source)   => regular copy
  ;   otherwise, do a reverse copy
  mov   eax, Source
  add   eax, ecx                      ; Source + Count
  cmp   eax, Destination
  jle   _StartByteCopy

  mov   eax, Destination
  add   eax, ecx                      ; Dest + Count
  cmp   eax, Source
  jle   _StartByteCopy

  mov   eax, Source
  cmp   eax, Destination
  je    _CopyMemDone         
  jl    _CopyOverlapped               ; too bad -- overlaps

  ; Pick up misaligned start bytes to get destination pointer 4-byte aligned
_StartByteCopy:
  cmp   DWORD PTR ecx, 0
  je    _CopyMemDone                ; Count == 0, all done
  mov   edx, Destination
  and   dl, 3                       ; check lower 2 bits of address
  test  dl, dl			    
  je    SHORT _CopyBlocks           ; already aligned?

  ; Copy a byte
  mov   edx, Source
  mov   al, BYTE PTR [edx]          ; get byte from Source
  inc   edx
  mov   Source, edx   
  mov   edx, Destination
  mov   BYTE PTR [edx], al          ; write byte to Destination
  inc   edx
  mov   Destination, edx    
  dec	ecx
  jmp   _StartByteCopy        	     ; back to top of loop

_CopyBlocks:
  ; Compute how many 64-byte blocks we can clear 
  mov   eax, ecx                    ; get Count in eax
  shr   eax, 6                      ; convert to 64-byte count
  shl   eax, 6                      ; convert back to bytes
  sub   ecx, eax                    ; subtract from the original count
  shr   eax, 6                      ; and this is how many 64-byte blocks

  ; If no 64-byte blocks, then skip 
  cmp   eax, 0
  je    _CopyRemainingDWords

  ; Save mm0
  movq	MmxSave, mm0

  ; Put source and destination pointers in esi/edi
  push  edi
  push  esi

  mov   edi, Destination
  mov   esi, Source

ALIGN  16
copymmx:
  movq  mm0, QWORD PTR ds:[esi]
  movq  QWORD PTR ds:[edi], mm0
  movq  mm0, QWORD PTR ds:[esi+8]
  movq  QWORD PTR ds:[edi+8], mm0
  movq  mm0, QWORD PTR ds:[esi+16]
  movq  QWORD PTR ds:[edi+16], mm0
  movq  mm0, QWORD PTR ds:[esi+24]
  movq  QWORD PTR ds:[edi+24], mm0
  movq  mm0, QWORD PTR ds:[esi+32]
  movq  QWORD PTR ds:[edi+32], mm0
  movq  mm0, QWORD PTR ds:[esi+40]
  movq  QWORD PTR ds:[edi+40], mm0
  movq  mm0, QWORD PTR ds:[esi+48]
  movq  QWORD PTR ds:[edi+48], mm0
  movq  mm0, QWORD PTR ds:[esi+56]
  movq  QWORD PTR ds:[edi+56], mm0
  add   edi, 64
  add   esi, 64
  dec  eax
  jnz  copymmx
  
; Restore mm0
  movq	mm0, MmxSave

_CopyRemaining:
  ; Copy advanced source and destination pointers back to memory
  mov   Destination, edi      ; write back advanced destination pointer
  mov   Source, esi     ; write back advanced source pointer
  pop   esi
  pop   edi

  ; Copy as many DWORDS as possible
_CopyRemainingDWords:
  cmp   ecx, 4
  jb    _CopyRemainingBytes

  mov   edx, Source
  mov   eax, DWORD PTR [edx]        ; get data from Source
  add   edx, 4                      ; advance Source pointer
  mov   Source, edx   ; write Source pointer back
  mov   edx, Destination
  mov   DWORD PTR [edx], eax        ; write byte to Destination
  add   edx, 4                      ; advance Destination pointer
  mov   Destination, edx    
  sub   ecx, 4                      ; decrement Count
  jmp   _CopyRemainingDWords  	    ; back to top

_CopyRemainingBytes:
  cmp   ecx, 0
  je    _CopyMemDone
  mov   edx, Source
  mov   al, BYTE PTR [edx]          ; get byte from Source
  inc	edx
  mov   Source, edx   
  mov   edx, Destination
  mov   BYTE PTR [edx], al          ; write byte to Destination
  add   edx, 1                      ; advance Destination pointer
  mov   Destination, edx    
  dec	ecx
  jmp   SHORT _CopyRemainingBytes   ; back to top of loop

  ;
  ; We do this block if the source and destination buffers overlap. To
  ; handle it, copy starting at the end of the source buffer and work
  ; your way back. Since this is the atypical case, this code has not
  ; been optimized, and thus simply copies bytes.
  ;
_CopyOverlapped:
   
  ; Move the source and destination pointers to the end of the range
  mov   eax, Source
  add   eax, ecx                      ; Source + Count
  dec	eax
  mov   Source, eax
  mov   eax, Destination
  add   eax, ecx                      ; Dest + Count
  dec	eax
  mov   Destination, eax      

_CopyOverlappedLoop:
  cmp   ecx, 0
  je    _CopyMemDone
  mov   edx, Source
  mov   al, BYTE PTR [edx]          ; get byte from Source
  dec	edx
  mov   Source, edx   
  mov   edx, Destination
  mov   BYTE PTR [edx], al          ; write byte to Destination
  dec   edx
  mov   Destination, edx    
  dec	ecx
  jmp   _CopyOverlappedLoop   	    ; back to top of loop

_CopyMemDone:
  ret
  
EfiCoreCopyMem  ENDP
  END

⌨️ 快捷键说明

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