powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Делфи+ассемблер 64-бит: вызов функции
10 сообщений из 10, страница 1 из 1
Делфи+ассемблер 64-бит: вызов функции
    #39848756
grey702
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нужен совет гуру по встроенному ассемблеру!

Есть метод для вызова внешней функции:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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.
Но как пользоваться не понял, описания нормального не нашел.
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39848785
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А чем стандартный Move не угодил?
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39848801
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grey702,

читай механизм вызова под x64.
4 первых параметра надо протолкнуть в регистры, но всё равно выделить стек под них
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39848812
grey702
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Читал... там еще дополнительно XMM
Может, нормальную доку про .PARAMS знаете? как это вообще работает?
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39848830
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39848891
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
grey702Читал... там еще дополнительно XMM
Может, нормальную доку про .PARAMS знаете? как это вообще работает?

Так вы же сами привели кусок доки, там все и описано.
.PARAMS - устанавливает кол-во переданных параметров в функцию. Инструкция генерирует смещение стека.
@params - позволяет адресоваться к выделенному стеку как к массиву байт. 0-31 первые 4 регистра rcx, rdx, r8, r9.

Судя по доке должно быть что-то вроде:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
      .PARAMS 3
      // сохраняет регистры
      MOV     @params[24], RCX
      MOV     @params[16], RDX
      MOV     DWORD(@params[8]), r8d      
      // что-то делает
      ....
     // копирует сохраненные в стеке значения в регистры
      MOV     RCX, @params[24]
      MOV     RDX, @params[16]
      MOV     r8d, DWORD(@params[8])

      CALL    MOVE
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39848909
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grey702,

подсмотри как делают в System.Rtti.Invoke - 21943123
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39849601
grey702
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan),
Там приходит уже готовый массив параметров... Я попробовал переделать на Invoke, проблема другая - Invoke с var параметрами нормально не работает, надо крутить через указатели, мне переписывать 100500 функций. Так что смотрю опять в сторону ассемблера
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39849629
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grey702,

модификатор var это всего лишь ссылка, в вашем оригинале я не вижу какой-то особой обработки ссылок - параметры формируются где-то во вне, т.е. то же самое.

основная мысль такая, вы же stdcall пытаетесь вызывать?
если это стандартные процы, я думаю там не будет значений больше 8 байт, очень какой-то скользкий вопрос с ними
т.е. разбить ваш входной массив на переменные int64 и отправить через invoke для начала
...
Рейтинг: 0 / 0
Делфи+ассемблер 64-бит: вызов функции
    #39850284
grey702
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пришел я к вот такой конструкции:

{$ifdef win64} // rcx //rdx // r8
function ExtCall(p_StackData: Pointer; p_Addr: Pointer; p_StackSize: NativeUInt): HResult;
asm
SUB RSP, 32+8

MOV [RBP+$210], p_Addr
// stack
SUB RSP, p_StackSize // место в стеке под даные
MOV RCX, p_StackData // указатель на параметры в RCX
MOV RDX, RSP // вершину стека в RВX
MOV R8, p_StackSize // количество байт в R8
CALL MOVE // перемещаем параметры в стек (Move(source, dest, n); // source - RCX, dest - RDX, n - R8)
// get parameters
POP RCX // выталкиваем параметры в регистры - первые 4, остальные остаются в стеке
POP RDX
POP R8
POP R9

CALL [RBP+$210]

ADD RSP, 32+8
end;

На первый вгляд задачу она решает - вызывается функция, про которую знаем только адрес, и адрес, по которому лежат параметры (тип их и количество неизвестно, имеем только их размер для помещения в стек).
В ассемблере я слаб, особенно в 64битном варианте. Если что подскажете - буду очень благодарен)
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Делфи+ассемблер 64-бит: вызов функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]