Комментарии 8
Статья норм. Карма,закладки,статья +/+/+.
В начале нужно было обязательно:
– рассмотреть rsp и rbp (если с первым - всё просто, то со вторым - всё не просто)
– calling convention
Иначе текст выглядит “магией”.
PS Буду писать виртуалки для скриптовых языков. Приглашаю поучаствовать.
Спасибо за обратную связь! Соглашусь, что в начале стоило про calling convention подробнее написать - в следующий раз учту. Статью несколько раз переписывал, поскольку то слишком, казалось бы, много информации уточняющей писал, то слишком мало. Пока пытаюсь пристреляться, насколько подробно стоит все разъяснять)
PS Буду писать виртуалки для скриптовых языков. Приглашаю поучаствовать.
Спасибо за приглашение, но, к сожалению, не моя специализация :(
Что меня всегда интересовало, это почему параметров входных через регистры можно передать больше, чем выходного размера?
Никогда не задумывался об этом, но стоит признать, что интересный вопрос Предположу, что “входных” регистров много, потому что очень часто функции принимают несколько аргументов. В то время как возвращаемых значений обычно меньше. Получается, что 2 регистра попросту оптимальный вариант, поскольку в большинстве случаев их хватает для фундаментальных типов и каких-то небольших других типов, а если что-то тяжелое, то можно просто другим способом возвращать - то есть как и делают с типами класса MEMORY, поэтому и нужда в большем количестве регистров пропадает.
Думаю,потому что обычно возвращается или bool,или указатель на память. Для всего этого хватает одного регистра.
Не затронута тема с плавающей точкой
как сверху упомянули, странно что выходных значений меньше, но лично я бы это даже сказал так: странно, что входные регистры не переиспользуются как выходные. учитывая, что `rdx` вроде как всё же так и делает, хоть почему-то и один. есть ли причина по которой вся шестёрка + уже выходной `rax` не может использоваться как для входа так и для выхода? это чем-то неудобно?
вообще, я немного предполагаю, что, когда придумывали этот cc, впринципе не особо задумывалось возвращать составные структуры в качестве обычного возврата функции, но вроде как так всё же даже не делают более новые cc. почему всё-таки?
есть ли причина по которой вся шестёрка + уже выходной
raxне может использоваться как для входа так и для выхода? это чем-то неудобно?
Придерживаюсь того, что писал раннее - передавать много аргументов в функцию это дело частое, поэтому и под это дело выделили 6 регистров (интересно, почему 6, кстати, но я подозреваю, что взвесив все трейд оффы это число оказалось самым оптимальным по мнению умных дядь), а возвращать много всего - относительно редко, вот их всего и 2 (опять же, наверное, умные дяди путем долгих раздумий пришли к выводу, что это оптимально), а для чего-то крупнее можно вернуть через скрытый аргумент.
учитывая, что
rdxвроде как всё же так и делает
Может быть, это совпадение.
я немного предполагаю, что, когда придумывали этот cc, впринципе не особо задумывалось возвращать составные структуры в качестве обычного возврата функции
Скорее, наоборот задмумывались, поскольку придумали класс типов MEMORY). Про другие CC я знаю не много, но, наверное, идея с MEMORY очень удачная, вот я и подозреваю, что другие CC тоде это используют.

Возврат значений из функций в x86-64: регистры, память и скрытые аргументы