а сишные функции почему-то cdecl , эти функции ч должен отчищать
А как я пойму какое соглашения я вызвал, если моя инструкция
Push str
Call [printf]?
Если так, то твое соглашение либо pascal, либо stdcall
Как так, я в одних функциях отчищаю стек, в других нет - хотя везде пишу call
Разные соглашения о вызовах. Где-то ты будешь через регистры передавать аргументы - fastcall или thiscall
Фаст наверное, thiscall я вообще не знаю
Там в макросах у Томаша много неоптимизированных моментов, потому что Томаш пишет от души, и вообще он старичок, целых 20 лет один и тот же проект полностью чисто на ассемблере пишет, так что его надо уважать.
Ну хорошо а если я положу аргументы в регистры и напишу call, то случится конец света?
fastcall - на х86_32 будет передача через eax, ecx, edx. thiscall - первый аргумент - указатель на экземпляр, передаётся в ecx
Тут зависит от функции. Если не ты писал функцию, то ты не можешь определять соглашение о вызовах
virtual origin = $ mov rax,param load opcode byte from origin+1 end virtual if opcode = 0B8h mov rax,param mov [rsp+(counter-1)*8],rax else mov qword [rsp+(counter-1)*8],param end if А еще меня заинтересовала эта штука
FASM может читать свой же код.
Да я в курсе, но что именно он тут отлавливает?
Надо полазать и заоптимизировать)
а я хочу в fasmw полазить, так и манит код посмотреть
Я понял. Опкод B8 это когда значение слишком большое. И в mov qword[], значение - оно не влезет, поэтому умный Томаш определил опкод, и если FASM сгенерировал B8, тогда он сначала пихает в регистр, а из регистра в память, а если значение маленькое (меньше 64 бит), тогда просто пихает сразу напрямую.
Своеобразный самомодифицирующийся код, к слову.
Не, это условная генерация кода. Хотя он мог бы так не извращаться и сразу, если это число, проверить, что оно больше чем 32 бита. По сути тут нет именно модификации кода, так как тот опкод, который он читает, находится в виртуальном пространстве и не проецируется на реальную память
Томаш так решил, значит надо.
Он сам делает так, как я сказал, в инициализции локальных переменных)
Ну в макросе local/locals. Там он если надо загрузить данные из области в 8 байт при условии что значение там больше 4 байт загружает по очереди по 4 байта
Ну, значит код старый просто, и он не успел переписать этот участок. Это в старой какой-то версии может нельзя было так проверять. Не знаю.
Зато я только что понял как мне сделать то, что я хочу - макрос jret)
И теперь я наконец смогу ещё больше автоматизировать даже ручные штуки вроде закрытия функции джампом на другую)
Я не знаю, почему конкретно тут опкод читается, но в целом Томаш это делает, потому что не все значения — просто n-битные числа. Есть отрицательные числа, которые можно компактнее кодировать с расширением знака, всякие поправки, всякие относительные метки, поэтому чем разбирать это вручную в каждом макросе, проще заставить ассемблер разбираться, у него под это есть логика, и он сделает это лучше тебя.
Обсуждают сегодня