Нужен совет гуру по встроенному ассемблеру!
Есть метод для вызова внешней функции:
function ExtCall(StackData: Pointer; Addr: Pointer; StackSize: Integer): HResult;
asm
PUSH EDI
MOV EDI,Addr
SUB ESP,StackSize
MOV EDX,ESP // адрес вершины стека пишем в EDX, чтобы далее переместить туда StackSize данных с адреса StackData командой MOVE
CALL MOVE // Move(D, S, n); // D - EAX (StackData: Pointer); S - EDX (там теперь лежит адрес вершины стека); n - к-во байт (StackSize) - в ЕСХ
CALL EDI
POP EDI
end;
Addr - адрес функции, которую вызываем. StackData - адрес, по которому в памяти лежат параметры в определенном порядке, как ожидает функция. StackSize - необходимый размер стека.
Все это нормально работает в 32-битном варианте.
Теперь встал вопрос перехода на 64 бита, и, естественно, работать перестало, поскольку соглашение о вызовах другое, и параметры должны быть в регистрах RCX, RDX и т д, а не в стеке.
Вопрос - есть ли возможность скопировать параметры в регистры (исходя из того, что имеем только адрес, по кторому они в памяти), не меняя полностью весь механизм? Я изучал хелпы, нашел вот такую вещь:
.PARAMS <number>
Used when calling external functions to setup the register parameter backing store as per the x64 calling convention as this is not normally done by default. When used, a pseudo-variable, @params, is available for passing stack params to called functions. Use @params as a byte array where the first stack parameter will be @params[32], locations 0-31 represent the 4 register parameters.
Но как пользоваться не понял, описания нормального не нашел.