Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Чт мар 28, 2024 23:19

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 17 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт авг 12, 2021 15:47 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Вот нужен опытный взгляд.
А то вдруг где-то в коде косякнул.

Код:
; RAX -- даётся указатель на массив параметров кода
; RDI -- хранится указатель на данные потока

; Код верхнего уровня для понимания
; : CALLBACK: \ n --  cb: param-addr -- ???
; HEADER
; ['] (CALL-BACK) COMPILE, ,
; ] ;


HEADER (CALL-BACK)
POP RAX
PUSH [RAX] ; тут количество параметров
PUSH RDX
PUSH RBX
PUSH RBP
PUSH RSI
PUSH RDI
PUSH r8
PUSH r9
PUSH r10
PUSH r11
PUSH r12
PUSH r13
PUSH r14
PUSH r15
; 14 CELLS + хранится код возврата из калбека
; 15 CELLS + тут уже параметры должны быть

LEA RBX, [CELL+RAX]      ; указатель на код
LEA RAX, [15*CELL+RSP]
MOV RSI, RSP

GS: MOV RDI, [20*CELL]      ; в винде на 64 бита сегмент GS может использоваться как хранилище

XOR RDX, RDX
PUSH RDX
PUSH RDX
PUSH RDX ; подушка

MOV ECX, 100
cb_stack:
PUSH RDX
DEC ECX
JNZ cb_stack

MOV RBP, RSP

PUSH RDX
PUSH RDX
PUSH RDX ; подушка
PUSH RSI

CALL RBX

POP RSP


POP r15
POP r14
POP r13
POP r12
POP r11
POP r10
POP r9
POP r8
POP RDI
POP RSI
POP RBP
POP RBX
POP RDX
MOV RCX, [RSP+CELL]         ; [RSP] - кол-во параметров [RSP+CELL] - возврат в калбек
ADD RSP, [RSP*CELL+CELL]
JMP RCX

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Сб авг 14, 2021 16:46 
Не в сети

Зарегистрирован: Чт июн 03, 2021 16:13
Сообщения: 26
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
Внимательно просмотрел несколько раз глазами. Я так понимаю что центральный CALL RBX это и есть точка входа в форт из переходника. Вы до него "подушку" делаете, а после возврата не удаляете ее со стека, хотя возможно, последующий POP RSP и есть востановление или это делается внутри вызываемого форт слова. Не зная всей идеии тяжело сказать.

А можно увидеть весь код ФС?


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Сб авг 14, 2021 22:22 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Blackice писал(а):
Внимательно просмотрел несколько раз глазами. Я так понимаю что центральный CALL RBX это и есть точка входа в форт из переходника. Вы до него "подушку" делаете, а после возврата не удаляете ее со стека, хотя возможно, последующий POP RSP и есть востановление или это делается внутри вызываемого форт слова. Не зная всей идеии тяжело сказать.

А можно увидеть весь код ФС?


Восстановление делает POP RSP

Весь код?

Пожалуйста,
https://cloud.mail.ru/public/UtSu/yPZw6zh1X
Все что касается 64-битов в паgке src2

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Пн сен 06, 2021 23:02 
Не в сети

Зарегистрирован: Чт июн 03, 2021 16:13
Сообщения: 26
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
Извините за задержку с ответом. После скачивания архива файл NOVA-CDW.EXE был тут же уничтожен защитником. Пришлось еще раз делать это на виртульной машине. После распаковки архива вышеприведенного кода относящегося к калбекам для х64 там не оказалось...

А зачем вы сохраняете в стеке все регистры? Параметры могут быть только в rcx, rdx, r8, r9 а, остальные будут передаваться уже через стек над т.н. регистровой областью стека. Так что скорее всего тут не совсем верно. (Хотя я не видел в винде калбеков с более чем 4-мя аргументами, но буду рад если кто покажет).


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Вт сен 07, 2021 20:56 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
В 32-битах передаётся все через стек
на 64-битах иначе?
Я прост оне нашёл документации у винде по калбекам.
А сохраняю я это всё на случай, если винда врёт

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Ср сен 08, 2021 22:51 
Не в сети

Зарегистрирован: Чт июн 03, 2021 16:13
Сообщения: 26
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
Victor__v писал(а):
В 32-битах передаётся все через стек
на 64-битах иначе?
Я прост оне нашёл документации у винде по калбекам.
А сохраняю я это всё на случай, если винда врёт


С переходом на 64 бита интерфейс вызова системных функций поменялся кардинально. Больше нет понятий stdcall, c-decl, fastcall, вместо этого есть единый механизм вызова. Документации по калбекам нет, так как то как система будет вызывать калбек, ничем не будет отличаться от того, как вы будете вызывать системную функцию. Да и тут информации не-много. Попробую пролить свет на эту тему.

Первые 4 целочисленных аргумента всегда передаются через регистры - RCX, RDX, R8, R9. Если это вещественные числа - то соответсвенно в регистрах XMM0, XMM1, XMM2, XMM3. (FPU больше не используется). Порядковый номер первых 4х аргументов закреплен за регистром. Тоесть, если метод имеет 4 аргумента: foo( INT, FLOAT, INT, FLOAT ), то распределение регистров будет следующее: RCX, XMM1, R8, XMM3. Еще пример: для foo( FLOAT, INT, INT, FLOAT ) -> XMM0, RDX, R8, XMM3. Думаю теперь идея ясна. Главная трудность тут в том, что для того чтобы написать правильный переходник для калбека или подготовить системный вызов, необходимо точно знать спецификацию метода.

Далее, если метод имеет более 4х аргументов, то все они передаются через стек над т.н. shadow space. Это дополнительные 4 ячейки стека над адрессом возврата. Эти ячейки выделяются всегда для того, чтобы вызываемая процедура могла сохранить регистры с аргументами и освободить их для свох нужд. Эти ячейки не иннициализируются никак. Если на входе в процедуру RSP указывает на адресс возврата, то [RSP+8] <- место для хранения RCX, [RSP+16] - для RDX, [RSP+24] - для R8, и [RSP+32] - для R9. Т.о. 5-й аргумент, если он есть то, будет в [RSP+40], 6-й в [RSP+48], ну и т.д.
Вызывающая процедура ответственна за созднание и удаление этой области стека после вызова. Не важно, сколько аргументов имеет процедура или не имеет их вообще, - эти 4 ячейки должны быть выделены на стеке перед вызовом. Вы каллбеке можете использовать их на свое усмотрение.

Возврат значения для целых как и раньше - в RAX, для вещественных - в XMM0.

Исходя из всего этого, я лично пришел к выводу, что написать универсальный варинат каллбек-переходника или системного вызова для 64-бит форт системы не получиться. Необходимо от пользователя получить спецификацию метода и на ее основе скомпилировать уже переходник: для каллбека передавать параметры в форт-систему и возращать значение в ОС, для системного вызова - готовить регистры, резервировать стек... Еще как вариант, учитывая что реальных комбинаций не так уж и много, можно банально предусмотреть их все, ну и выбирать подходящий зная сигнатуру метода.



За это сообщение автора Blackice поблагодарили - 4: Hishnik, NLObP, Total Vacuum, zma
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт сен 09, 2021 11:37 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Цитата:
Исходя из всего этого, я лично пришел к выводу, что написать универсальный варинат каллбек-переходника или системного вызова для 64-бит форт системы не получиться.


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

Впрочем, универсальный переходник делать-то и не требуется.
Для обычных сисей черех регистры.
Для флоатов (OPENGL, например) напишем другую обертку, благо в названии функций уже написано, какие параметры они жрут)

А со всеми остальными, хм, ну придумаем что-нибудь)

Может кто-нибудь скинуть дизассемблерный листинг или исходиники на асме какого-нибудь калбека под 64 бита?

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт сен 09, 2021 16:29 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Ещё, если верить https://docs.microsoft.com/en-us/cpp/bu ... w=msvc-160
то флоаты также передаются в обычных регистрах, а не в XMM

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт сен 09, 2021 16:47 
Не в сети
Аватара пользователя

Зарегистрирован: Ср июл 03, 2019 11:10
Сообщения: 463
Откуда: Москва
Благодарил (а): 57 раз.
Поблагодарили: 22 раз.
Victor__v писал(а):
флоаты также передаются в обычных регистрах, а не в XMM

Разве? Вот же цитата с буржуйского сайта:
Integer arguments are passed in registers RCX, RDX, R8, and R9. Floating point arguments are passed in XMM0L, XMM1L, XMM2L, and XMM3L.

Из интересного там еще это:
The x64 ABI considers registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, and XMM6-XMM15 nonvolatile. They must be saved and restored by a function that uses them.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт сен 09, 2021 18:04 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Меня больше привлёк этот абзац.

Цитата:
Varargs

If parameters are passed via varargs (for example, ellipsis arguments), then the normal register parameter passing convention applies. That convention includes spilling the fifth and later arguments to the stack. It's the callee's responsibility to dump arguments that have their address taken. For floating-point values only, both the integer register and the floating-point register must contain the value, in case the callee expects the value in the integer registers.


В любом случае, надо будут все пробовать)
Если в регистру совать флоаты и нет вылета, то работает. Иначе, едлаем другую обёртку)

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт сен 09, 2021 18:21 
Не в сети
Аватара пользователя

Зарегистрирован: Ср июл 03, 2019 11:10
Сообщения: 463
Откуда: Москва
Благодарил (а): 57 раз.
Поблагодарили: 22 раз.
Тут речь о функциях с переменным числом параметров (типа printf): они должны пихать 5-й и последующие параметры в стек... А первые 4-х параметров надо
пихать либо в RXX (если параметр целочисленный), либо и в RXX и в XMMXX (если параметр типа float)... :D Если бы я писал 64-битный Форт, то на всякий случай попробовал бы пихать каждый из параметров в оба регистра (целочисленный и float)... Но я пишу 8-битный... :D


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Чт сен 09, 2021 21:24 
Не в сети

Зарегистрирован: Чт июн 03, 2021 16:13
Сообщения: 26
Благодарил (а): 0 раз.
Поблагодарили: 7 раз.
Victor__v писал(а):
А вот с калбеками беда.
Может кто-нибудь скинуть дизассемблерный листинг или исходиники на асме какого-нибудь калбека под 64 бита?


Привожу свой. (К сожалению шрифт не моноширинный и форматирование не держиться, так что все мои старания по рисованию стрелочек свелись на нет. Лучше скопировать в редактор с моноширинным шрифтом, выровнять и смотреть там.)

Происходит следующее, - в заранее подготовленный 96 байтный блок на момент его компиляции в шитый код заносятся:
адресс процедуры на С, которая собственно и будет обеспечивать передачу аргументов каллбека в форт и возврат значения в ОС;
адресс форт-слова, которое будет вызвано - пользовательский обработчик каллбека;
колличество аргументов и флаг возврата значения. Если он установлен, то со стека форта снимется последнее значение и занесется в регистр RAX;
указатель this объекта Task (у меня ООП тут совсем не ради ООП, не обращайте внимания);
Разумеется, область памяти куда все это компилируется должна иметь атрибуты execute-read-write.

Далее, адресс этого переходника передается в системную функцию которая будет вызывать калбек. При вызове из системы, делается перепрыжка через область данных, сохраняются аргументы и осуществляется прыжок в обработчик на С. Заметьте, так как я не изменил RSP, мне незачем выделять на стеке 4 ячейки для своего собственного обработчика, он будет использовать те что уже зарезервировала ОС. Ну и естесвенно возрват осуществиться уже прямо в ОС.

Учитывая, что бработчик на С принимает один аргумент (RCX - указатель на весь переходник), то мне просто необходимо место для хранения аргументов каллбека и я не могу в этом случае использовать область "оттенения регистров", ведь ее может использовать мой собственный обработчик. Именно по-этому оно резервируется в самом переходнике. Если же вы пишете форт на ассемблере, то вы спокойно можете сохранить регистры с аргументами в те самые 4 ячейки, которые уже выделенны на стеке и т.о. сократить размер переходника на 32 байта (указатель this тоже можно выбросить). Далее прыжок уже в универсальный обработчик так как у него есть все необходимое для обеспечения работы форт-слова в калбеке. Если стеки ОС и форта не связанны, то форт-слово из каллбека получает доступ к своему родному стеку что может быть полезно.

Код:
__thunk:
E840000000             +- call __thunk + 40h   <----------+ ; перепрыгнем через область данных каллбека, а заодно получим адресс нашего переходника
9090909090909090  |                                    <---+    |  ; адресс каллбек перехватчика, устанавливаеться при компиляции
9090909090909090  |                                           |    |  ; NFA слова которое собственно и будет вызываться в каллбеке
9090909090909090  |                                           |    |  ; dword: колличество аргументов, dword: флаг возврата значения
9090909090909090  |                                           |    |  ; <- 1й аргумент RCX
9090909090909090  |                                           |    |  ; <- 2й аргумент RDX
9090909090909090  |                                           |    |  ; <- 3й аргумент R8
9090909090909090  |                                           |    |  ; <- 4й аргумент R9
9090909090909090  |                                           |    |  ; указатель this объекта Task
58                           +-> pop rax                      ---+    |  ; теперь RAX содержит адресс области данных переходника
48894818                      mov qword ptr [rax+24], rcx   |  ; сохраняем аргументы в отведенное для них место.
48895020                      mov qword ptr [rax+32], rdx  |  ; хотя колличество аргументов уже известно, так как установленно
4C894028                      mov qword ptr [rax+40], r8    |  ; еще при компиляции, но анализировать это и сохранять только те, что
4C894830                      mov qword ptr [rax+48], r9    |  ; фактически переданы - нету смысла. Просто сохраняем все 4 регистра.
488d48fb                       lea rcx, [rax-5]              -------+ ; RCX <- адресс всего переходника в шитом коде
488B00                          mov rax, qword ptr [rax]            ; RAX <- адресс перехватчика написанном на С
FFE0                              jmp rax                                     ; прыгаем прямо в обработчик
90                                 nop                                           ; для выравниваия


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Пт сен 10, 2021 10:15 
Не в сети
Аватара пользователя

Зарегистрирован: Ср июл 03, 2019 11:10
Сообщения: 463
Откуда: Москва
Благодарил (а): 57 раз.
Поблагодарили: 22 раз.
Надо делать 64-битный форт сразу с кэшированием четырех верхних элементов стека в регистрах rcx/rdx/r8/r9, тогда колбэки получаются автоматически на сдачу... :D :D


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Сб сен 11, 2021 19:59 
Не в сети

Зарегистрирован: Чт янв 07, 2016 19:14
Сообщения: 1288
Благодарил (а): 3 раз.
Поблагодарили: 18 раз.
Total Vacuum писал(а):
Надо делать 64-битный форт сразу с кэшированием четырех верхних элементов стека в регистрах rcx/rdx/r8/r9, тогда колбэки получаются автоматически на сдачу... :D :D

Тогда уж полностью регистровую форт-машину.
Что мелочиться) Так даже проще будет)
Только стек ограничим 11 переменными, потому что мне нравится это число)

_________________
Цель: сделать 64-битную Нову под Винду


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Обёртка для каллбеков или гадание по коду
СообщениеДобавлено: Сб сен 11, 2021 21:52 
Не в сети

Зарегистрирован: Пн янв 07, 2013 22:40
Сообщения: 2141
Благодарил (а): 8 раз.
Поблагодарили: 74 раз.
Victor__v писал(а):
Total Vacuum писал(а):
Надо делать 64-битный форт сразу с кэшированием четырех верхних элементов стека в регистрах rcx/rdx/r8/r9, тогда колбэки получаются автоматически на сдачу... :D :D

Тогда уж полностью регистровую форт-машину.
Что мелочиться) Так даже проще будет)
Только стек ограничим 11 переменными, потому что мне нравится это число)

? как в модели калькулятора MK-61, MK-161 или HP (RPN, RPL) на три элемета стэка X,Y,Z (плавающей арифметики) + T регистр. :)
(а на этой системе команд уже запустить Форт - Callisto Каллисто-2)
Ath , вроде, забанен на местном форуме.
Местная тема: Каллисто 1.0 для «Электроники МК-161»


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 17 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB