Скачиваний:
29
Добавлен:
01.05.2014
Размер:
14.02 Кб
Скачать

// Функции для работы с блоками памяти, массивами //
// одинарных и двойных слов, множествами в виде //
// таких массивов, битами в составе двойного слова //
// и битовыми строками. //

unit uBinary;

interface

uses uConsts;
{ Разные функции }

{ G_Log2 возвращает число, равное логарифму числа L по основанию 2.
Другими словами, функция возвращает индекс самого старшего ненулевого
бита в числе L. Если L равно 0, функция возвращает 0. }

function G_Log2(L: LongWord): LongWord;

{ G_CeilPowerOfTwo возвращает число, равное 2 в степени N, большее или
равное L (N - целое число). Если L равно 0, функция возвращает 1. Если
L больше $80000000, функция возвращает 0. }

function G_CeilPowerOfTwo(L: LongWord): LongWord;

{ G_IncPowerOfTwo возвращает число, равное 2 в степени N, большее L (N -
целое число). Если L равно 0, функция возвращает 1. Если L больше или
равно $80000000, функция возвращает 0. }

function G_IncPowerOfTwo(L: LongWord): LongWord;


{ Функции для работы с массивами двойных слов }


{ G_FillLongs заполняет массив элементов типа LongWord (или любого другого
4-байтного типа), указываемый параметром P, значением L. Количество
элементов в массиве передается параметром Count. }

procedure G_FillLongs(L: LongWord; P: Pointer; Count: Cardinal);

{ G_CopyLongs копирует Count элементов массива типа LongWord (или другого
4-байтного типа, например, Integer или Pointer) из области памяти,
указываемой параметром Source, в область памяти, указываемую параметром
Dest. Области памяти не должны перекрываться. }

procedure G_CopyLongs(Source, Dest: Pointer; Count: Cardinal);

{ G_MoveLongs копирует Count элементов массива типа LongWord (или другого
4-байтного типа) из области памяти, указываемой параметром Source, в
область памяти, указываемую параметром Dest. Эта процедура должна
применяться в случае, если области памяти могут перекрываться. }

procedure G_MoveLongs(Source, Dest: Pointer; Count: Cardinal);

{ G_SameLongs выполняет побайтное сравнение массивов 4-байтных элементов
(например, типа Integer), адресуемых P1 и P2. Количество элементов в каждом
из массивов задается параметром Count. Функция возвращает True, если все
соответствующие элементы обоих массивов равны, в противном случае возвращает
False. }
function G_SameLongs(P1, P2: Pointer; Count: Cardinal): Boolean;

{ Поиск, замена, подсчет, удаление значений в массиве одинарных и двойных слов }

{ Следующие функции G_Scan_... находят число, переданное первым параметром,
в массиве 4-байтных значений, адрес которого передан параметром ArrPtr.
Параметр Count задает количество элементов в массиве. Поиск выполняется
с начала массива. Индекс первого найденного элемента массива возвращается
как результат функции (элементы нумеруются с нуля). Если число не найдено
в массиве, функция возвращает -1. }
function G_Scan_Pointer(P: Pointer; ArrPtr: Pointer; Count: Cardinal): Integer;


{ Функции для работы с битами в составе двойного слова }

{ Массив BitMasks32 содержит маску для каждого бита в составе двойного слова
типа LongWord. Значение, маскирующее бит, можно получить обратившись к
элементу массива с индексом, соответствующим номеру бита. }

const
BitMasks32: array[0..31] of LongWord =
($00000001,$00000002,$00000004,$00000008,$00000010,$00000020,$00000040,$00000080,
$00000100,$00000200,$00000400,$00000800,$00001000,$00002000,$00004000,$00008000,
$00010000,$00020000,$00040000,$00080000,$00100000,$00200000,$00400000,$00800000,
$01000000,$02000000,$04000000,$08000000,$10000000,$20000000,$40000000,$80000000);

implementation

{ Разные функции }

function G_Log2(L: LongWord): LongWord;
asm
TEST EAX,EAX
JE @@zq
BSR EAX,EAX
@@zq:
end;

function G_CeilPowerOfTwo(L: LongWord): LongWord;
asm
TEST EAX,EAX
JE @@zq
BSR EDX,EAX
BSF ECX,EAX
CMP EDX,ECX
JNE @@nx
RET
@@zq: MOV EAX,1
RET
@@nx: INC EDX
TEST EAX,$80000000
JNE @@ov
MOV EAX,DWORD PTR [EDX*4+BitMasks32]
RET
@@ov: XOR EAX,EAX
end;

function G_IncPowerOfTwo(L: LongWord): LongWord;
asm
TEST EAX,EAX
JE @@zq
TEST EAX,$80000000
JNE @@ov
BSR EDX,EAX
INC EDX
MOV EAX,DWORD PTR [EDX*4+BitMasks32]
RET
@@zq: MOV EAX,1
RET
@@ov: XOR EAX,EAX
end;

{ Функции для работы с массивами двойных слов }

procedure G_FillLongs(L: LongWord; P: Pointer; Count: Cardinal);
asm
CMP ECX,35
JBE @@xx
MOV [EDX],EAX
MOV [EDX+4],EAX
TEST EDX,4
JE @@nx1
MOV [EDX+8],EAX
ADD EDX,4
DEC ECX
@@nx1: MOVQ MM0,[EDX]
SUB ECX,2
ADD EDX,8
@@lp: SUB ECX,32
JS @@nx2
MOVQ [EDX],MM0
MOVQ [EDX+8],MM0
MOVQ [EDX+16],MM0
MOVQ [EDX+24],MM0
MOVQ [EDX+32],MM0
MOVQ [EDX+40],MM0
MOVQ [EDX+48],MM0
MOVQ [EDX+56],MM0
MOVQ [EDX+64],MM0
MOVQ [EDX+72],MM0
MOVQ [EDX+80],MM0
MOVQ [EDX+88],MM0
MOVQ [EDX+96],MM0
MOVQ [EDX+104],MM0
MOVQ [EDX+112],MM0
MOVQ [EDX+120],MM0
ADD EDX,128
JMP @@lp
@@nx2: ADD ECX,32
@@xx: JMP DWORD PTR @@wV[ECX*4]
@@wV: DD @@w00, @@w01, @@w02, @@w03
DD @@w04, @@w05, @@w06, @@w07
DD @@w08, @@w09, @@w10, @@w11
DD @@w12, @@w13, @@w14, @@w15
DD @@w16, @@w17, @@w18, @@w19
DD @@w20, @@w21, @@w22, @@w23
DD @@w24, @@w25, @@w26, @@w27
DD @@w28, @@w29, @@w30, @@w31
DD @@w32, @@w33, @@w34, @@w35
@@w35: MOV [EDX+ECX*4-140],EAX
@@w34: MOV [EDX+ECX*4-136],EAX
@@w33: MOV [EDX+ECX*4-132],EAX
@@w32: MOV [EDX+ECX*4-128],EAX
@@w31: MOV [EDX+ECX*4-124],EAX
@@w30: MOV [EDX+ECX*4-120],EAX
@@w29: MOV [EDX+ECX*4-116],EAX
@@w28: MOV [EDX+ECX*4-112],EAX
@@w27: MOV [EDX+ECX*4-108],EAX
@@w26: MOV [EDX+ECX*4-104],EAX
@@w25: MOV [EDX+ECX*4-100],EAX
@@w24: MOV [EDX+ECX*4-96],EAX
@@w23: MOV [EDX+ECX*4-92],EAX
@@w22: MOV [EDX+ECX*4-88],EAX
@@w21: MOV [EDX+ECX*4-84],EAX
@@w20: MOV [EDX+ECX*4-80],EAX
@@w19: MOV [EDX+ECX*4-76],EAX
@@w18: MOV [EDX+ECX*4-72],EAX
@@w17: MOV [EDX+ECX*4-68],EAX
@@w16: MOV [EDX+ECX*4-64],EAX
@@w15: MOV [EDX+ECX*4-60],EAX
@@w14: MOV [EDX+ECX*4-56],EAX
@@w13: MOV [EDX+ECX*4-52],EAX
@@w12: MOV [EDX+ECX*4-48],EAX
@@w11: MOV [EDX+ECX*4-44],EAX
@@w10: MOV [EDX+ECX*4-40],EAX
@@w09: MOV [EDX+ECX*4-36],EAX
@@w08: MOV [EDX+ECX*4-32],EAX
@@w07: MOV [EDX+ECX*4-28],EAX
@@w06: MOV [EDX+ECX*4-24],EAX
@@w05: MOV [EDX+ECX*4-20],EAX
@@w04: MOV [EDX+ECX*4-16],EAX
@@w03: MOV [EDX+ECX*4-12],EAX
@@w02: MOV [EDX+ECX*4-8],EAX
@@w01: MOV [EDX+ECX*4-4],EAX
@@w00: EMMS
end;

procedure G_CopyLongs(Source, Dest: Pointer; Count: Cardinal);
asm
@@lp: SUB ECX,16
JS @@nx
MOVQ MM0,[EAX]
MOVQ MM1,[EAX+8]
MOVQ MM2,[EAX+16]
MOVQ MM3,[EAX+24]
MOVQ MM4,[EAX+32]
MOVQ MM5,[EAX+40]
MOVQ MM6,[EAX+48]
MOVQ MM7,[EAX+56]
MOVQ [EDX],MM0
MOVQ [EDX+8],MM1
MOVQ [EDX+16],MM2
MOVQ [EDX+24],MM3
MOVQ [EDX+32],MM4
MOVQ [EDX+40],MM5
MOVQ [EDX+48],MM6
MOVQ [EDX+56],MM7
ADD EAX,64
ADD EDX,64
JMP @@lp
@@nx: ADD ECX,16
PUSH EBX
JMP DWORD PTR @@wV[ECX*4]
@@wV: DD @@w00, @@w01, @@w02, @@w03
DD @@w04, @@w05, @@w06, @@w07
DD @@w08, @@w09, @@w10, @@w11
DD @@w12, @@w13, @@w14, @@w15
@@w15: MOV EBX,[EAX+ECX*4-60]
MOV [EDX+ECX*4-60],EBX
@@w14: MOV EBX,[EAX+ECX*4-56]
MOV [EDX+ECX*4-56],EBX
@@w13: MOV EBX,[EAX+ECX*4-52]
MOV [EDX+ECX*4-52],EBX
@@w12: MOV EBX,[EAX+ECX*4-48]
MOV [EDX+ECX*4-48],EBX
@@w11: MOV EBX,[EAX+ECX*4-44]
MOV [EDX+ECX*4-44],EBX
@@w10: MOV EBX,[EAX+ECX*4-40]
MOV [EDX+ECX*4-40],EBX
@@w09: MOV EBX,[EAX+ECX*4-36]
MOV [EDX+ECX*4-36],EBX
@@w08: MOV EBX,[EAX+ECX*4-32]
MOV [EDX+ECX*4-32],EBX
@@w07: MOV EBX,[EAX+ECX*4-28]
MOV [EDX+ECX*4-28],EBX
@@w06: MOV EBX,[EAX+ECX*4-24]
MOV [EDX+ECX*4-24],EBX
@@w05: MOV EBX,[EAX+ECX*4-20]
MOV [EDX+ECX*4-20],EBX
@@w04: MOV EBX,[EAX+ECX*4-16]
MOV [EDX+ECX*4-16],EBX
@@w03: MOV EBX,[EAX+ECX*4-12]
MOV [EDX+ECX*4-12],EBX
@@w02: MOV EBX,[EAX+ECX*4-8]
MOV [EDX+ECX*4-8],EBX
@@w01: MOV EBX,[EAX+ECX*4-4]
MOV [EDX+ECX*4-4],EBX
@@w00: POP EBX
EMMS
end;

procedure G_MoveLongs(Source, Dest: Pointer; Count: Cardinal);
asm
CMP EDX,EAX
JA @@bm
JE @@qt
CALL G_CopyLongs
@@qt: RET
@@bm: SHL ECX,2
ADD EAX,ECX
ADD EDX,ECX
@@lp: SUB ECX,64
JS @@nx
SUB EAX,64
SUB EDX,64
MOVQ MM0,[EAX]
MOVQ MM1,[EAX+8]
MOVQ MM2,[EAX+16]
MOVQ MM3,[EAX+24]
MOVQ MM4,[EAX+32]
MOVQ MM5,[EAX+40]
MOVQ MM6,[EAX+48]
MOVQ MM7,[EAX+56]
MOVQ [EDX],MM0
MOVQ [EDX+8],MM1
MOVQ [EDX+16],MM2
MOVQ [EDX+24],MM3
MOVQ [EDX+32],MM4
MOVQ [EDX+40],MM5
MOVQ [EDX+48],MM6
MOVQ [EDX+56],MM7
JMP @@lp
@@nx: ADD ECX,64
SUB EAX,ECX
SUB EDX,ECX
JMP DWORD PTR @@wV[ECX]
@@wV: DD @@w00, @@w01, @@w02, @@w03
DD @@w04, @@w05, @@w06, @@w07
DD @@w08, @@w09, @@w10, @@w11
DD @@w12, @@w13, @@w14, @@w15
@@w15: MOV ECX,[EAX+56]
MOV [EDX+56],ECX
@@w14: MOV ECX,[EAX+52]
MOV [EDX+52],ECX
@@w13: MOV ECX,[EAX+48]
MOV [EDX+48],ECX
@@w12: MOV ECX,[EAX+44]
MOV [EDX+44],ECX
@@w11: MOV ECX,[EAX+40]
MOV [EDX+40],ECX
@@w10: MOV ECX,[EAX+36]
MOV [EDX+36],ECX
@@w09: MOV ECX,[EAX+32]
MOV [EDX+32],ECX
@@w08: MOV ECX,[EAX+28]
MOV [EDX+28],ECX
@@w07: MOV ECX,[EAX+24]
MOV [EDX+24],ECX
@@w06: MOV ECX,[EAX+20]
MOV [EDX+20],ECX
@@w05: MOV ECX,[EAX+16]
MOV [EDX+16],ECX
@@w04: MOV ECX,[EAX+12]
MOV [EDX+12],ECX
@@w03: MOV ECX,[EAX+8]
MOV [EDX+8],ECX
@@w02: MOV ECX,[EAX+4]
MOV [EDX+4],ECX
@@w01: MOV ECX,[EAX]
MOV [EDX],ECX
@@w00: EMMS
end;

function G_SameLongs(P1, P2: Pointer; Count: Cardinal): Boolean;
asm
CMP EAX,EDX
JE @@ex
PUSH ESI
PUSH EBX
MOV ESI,ECX
AND ECX,$7
SHR ESI,3
JE @@nx
@@lp1: MOV EBX,[EAX]
CMP EBX,[EDX]
JNE @@zq1
MOV EBX,[EAX+4]
CMP EBX,[EDX+4]
JNE @@zq1
MOV EBX,[EAX+8]
CMP EBX,[EDX+8]
JNE @@zq1
MOV EBX,[EAX+12]
CMP EBX,[EDX+12]
JNE @@zq1
MOV EBX,[EAX+16]
CMP EBX,[EDX+16]
JNE @@zq1
MOV EBX,[EAX+20]
CMP EBX,[EDX+20]
JNE @@zq1
MOV EBX,[EAX+24]
CMP EBX,[EDX+24]
JNE @@zq1
MOV EBX,[EAX+28]
CMP EBX,[EDX+28]
JNE @@zq1
ADD EAX,32
ADD EDX,32
DEC ESI
JNE @@lp1
@@nx: JMP DWORD PTR @@tV[ECX*4]
@@ex: MOV EAX,1
RET
@@tV: DD @@tu0, @@tu1, @@tu2, @@tu3
DD @@tu4, @@tu5, @@tu6, @@tu7
@@zq1: POP EBX
POP ESI
XOR EAX,EAX
RET
@@tu7: MOV EBX,[EAX+ECX*4-28]
CMP EBX,[EDX+ECX*4-28]
JNE @@zq2
@@tu6: MOV EBX,[EAX+ECX*4-24]
CMP EBX,[EDX+ECX*4-24]
JNE @@zq2
@@tu5: MOV EBX,[EAX+ECX*4-20]
CMP EBX,[EDX+ECX*4-20]
JNE @@zq2
@@tu4: MOV EBX,[EAX+ECX*4-16]
CMP EBX,[EDX+ECX*4-16]
JNE @@zq2
@@tu3: MOV EBX,[EAX+ECX*4-12]
CMP EBX,[EDX+ECX*4-12]
JNE @@zq2
@@tu2: MOV EBX,[EAX+ECX*4-8]
CMP EBX,[EDX+ECX*4-8]
JNE @@zq2
@@tu1: MOV EBX,[EAX+ECX*4-4]
CMP EBX,[EDX+ECX*4-4]
JNE @@zq2
@@tu0: POP EBX
POP ESI
MOV EAX,1
RET
@@zq2: POP EBX
POP ESI
XOR EAX,EAX
end;

{ Поиск, замена, подсчет, удаление значений в массиве одинарных и двойных слов }

function G_Scan_Pointer(P: Pointer; ArrPtr: Pointer; Count: Cardinal): Integer;
asm
TEST ECX,ECX
JE @@m1
PUSH EDI
MOV EDI,EDX
REPNE SCASD
JNE @@m2
MOV EAX,EDI
SUB EAX,EDX
POP EDI
SHR EAX,2
DEC EAX
RET
@@m2: POP EDI
@@m1: MOV EAX,$FFFFFFFF
end;

end.

Соседние файлы в папке utils