The Bird of Hermes
Или как он там называется
The Bird of Hermes
Кодирование неоднозначное, даже jz можно по-разному закодировать.
Ну для этого достаточно забить в базу все варианты опкодов для условного jz
s54820
Ну для этого достаточно забить в базу все варианты опкодов для условного jz
Отлично, осталось только в листинге указать, какой вариант использовать, и сделать это для всех инструкций, не только для jz.
The Bird of Hermes
Отлично, осталось только в листинге указать, какой вариант использовать, и сделать это для всех инструкций, не только для jz.
Ну так дизасм этим и будет заниматься, и тут особо для неоднозначности не будет места
notme
Как может влиять наличие/отсутствие команд push pop в этом примере?: push rcx call proc pop rcx
The Bird of Hermes
Как может влиять наличие/отсутствие команд push pop в этом примере?: push rcx call proc pop rcx
Судя по тому, что ты используешь rcx, у тебя х64, а значит смысла кидать в стек нет
notme
С наличием этих инструкций - падает без них - работает
889
Как может влиять наличие/отсутствие команд push pop в этом примере?: push rcx call proc pop rcx
Ты просто сохраняешь регистр, чтобы функция его не затёрла
notme
Они стек меняют
ну... вообще да... но выше и ниже есть ещё несколько push-pop и удаление их/добавление ни на что не влияет
Aiwan \ (•◡•) / _bot
С наличием этих инструкций - падает без них - работает
значит в самой функции чтото не так со стеком
Aiwan \ (•◡•) / _bot
С наличием этих инструкций - падает без них - работает
падает именно на какой строке? прндполагаю что в конце твоей функции, не правильно стек восстанавливается
The Bird of Hermes
да
Ну вот. Выравнивание по границе 16 соблюдается.
notme
Ну вот. Выравнивание по границе 16 соблюдается.
ой, я понял про что ты, я думал ты имел ввиду что они парно все - да а на счёт четности не анализировал
The Bird of Hermes
ой, я понял про что ты, я думал ты имел ввиду что они парно все - да а на счёт четности не анализировал
И ещё, в х64 если ты прямо перед вызовом в стек кладешь - это не поможет сохранить значение, потому что функция считает место под аргументы своей собственностью, которую можно менять
notme
Ну вот. Выравнивание по границе 16 соблюдается.
Ну ёмаё! точно добавил ещё один пуш-поп и заработало
The Bird of Hermes
Что это за бред?
Ну это как бы так работает. Функции хотят, чтобы ты им в стеке выделил минимум 32 байта под аргументы
The Bird of Hermes
Если в стек кинешь что-то, функция будет считать, что это ты для неё выделил)
notme
А вообще я пишу пришлёпку к компилятору FPC(pascal) для профайлинга Которая будет вставлять в каждую ф-ию в начало и конец вызов специальных ф-ий, где будет сохраняться адрес ф-ии и RDTSC
889
Как может влиять наличие/отсутствие команд push pop в этом примере?: push rcx call proc pop rcx
Попробуй не через стек сохранить rcx, а через r11, если не упадёт, значит проблема всё-таки в том, что функция затирает rcx и всё.
Aiwan \ (•◡•) / _bot
Да
а не до ее вызова
The Bird of Hermes
а не до ее вызова
Ну да. Я и не говорил, что это происходит до вызова
The Bird of Hermes
Я сказал, что функция это делает
The Bird of Hermes
.
Ну
Aiwan \ (•◡•) / _bot
notme
вот эта ф-ия, вернее их две - они pure assembler x64 на них передаётся управление перед прологом и после эпилога каждой из ф-ии в программе ЯВУ
The Bird of Hermes
так у него до функи пушится
Да, но сама функция будет работать так, будто положенное в стек - место под аргументы для неё. Он же без макросов пишет
The Bird of Hermes
Соответственно может на своё усмотрение их затереть
The Bird of Hermes
Конечно это если функция внешняя, а не написана самостоятельно
Aiwan \ (•◡•) / _bot
Да, но сама функция будет работать так, будто положенное в стек - место под аргументы для неё. Он же без макросов пишет
нет, она саиа себе должна ввделять теневое место, если прогеру это не надо, то не обязательно
The Bird of Hermes
889
Ммм мы оба не уточнили про ось). В винде все так
В винде соглашение на 4 аргумента в регистрах
Aiwan \ (•◡•) / _bot
а я про винду говорю
The Bird of Hermes
В винде соглашение на 4 аргумента в регистрах
И под них обязательно выделяется место в стеке
Aiwan \ (•◡•) / _bot
фсе, я устал
The Bird of Hermes
Причём как минимум под 4
notme
в общем как то так генерируется код: call profiler_enter push rbp // это уже начало тела ф-ии mov rbp,rsp lea rsp,[rsp-$30] mov [rbp-$10],rbx ... mov rbx,[rbp-$10] lea rsp,[rbp+$00] pop rbp // конец тела ф-ии + ret ниже call profiler_exit ret
Aiwan \ (•◡•) / _bot
И под них обязательно выделяется место в стеке
буду вечером проверятб отсутствие теневого места в стеке
The Bird of Hermes
буду вечером проверятб отсутствие теневого места в стеке
Можно вообще посмотреть, как макрос fastcall работает
889
И под них обязательно выделяется место в стеке
Где это написано? https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
889
889
Это System 5, может кому интересно будет.
Aiwan \ (•◡•) / _bot
Где это написано? https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
во. значит если параметров нет, то и необходимость теневого места нет
Aiwan \ (•◡•) / _bot
да даже если и были бы, то саи прогер решает помещать пара етры для созранности туда или нет
889
да даже если и были бы, то саи прогер решает помещать пара етры для созранности туда или нет
Не, если бы это было в соглашении прописано, то решал бы уже не прогер)
The Bird of Hermes
Где это написано? https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
Двоичный интерфейс для 64-разрядных приложений (ABI) по умолчанию использует соглашение о вызовах по четырем регистрам. Место в стеке вызовов выделяется как теневое хранилище для вызываемых функций сохранения этих регистров.
Aiwan \ (•◡•) / _bot
Не, если бы это было в соглашении прописано, то решал бы уже не прогер)
я думаю этл не строгое правило. сделано для удобства в реалиях новых соглашений. параме ры скидываются в стек на сохранность, ибо при большом коде/расчетах занииают регистр(ы). а так, вызываются из памяти при необходимости, и при этом свободны регистры, используемые в передаче параметров
🦥Alex Fails
в целом оно ща де-факто по двум ABI: Itanium на линуксах , и MSVC на окнах
Aiwan \ (•◡•) / _bot
Двоичный интерфейс для 64-разрядных приложений (ABI) по умолчанию использует соглашение о вызовах по четырем регистрам. Место в стеке вызовов выделяется как теневое хранилище для вызываемых функций сохранения этих регистров.
ах да, вспомнил. выделять надо всегда, но использовать по необзодимости, ибо после памяти с теневым местом идут те рараметры, которые передпвались уже через стек (>4)
The Bird of Hermes
The Bird of Hermes
Надо бы портануть свои макросы на х86😁
notme
Капец вы тут спорите ) А у меня ещё вопрос ) что быстрее sub rsp, N mov mov ... mov mov add rsp, N или push push pop pop
The Bird of Hermes
конечно второе
push же медленнее, чем mov
notme
Зависит от количества аргументов
всего лишь шесть пар push-pop'ов
Aiwan \ (•◡•) / _bot
push же медленнее, чем mov
точки еще дольше, ибо неизвестно сколько в них кода. но скоией всего я неправильно понял
notme
точки еще дольше, ибо неизвестно сколько в них кода. но скоией всего я неправильно понял
в точках там mov reg, [esp+N] - взятие адреса возврата и чтение Rdtsc в регистр rcx
notme
// Нужно сохранить RCX, RDX, R8, R9 - в них передаются параметры // а также любые регистры, которые эта функция меняет // и восстановить всё это в конце // нужно обращать внимание, что стек должен быть выравнен на 16 байт // поэтому число push-pop должно быть четное push rcx // сохраняем регистры mov rcx, [rsp+8] // берём адрес возврата - первый аргумент push rax // продолжение сохранения регистров push rcx push rdx push r8 push r9 rdtsc shl rdx, 32 or rdx, rax // RDX RDTSC - второй аргумент call profiler_function_enter pop r9 // восстанавливаем регистры pop r8 pop rdx pop rcx pop rax pop rcx
The Bird of Hermes
Без макросов писать на х64 - сущие страдания
notme
А зачем?
Я пишу функцию в компиляторе FPC(Pascal) для профайлинга Компилятор будет эту функцию вставлять непосредственно перед началом каждой функции - она будет читать адрес и rdtsc для того, чтобы потом построить граф, для профайлинга
notme
Используй макросы и будет тебе щастье🤣
это короткая ассемблерная прослойка, думаю тут это не нужно и в FPC макросы ограничены... этот код - он прям в коде паскаля, FPC так позволяет писать