1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
;/*++
;
;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:
;
; EfiZeroMem.c
;
;Abstract:
;
; This is the code that supports IA32-optimized ZeroMem service
;
;--*/
;---------------------------------------------------------------------------
.686
.model flat,C
.mmx
.code
;---------------------------------------------------------------------------
;VOID
;EfiCommonLibZeroMem (
; IN VOID *Buffer,
; IN UINTN Count
; )
;/*++
;
;Input: VOID *Buffer - Pointer to buffer to clear
; UINTN Count - Number of bytes to clear
;
;Output: None.
;
;Saves:
;
;Modifies:
;
;Description: This function is an optimized zero-memory function.
;
;Notes: This function tries to zero memory 8 bytes at a time. As a result,
; it first picks up any misaligned bytes, then words, before getting
; in the main loop that does the 8-byte clears.
;
;--*/
EfiCommonLibZeroMem PROC
; UINT64 MmxSave;
push ebp
mov ebp, esp
push ecx ; Reserve space for local variable MmxSave
push ecx
push edi
mov ecx, [ebp + 0Ch] ; Count
mov edi, [ebp + 8]; Buffer
; Pick up misaligned start bytes (get pointer 4-byte aligned)
_StartByteZero:
mov eax, edi
and al, 3 ; check lower 2 bits of address
test al, al
je _ZeroBlocks ; already aligned?
cmp ecx, 0
je _ZeroMemDone
; Clear the byte memory location
mov BYTE PTR [edi], 0
inc edi
; Decrement our count
dec ecx
jmp _StartByteZero ; back to top of loop
_ZeroBlocks:
; Compute how many 64-byte blocks we can clear
mov edx, ecx
shr ecx, 6 ; convert to 64-byte count
shl ecx, 6 ; convert back to bytes
sub edx, ecx ; subtract from the original count
shr ecx, 6 ; and this is how many 64-byte blocks
; If no 64-byte blocks, then skip
cmp ecx, 0
je _ZeroRemaining
; Save mm0
movq [ebp - 8], mm0 ; Save mm0 to MmxSave
pxor mm0, mm0 ; Clear mm0
_B:
movq QWORD PTR ds:[edi], mm0
movq QWORD PTR ds:[edi+8], mm0
movq QWORD PTR ds:[edi+16], mm0
movq QWORD PTR ds:[edi+24], mm0
movq QWORD PTR ds:[edi+32], mm0
movq QWORD PTR ds:[edi+40], mm0
movq QWORD PTR ds:[edi+48], mm0
movq QWORD PTR ds:[edi+56], mm0
add edi, 64
dec ecx
jnz _B
; Restore mm0
movq mm0, [ebp - 8] ; Restore mm0 from MmxSave
emms ; Exit MMX Instruction
_ZeroRemaining:
; Zero out as many DWORDS as possible
mov ecx, edx
shr ecx, 2
xor eax, eax
rep stosd
; Zero out remaining as bytes
mov ecx, edx
and ecx, 03
rep stosb
_ZeroMemDone:
pop edi
leave
ret
EfiCommonLibZeroMem ENDP
END
|