|
|
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
Нужен совет гуру по встроенному ассемблеру! Есть метод для вызова внешней функции: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 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. Но как пользоваться не понял, описания нормального не нашел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 13:00 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
А чем стандартный Move не угодил? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 13:51 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
grey702, читай механизм вызова под x64. 4 первых параметра надо протолкнуть в регистры, но всё равно выделить стек под них ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 14:13 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
Читал... там еще дополнительно XMM Может, нормальную доку про .PARAMS знаете? как это вообще работает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 14:39 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 15:03 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 16:36 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2019, 16:51 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan), Там приходит уже готовый массив параметров... Я попробовал переделать на Invoke, проблема другая - Invoke с var параметрами нормально не работает, надо крутить через указатели, мне переписывать 100500 функций. Так что смотрю опять в сторону ассемблера ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2019, 10:07 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
grey702, модификатор var это всего лишь ссылка, в вашем оригинале я не вижу какой-то особой обработки ссылок - параметры формируются где-то во вне, т.е. то же самое. основная мысль такая, вы же stdcall пытаетесь вызывать? если это стандартные процы, я думаю там не будет значений больше 8 байт, очень какой-то скользкий вопрос с ними т.е. разбить ваш входной массив на переменные int64 и отправить через invoke для начала ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.08.2019, 10:46 |
|
||
|
Делфи+ассемблер 64-бит: вызов функции
|
|||
|---|---|---|---|
|
#18+
Пришел я к вот такой конструкции: {$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битном варианте. Если что подскажете - буду очень благодарен) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.08.2019, 12:18 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39848756&tid=2039137]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
160ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 453ms |

| 0 / 0 |
