Конференция "Основная" » Инструкция ANDN (asm64)
 
  • dmk © (20.02.17 09:30) [0]
    Я так понял, что ANDN (Logical AND NOT) инструкция не поддерживается Delphi? У меня XE6. Компилятор говорит Undeclared identifier.
  • Rouse_ © (20.02.17 10:01) [1]
    нет конечно, ибо BMI1. (как и TZCNT)
    Она практически никакими декомпилерами не поддерживается.
    А AND + NOT использовать не судьба?
  • dmk © (20.02.17 10:03) [2]
    blsr, blsi, blsmsk тоже не поддерживает :( короче инструкции bmi1 и dmi2 в Delphi отсутствуют.
  • dmk © (20.02.17 10:06) [3]
    >А AND + NOT использовать не судьба?
    Мне байт надо превратить в 64 бита. Не знаю как лучше сделать.
    короче есть байт 10101111b, а нужно из него сделать FF00FF00FFFFFFFFh
    У меня сейчас таблица зарнее расчитана 8 -> 64, но очень медленно получается из памяти читать.
  • dmk © (20.02.17 10:16) [4]
    Сейчас через таблицу[0..255] работает:

    mov rdx, TableAddr
    movzx eax, byte ptr [rsi]
    shl ax, 3 //Смещение в таблице
    mov rax, [rdx+rax] //Читаем строку байтов
    mov [rdi], rax //Пишем готовую строку


    Думал быстрее сделать.
  • Rouse_ © (20.02.17 10:21) [5]

    > dmk ©   (20.02.17 10:16) [4]

    Чет я слегка прифигел, нукась дай ка мне саму таблицу.
  • dmk © (20.02.17 10:27) [6]
    По описанию вроде bextr подходит, но она тоже bmi1 :(
  • dmk © (20.02.17 10:29) [7]
    Таблица расчитывается. Так не выложишь ;)
    //Процедура создает массив отображающий биты в Grayscale представлении
    //Пример: (10001111) = ($00 $FF $FF $FF $00 $00 $00 $00)
    //Используется для прорисовки при битности 1 Bpp
    //Массив занимает 1Кб
    procedure InitGrayBits;
    var
     i: byte; //Счетчик байтов
     bc: byte; //Счетчик битов

    begin
     for i := 0 to 255 do
     for bc := 0 to 7 do
       if GetBit(i, bc) then
         //Если бит установлен, то это черный цвет
         //Если не установлен, то прозрачная область, т.е. белый
         GrayBitsArray[i].Cell[7 - bc] := $00 else
         GrayBitsArray[i].Cell[7 - bc] := $FF;

     //Адрес начала массива
     GrayBitsAddr := TAddress(@GrayBitsArray[0].Cell[0]);
    end;
  • dmk © (20.02.17 10:31) [8]
    Вернее таблица занимает 2Кб
  • Rouse_ © (20.02.17 11:02) [9]
    Вот чесно говоря ничего не понятно :)
    Покажи процедуру с асмом полностью, ибо вот после этого:

    movzx eax, byte ptr [rsi]
    ...
    mov rax, [rdx+rax] //Читаем строку байтов

    без xor rax, rax имеешь шанс вылететь в трубу

    еще не понятно откуда RSI приходит
  • Rouse_ © (20.02.17 11:04) [10]
    хотя нет, про RAX это лишнее
  • dmk © (20.02.17 11:25) [11]
    Преобразует биты в байты:
    GrayBitsAddr - это таблица

    procedure BitsToBytes(Src, Dest, NumBits: uint64);
    asm
     .NOFRAME
     movq xmm0, rsi
     movq xmm1, rdi
     movq xmm2, rbx

     mov rdi, Dest //Адрес конечного буфера

     mov bl, Self.FIndexedMask
     mov rsi, Src //Адрес изображения
     mov rcx, NumBits //Кол-во бит для преобразования
     shr rcx, 3 //Делим на 8, т.к. читаем байты
     mov rdx, GrayBitsAddr //Массив Gray-представления битов
     mov r9, $FFFFFFFFFFFFFFFF
     xor rax, rax //Очистка

     cmp bl, 0
     je @@ClearMask

    @@NextByte:
     movzx eax, byte ptr [rsi] //Читаем байт изображения, или 8 Bitmap пикселей
     test al, al
     jz @@WriteWhite

     shl ax, 3 //Смещение в массиве GrayBits к нужной ячейке
     mov rax, [rdx+rax] //Читаем строку байтов из GrayBits в rax
     mov [rdi], rax //Пишем строку в конечный адрес
     jmp @@NextAddr

    @@WriteWhite:
     mov [rdi], r9  //Пишем нулевую строку в конечный адрес

    @@NextAddr:
     inc rsi //Смещение к следующему исходному байту изображения
     add rdi, 8 //Смещение в конечном адресе на 8 байт
     dec rcx
     jnz @@NextByte

     jmp @@Out

    @@ClearMask: //Каналы отключены, пишем нулевые пикселы
     mov [rdi], r9 //Пишем строку в конечный адрес
     add rdi, 8
     dec rcx
     jnz @@ClearMask

    @@Out:
     movq rbx, xmm2
     movq rdi, xmm1
     movq rsi, xmm0
    end;
  • Rouse_ © (20.02.17 11:37) [12]
    Ну в принципе норм. только вот так бы вот начало переписал:

    procedure BitsToBytes(Src, Dest, NumBits: uint64);
    asm
     .NOFRAME
     movq xmm0, rsi
     movq xmm1, rdi
     movq xmm2, rbx

     mov rdi, Dest //Адрес конечного буфера
     xor rax, rax //Очистка  

     mov bl, Self.FIndexedMask
     mov r9, $FFFFFFFFFFFFFFFF
     mov rcx, NumBits //Кол-во бит для преобразования
     shr rcx, 3 //Делим на 8, т.к. читаем байты  
     cmp bl, 0
     je @@ClearMask
     
     mov rsi, Src //Адрес изображения  
     mov rdx, GrayBitsAddr //Массив Gray-представления битов
  • Rouse_ © (20.02.17 11:40) [13]
    а, блин, за вот такое руки бы оторвать:
     movq xmm0, rsi
     movq xmm1, rdi
     movq xmm2, rbx

    у тебя чего стека нема?
    А если у меня там Extended лежит промежуточный?
  • dmk © (20.02.17 11:49) [14]
    Не, там ничего не лежит. Со стеком медленнее работает. Память все таки.

    Есть такой вариант, но он медленнее в 2 раза.
    procedure TImageStream.BitsToBytesShuf(Src, Dest, NumBits: uint64);
    const
     ShufMask: uint64 = $00000000000000FF;

    asm
     .NOFRAME
     movq xmm0, rsi
     movq xmm1, rdi
     movq xmm2, rbx

     mov rdi, Dest //Адрес конечного буфера

     mov r10b, Self.FIndexedMask
     mov rsi, Src //Адрес изображения
     mov rcx, NumBits //Кол-во бит для преобразования
     shr rcx, 3 //Делим на 8, т.к. читаем байты
     mov rdx, 8
     movq xmm4, ShufMask
     movq xmm5, xmm4

    @@NextByte:
     movzx rax, byte ptr [rsi] //Читаем байт изображения, или 8 Bitmap пикселей
     and al, r10b

     bt ax, 0
     setc bl
     shl rbx, 8

     bt ax, 1
     setc bl
     shl rbx, 8

     bt ax, 2
     setc bl
     shl rbx, 8

     bt ax, 3
     setc bl
     shl rbx, 8

     bt ax, 4
     setc bl
     shl rbx, 8

     bt ax, 5
     setc bl
     shl rbx, 8

     bt ax, 6
     setc bl
     shl rbx, 8

     bt ax, 7
     setc bl

     movq xmm3, rbx
     movq xmm4, xmm5
     pshufb xmm4, xmm3
     movq [rdi], xmm4 //Пишем строку в конечный адрес

     inc rsi //Смещение к следующему исходному байту изображения
     add rdi, rdx //Смещение в конечном адресе на 8 байт
     dec rcx
     jnz @@NextByte

    @@Out:
     movq rbx, xmm2
     movq rdi, xmm1
     movq rsi, xmm0
    end;
  • dmk © (20.02.17 11:52) [15]
    >А если у меня там Extended лежит промежуточный?

    In line with the x64 Application Binary Interface (ABI), the contents of the following registers must be preserved and restored within inline assembly functions: R12, R13, R14, R15, RDI, RSI, RBX, RBP, RSP, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15.

    Уже проверял. xmm0-xmm3 всегда свободны. Потому и использую как стек. Быстрее все рабоатет.
  • dmk © (20.02.17 12:02) [16]
    имбаркадеро вообще память копирует через FPU. Ничего - работает :)
  • Rouse_ © (20.02.17 12:08) [17]
    Да, это я уже заработался, у меня половина защиты через XMM и DR регистры выстроена.
    Ошибся.
  • dmk © (20.02.17 13:26) [18]
    Интересно, а как собрать самому последовательность?

    Кое что прочитал, но пока не понял как инструкцию собрать ;(

     //Наследственные префиксы 66H, 67H, F2H and F3H.
     //Используются для новых инструкций
     //Размещаются перед REX префиксом

     //1 bit w       Определяет данные как байт или полноразмерные, где полноразмерные это 16 или 32 бита (Таблица B-6)
     //1 bit s       Определяет знак поля данных (see Table B-7)
     //2 bit sreg2   Segment register specifier for CS, SS, DS, ES (see Table B-8)
     //3 bit sreg3   Segment register specifier for CS, SS, DS, ES, FS, GS (see Table B-8)
     //3 bit eee     Specifies a special-purpose (control or debug) register (Таблица B-9)
     //4 bit tttn    Для условных инструкций определяет состояние ASSERTED (Утвержденный) или NEGATED (Отрицается) (Таблица B-12)
     //1 bit d       Определяет направление операции (Таблица B-11)

     //REX префикс (Mod Reg* R/M) - 1 байт
     //7-6  Mod
     //5-3  Reg
     //2-0  R/M

     //SIB 1 байт
     //7-6  Scale
     //5-3  Index
     //2-0  Base

     //Поле reg  (3 бита) Определитель основных регистров (Таблица B-4 или B-5) для инструкций не содержащих поле W
     //000  AX | EAX | RAX
     //001  CX | ECX | RCX
     //010  DX | EDX | RDX
     //011  BX | EBX | RBX
     //100  SP | ESP | RSP
     //101  BP | EBP | RBP
     //110  SI | ESI | RSI
     //111  DI | EDI | RDI

    REX W RXB           W   MOD REG R/M
    0100 1 100   1000 1001    11 000 010
    REX W RXB                       RAX RDX
    0100 1 000   1000 1001    11 010 011
                                          RDX RBX
  • Rouse_ © (20.02.17 13:50) [19]
    ну как в обычном ассемблирующем движке, у тебя даже REX префикс обозначен
 
Конференция "Основная" » Инструкция ANDN (asm64)
Есть новые Нет новых   [118241   +25][b:0][p:0.001]