diff --git a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
index 64b0595f45..d7e60ffdf9 100644
--- a/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+++ b/MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
@@ -66,6 +66,7 @@
   Ia32/SetMem16.S
   Ia32/SetMem.nasm
   Ia32/SetMem.S
+  Ia32/CopyMem.nasm
   Ia32/CopyMem.S
   Ia32/ScanMem64.nasm
   Ia32/ScanMem64.asm
@@ -87,6 +88,7 @@
   Ia32/SetMem16.asm
   Ia32/SetMem.nasm
   Ia32/SetMem.asm
+  Ia32/CopyMem.nasm
   Ia32/CopyMem.asm
 
 [Sources.X64]
diff --git a/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.nasm b/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.nasm
new file mode 100644
index 0000000000..491bdf2a0e
--- /dev/null
+++ b/MdePkg/Library/BaseMemoryLibRepStr/Ia32/CopyMem.nasm
@@ -0,0 +1,64 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+;   CopyMem.Asm
+;
+; Abstract:
+;
+;   CopyMem function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+    SECTION .text
+
+;------------------------------------------------------------------------------
+;  VOID *
+;  InternalMemCopyMem (
+;    IN VOID   *Destination,
+;    IN VOID   *Source,
+;    IN UINTN  Count
+;    )
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalMemCopyMem)
+ASM_PFX(InternalMemCopyMem):
+    push    esi
+    push    edi
+    mov     esi, [esp + 16]             ; esi <- Source
+    mov     edi, [esp + 12]             ; edi <- Destination
+    mov     edx, [esp + 20]             ; edx <- Count
+    lea     eax, [esi + edx - 1]        ; eax <- End of Source
+    cmp     esi, edi
+    jae     .0
+    cmp     eax, edi
+    jae     @CopyBackward               ; Copy backward if overlapped
+.0:
+    mov     ecx, edx
+    and     edx, 3
+    shr     ecx, 2
+    rep     movsd                       ; Copy as many Dwords as possible
+    jmp     @CopyBytes
+@CopyBackward:
+    mov     esi, eax                    ; esi <- End of Source
+    lea     edi, [edi + edx - 1]        ; edi <- End of Destination
+    std
+@CopyBytes:
+    mov     ecx, edx
+    rep     movsb                       ; Copy bytes backward
+    cld
+    mov     eax, [esp + 12]             ; eax <- Destination as return value
+    pop     edi
+    pop     esi
+    ret
+