Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2018.04.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.002 c
1-1357117761
shopgirl1987
2013-01-02 13:09
2018.04.08
Автоматический прием WM-платежей и Delphi


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


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


8-1243634121
novarm44
2009-05-30 01:55
2018.04.08
Тормоза Direct3D и OpenGL под Vista и Windows 7


2-1460338110
Abcdef123
2016-04-11 04:28
2018.04.08
Email component





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский