Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2018.04.08;
Скачать: CL | DM;

Вниз

Перегружаемый код   Найти похожие ветки 

 
Dmk ©   (2016-04-11 16:34) [0]

Привет! Существует ли такая возможность, чтобы в переменную поместить байт-код и исполнить его? О перегружаемых функциях я знаю - использую. Хочется что то вроде код по выбору:

a := begin b+cy; d*ay; e * ty; end;
или
a := begin b+cx; d*ax; e * tx; end;

а потом Call(a)


 
Rouse_ ©   (2016-04-11 16:40) [1]

возьми паскальскрипт или LUA и передавай туда все прямо в таком виде, не забывая инициализировать контекст.


 
Sha ©   (2016-04-11 17:52) [2]

есть же процедурные переменные


 
Юрий Зотов ©   (2016-04-11 18:00) [3]

Если система допускает исполнение кода в стеке (Win32 допускает), то можно в процедуру передать даже машинный код и выполнить его.


 
DVM ©   (2016-04-11 18:00) [4]


> Dmk ©   (11.04.16 16:34) 


>  в переменную поместить байт-код

Этот твой код он в виде текста в программу попадает извне?


 
Dmk ©   (2016-04-11 18:20) [5]

Ищу замену inline asm, только для 64 бит. Не хватает очень. В 32 битах работает, а в 64 - нет. Просто писать кучу разных перегружаемых функций напрягает. У меня получается 4-6 функций, которые делают одно и то же, но код разный: код от Delphi-компилятора, код для MMX, код для SSE, код для SSSE3 и т.д., а там всего то разница в 2-3 строки, которые перегрузить и все.

В inline можно сделать так: db FA,C0, 20, 01, что по сути является исполняемым кодом. Вот и подумалось, что код в переменную загрузить и поменять по ходу исполнения в зависимости от условий.


 
Dmk ©   (2016-04-11 18:22) [6]

Да и оптимизация кода Delphi-компилятора никакая.


 
Dmk ©   (2016-04-11 18:55) [7]

И еще inline потом, что лишний call на больших количествах операций сильно заметен.


 
Rouse_ ©   (2016-04-11 19:33) [8]


> Dmk ©   (11.04.16 18:20) [5]
> Ищу замену inline asm, только для 64 бит.

выноси в отдельные функции, целиком написанные на асме и вызывай их.
В чем проблема? Я так и делаю.


 
Rouse_ ©   (2016-04-11 19:35) [9]

Вот к примеру кусок тебе живого кода:

function ZwQueryInformationProcessEx(
 ProcessInformationClass: Integer;
 ProcessInformation: Pointer;
 ProcessInformationLength: Cardinal): DWORD;
var
 SysCallArgument: ULONG_PTR;
 aProcessInformationClass: Integer;
 aProcessInformation: Pointer;
 aProcessInformationLength: Cardinal;
asm
{$IFDEF WIN32}
     mov  SAVED_EBP, ebp
     mov  SAVED_ESP, esp

     mov  aProcessInformationClass, eax
     mov  eax, ProcessInformation
     mov  aProcessInformation, eax
     mov  eax, ProcessInformationLength
     mov  aProcessInformationLength, eax

     mov  al, cfNtQueryInformationProcess
     call GetSysCallArgument
     mov  SysCallArgument, eax

     push  0
     push  aProcessInformationLength
     push  aProcessInformation
     push  aProcessInformationClass
     push  $FFFFFFFF

     cmp  fs:[$C0], 0
     jz   @32Bit

     mov eax, SysCallArgument
     lea edx, [esp]
     xor ecx, ecx
     call RunWow64
     jmp @FINALIZE

   @32Bit:
     push 0
     mov eax, SysCallArgument
     call RunSysEnter

   @FINALIZE:
     mov   ebp, SAVED_EBP
     mov   esp, SAVED_ESP
{$ELSE}
     mov  SAVED_EBP, rbp
     mov  SAVED_ESP, rsp

     sub rsp, $40

     mov  aProcessInformationClass, ecx
     mov  aProcessInformation, rdx
     mov  aProcessInformationLength, r8d

     mov  rcx, cfNtQueryInformationProcess
     call GetSysCallArgument
     mov  SysCallArgument, rax

     or   rcx, -1
     xor  rdx, rdx
     mov  edx, aProcessInformationClass
     mov  r8, aProcessInformation
     xor  r9, r9
     mov  r9d, aProcessInformationLength
     mov  qword ptr [rsp+$20], 0

     mov rax, SysCallArgument
     call RunSysCall

     mov rbp, SAVED_EBP
     mov rsp, SAVED_ESP
{$ENDIF}
end;


 
Dmk ©   (2016-04-11 20:31) [10]

Rouse_ ©   (11.04.16 19:35) [9]
Так я так и делаю. Вот например процедура:
function BlendPixelMMX(APixel, AColor: TColorRef; Alpha, Opacity: byte): dword;
const
 ShufMask: uint64 = $0100010001000100;

asm
 pxor mm0, mm0
 pxor mm1, mm1
 movq mm2, ShufMask

 movd mm4, APixel
 punpcklbw mm0, mm4
 psrld mm0, 8

 movd mm5, AColor
 punpcklbw mm1, mm5
 psrld mm1, 8

 movzx eax, Alpha
 inc eax
 movzx r11d, Opacity
 mul eax, r11d
 shr ax, 8
 mov dx, ax
 xor dx, $FF

 inc edx
 movd mm3, edx
 pshufb mm3, mm2

 inc eax
 movd mm4, eax
 pshufb mm4, mm2

 pmullw mm1, mm4
 pmullw mm0, mm3
 paddusw mm0, mm1
 psrlw mm0, 8

 packuswb mm0, mm0
 movd eax, mm0
end;


Все замечательно, кроме того, что нужна еще такая же на паскале:
procedure BlendPixel(dA: TAddress; AColor: TColorRef; Alpha, Opacity: byte);
var
 lpAlpha: word;
 lpADif: word;
 lpBR, lpBG, lpBB: word;

begin
 lpAlpha := (((Alpha + 1) * Opacity) shr 8);
 lpADif := (lpAlpha xor $FF) + 1;
 lpAlpha := lpAlpha + 1;

 lpBR := TFColorRef(AColor).r * lpAlpha;
 lpBG := TFColorRef(AColor).g * lpAlpha;
 lpBB := TFColorRef(AColor).b * lpAlpha;

 TFColorRef(PDWord(dA)^).r := ((TFColorRef(PDWord(dA)^).r * lpADif + lpBR) shr 8);
 TFColorRef(PDWord(dA)^).g := ((TFColorRef(PDWord(dA)^).g * lpADif + lpBG) shr 8);
 TFColorRef(PDWord(dA)^).b := ((TFColorRef(PDWord(dA)^).b * lpADif + lpBB) shr 8);
end;


И тут все замечательно кроме одного - плохой оптимизации. Delphi генерит ужасный код.
ScreenBitmap64.pas.353: begin
000000000070DA30 55               push rbp
000000000070DA31 4883EC10         sub rsp,$10
000000000070DA35 488BEC           mov rbp,rsp
000000000070DA38 48894D20         mov [rbp+$20],rcx
000000000070DA3C 895528           mov [rbp+$28],edx
000000000070DA3F 44884530         mov [rbp+$30],r8b
000000000070DA43 44884D38         mov [rbp+$38],r9b
ScreenBitmap64.pas.355: lpAlpha := (((Alpha + 1) * Opacity) shr 8);
000000000070DA47 480FB64530       movzx rax,byte ptr [rbp+$30]
000000000070DA4C 83C001           add eax,$01
000000000070DA4F 480FB64D38       movzx rcx,byte ptr [rbp+$38]
000000000070DA54 0FAFC1           imul eax,ecx
000000000070DA57 C1E808           shr eax,$08
000000000070DA5A 6689450E         mov [rbp+$0e],ax
ScreenBitmap64.pas.357: lpADif := (lpAlpha xor $FF) + 1;
000000000070DA5E 480FB7450E       movzx rax,word ptr [rbp+$0e]
000000000070DA63 6681F0FF00       xor ax,$00ff
000000000070DA68 6683C001         add ax,$01
000000000070DA6C 6689450C         mov [rbp+$0c],ax
ScreenBitmap64.pas.359: lpAlpha := lpAlpha + 1;
000000000070DA70 6683450E01       add word ptr [rbp+$0e],$01
ScreenBitmap64.pas.362: lpBR := TFColorRef(AColor).r * lpAlpha;
000000000070DA75 660FB6452A       movzx ax,byte ptr [rbp+$2a]
000000000070DA7A 660FAF450E       imul ax,[rbp+$0e]
000000000070DA7F 6689450A         mov [rbp+$0a],ax
ScreenBitmap64.pas.363: lpBG := TFColorRef(AColor).g * lpAlpha;
000000000070DA83 660FB64529       movzx ax,byte ptr [rbp+$29]
000000000070DA88 660FAF450E       imul ax,[rbp+$0e]
000000000070DA8D 66894508         mov [rbp+$08],ax
ScreenBitmap64.pas.364: lpBB := TFColorRef(AColor).b * lpAlpha;
000000000070DA91 660FB64528       movzx ax,byte ptr [rbp+$28]
000000000070DA96 660FAF450E       imul ax,[rbp+$0e]
000000000070DA9B 66894506         mov [rbp+$06],ax
ScreenBitmap64.pas.367: TFColorRef(PDWord(dA)^).r := ((TFColorRef(PDWord(dA)^).r * lpADif + lpBR) shr 8);
000000000070DA9F 488B4520         mov rax,[rbp+$20]
000000000070DAA3 488B4D20         mov rcx,[rbp+$20]
000000000070DAA7 480FB64902       movzx rcx,byte ptr [rcx+$02]
000000000070DAAC 0FB7550C         movzx edx,word ptr [rbp+$0c]
000000000070DAB0 0FAFCA           imul ecx,edx
000000000070DAB3 0FB7550A         movzx edx,word ptr [rbp+$0a]
000000000070DAB7 03CA             add ecx,edx
000000000070DAB9 C1E908           shr ecx,$08
000000000070DABC 884802           mov [rax+$02],cl
ScreenBitmap64.pas.368: TFColorRef(PDWord(dA)^).g := ((TFColorRef(PDWord(dA)^).g * lpADif + lpBG) shr 8);
000000000070DABF 488B4520         mov rax,[rbp+$20]
000000000070DAC3 488B4D20         mov rcx,[rbp+$20]
000000000070DAC7 480FB64901       movzx rcx,byte ptr [rcx+$01]
000000000070DACC 0FB7550C         movzx edx,word ptr [rbp+$0c]
000000000070DAD0 0FAFCA           imul ecx,edx
000000000070DAD3 0FB75508         movzx edx,word ptr [rbp+$08]
000000000070DAD7 03CA             add ecx,edx
000000000070DAD9 C1E908           shr ecx,$08
000000000070DADC 884801           mov [rax+$01],cl
ScreenBitmap64.pas.369: TFColorRef(PDWord(dA)^).b := ((TFColorRef(PDWord(dA)^).b * lpADif + lpBB) shr 8);
000000000070DADF 488B4520         mov rax,[rbp+$20]
000000000070DAE3 488B4D20         mov rcx,[rbp+$20]
000000000070DAE7 480FB609         movzx rcx,byte ptr [rcx]
000000000070DAEB 0FB7550C         movzx edx,word ptr [rbp+$0c]
000000000070DAEF 0FAFCA           imul ecx,edx
000000000070DAF2 0FB75506         movzx edx,word ptr [rbp+$06]
000000000070DAF6 03CA             add ecx,edx
000000000070DAF8 C1E908           shr ecx,$08
000000000070DAFB 8808             mov [rax],cl
ScreenBitmap64.pas.370: end;
000000000070DAFD 488D6510         lea rsp,[rbp+$10]
000000000070DB01 5D               pop rbp
000000000070DB02 C3               ret


 
Dmk ©   (2016-04-11 20:34) [11]

То что генерит Delphi в 7-8 раз медленней даже MMX версии, я уж не говорю про SSE+++, AVX и т.д.


 
Rouse_ ©   (2016-04-11 21:19) [12]

Так вот не надо писать на паскале в данном случае


 
Sha ©   (2016-04-11 21:25) [13]

вот не надо писать на паскале *так* в данном случае )


 
Dmk ©   (2016-04-11 21:36) [14]

А как надо?


 
Sha ©   (2016-04-11 21:47) [15]

Можно попробовать что-нибудь вроде этого:
не передавать лишних параметров,
подобрать подходящие типы параметров,
избавиться от лишних переменных,
меньше читать-писать в память,
расположить цвет в 64 битах регистра вразбежку аналогично mmx,
работать в "векторном" стиле сразу с 64 битами,
потом собрать результат.


 
Dmk ©   (2016-04-11 21:59) [16]

>меньше читать-писать в память,
ВО! Самое то! Delphi почти каждое действие в памяти делает. От того и грустно. Регистры как то побоку. Видимо опять переписывать на asm :(


 
Sha ©   (2016-04-11 22:13) [17]

Это не Delphi. Вернее, не только Delphi.

Если удастся переписать код в соответствии с [15],
то будет иметь смысл перетащить в процедуру и цикл.


 
Sha ©   (2016-04-11 22:28) [18]

Поставь себя на место разработчика компилятора.

В твоей процедуре требуется присвоить значение элементу структуры.
Самое простое решение - расположить структуру в памяти и там выполнить присваивание.
Скорее всего ты как разработчик компилятора не стал бы заморачиваться с особым случаем
и анализировать, может ли структура целиком поместиться в регистр,
а затем при помощи масок и сдвигов с учетом выравнивания менять его значение.
Слишком особенный случай, да и не надо это никому.

Поэтому, если хочешь не дергать память на паскале,
то твоя задача как программиста - написать программу без использования структур.



Страницы: 1 вся ветка

Текущий архив: 2018.04.08;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.007 c
2-1460612628
Аши
2016-04-14 08:43
2018.04.08
Файл 4 гигабайта


2-1460381686
Dmk
2016-04-11 16:34
2018.04.08
Перегружаемый код


15-1470771674
NailMan
2016-08-09 22:41
2018.04.08
Мой первый боевой девайс на Arduino полетел!


6-1286108067
Skyhawk99
2010-10-03 16:14
2018.04.08
Проблема с idHTTP и кирилицей


1-1357117761
shopgirl1987
2013-01-02 13:09
2018.04.08
Автоматический прием WM-платежей и Delphi