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

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

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