Вызываемому требуется только сохранить / восстановить сохраненные (энергонезависимые, с сохранением вызовов) регистры вызываемого объекта, значение которых ему необходимо изменить на мгновение (некоторые из которых могут не использоваться ни одним вызывающим абонентом в цепочке стека / трассировке стека, но вызываемый объект не делает этого) я знаю это), а вызывающему абоненту нужно только сохранить / восстановить сохраненные (изменчивые, закрытые по вызову) регистры вызывающего абонента, которые ему нужны после вызова (которые вызываемый в будущей цепочке стека может фактически не изменять, но вызывающий не делает '' незнаю это).
Как правило, по крайней мере в соглашении о вызовах Microsoft x64, вы будете увидеть много явно сохраненных энергонезависимых регистров в стеке, но не явно сохраненных энергозависимых регистров - я думаю, идея состоит в том, что компиляторы никогда не доходят до стадии, когда вызывающей стороне необходимо явно сохранить регистр прямо перед вызовом, особенно выражение, которое не является это переменная в самой программе; вместо этого он может планировать заранее и полностью избегать использования этих регистров, использовать регистр, но не оптимизировать хранилище переменных вне стека, использовать регистры для параметров, переданных вызываемой функции, которые не работают после вызова вызываемой функции, потому что они не работают. t определены как переменные в программе или используют изменчивый регистр.
Вызываемый объект явно подталкивает любой энергонезависимый регистр, который ему необходимо сохранить, в связи с вызовом, который он делает в стек в прологе функции, и восстанавливает их в эпилоге. Он может сохранять их в энергозависимых регистрах, но должен восстанавливать их в энергонезависимый регистр или сохранять в стек (в этом случае сохранение / сохранение называется разливом), если вызываемая функция выполняет вызов сама и не может сохранить его в другом энергонезависимый регистр, потому что тогда этот регистр также нужно будет сохранить.
Я согласен с тем, что сохранение вызывающего абонента означает, что регистр необходимо сохранить независимо от того, использует его вызывающий абонент или нет. Это неверно, и, возможно, даже не нужно сохранять регистр, даже если он действительно использует регистр, потому что он знает, что он ему не нужен после вызова или может вообще не выполнять вызов.
Хорошо иметь ровный баланс. Недостатком является наличие всего одного и ни одного другого, но иногда может быть оптимальным иметь склонность к одному типу, например энергонезависимому, где этот регистр может преимущественно использоваться в вызываемой функции, а не в вызывающей стороне. функция, как предложил Питер с xmm
регистрами.
Я думаю, что наличие всех энергонезависимых регистров повредит больше, чем наличие всех энергозависимых регистров, потому что вы сохраните параметры, которые могут быть мертвыми в вызывающем абоненте после вызова (поэтому параметры являются непостоянными; кроме того, сохранение регистра возвращаемого значения является невозможно, поэтому у вас должен быть хотя бы один изменчивый регистр для этого или возвращать значения в стеке, что медленнее), и вы также не сможете мгновенно изменить регистр без сохранения значения в стек, потому что есть доступны только энергонезависимые регистры, тогда как если бы все они были энергозависимыми регистрами, вы могли бы хранить значения в регистрах до тех пор, пока не будет сделан вызов или если не будет никакого вызова вообще. Всегда будет вызывающая функция (если только это не базовый фрейм), но конечных функций гораздо больше, чем базовых фреймов, и базовый фрейм не должен придерживаться соглашения о вызовах, чтобы оптимизировать сохранение энергонезависимых регистров, и может не оптимизировать их, если строго придерживаться этого, тогда как листовая функция, не сохраняющая изменчивые регистры, определена в соглашении о вызовах.
Если бы все регистры были энергозависимыми, это все еще было бы недостатком, потому что энергонезависимые регистры могут упростить компиляцию вашего собственного приложения, потому что нагрузка ложится на вызываемую функцию, которая может быть в какой-то библиотеке, скомпилированной отдельно. Кроме того, поскольку все изменчивые регистры сохраняются при создании кадра ловушки, а не энергонезависимых регистров (это относится к соглашению о вызовах Microsoft x64, по крайней мере,, если нет исключения или переключения контекста), будет больше штраф времени / пространства для обычных системных вызовов, если все регистры были непостоянными.
person
Lewis Kelsey
schedule
28.03.2021