Почему IA-32 имеет неинтуитивное соглашение о сохранении регистра звонящего и вызываемого абонента? - PullRequest
3 голосов
/ 01 декабря 2011

Общие соглашения о вызовах для IA-32 гласят:

• Callee-save registers
%ebx, %esi, %edi, %ebp, %esp
Callee must not change these.  (Or restore the caller's values before returning.)

• Caller-save registers
%eax, %edx, %ecx, condition flags
Caller saves these if it wants to preserve them.  Callee can freely clobber.

Почему существует это странное соглашение?Почему бы не сохранить все регистры перед вызовом другой функции?Или попросить вызываемого сохранить и восстановить все с помощью pusha / popa?

Ответы [ 4 ]

9 голосов
/ 01 декабря 2011

Зачем вам писать код для сохранения регистров в каждой функции, которая вам может не понадобиться? Это добавило бы дополнительный код и дополнительную запись в память для каждого вызова функции. Сейчас это может показаться неважным, но в 80-х годах, когда создавалось это соглашение, оно, вероятно, имело значение.

И обратите внимание, что у ia-32 нет фиксированного соглашения о вызовах - то, что вы перечислите, является лишь внешним соглашением - ia-32 не применяет его. Если вы пишете свой собственный код, вы используете регистры как хотите.

Также см. Обсуждение История соглашений о вызовах в блоге Old New Thing.

При принятии решения, какие регистры должны быть сохранены вызывающим Соглашение, вы должны сбалансировать потребности вызывающего абонента с потребности вызываемого. Вызывающая сторона предпочла бы, чтобы все регистры были сохраняется, так как это устраняет необходимость для вызывающего абонента беспокоиться о сохранение / восстановление значения через вызов. Собеседник предпочел бы, чтобы регистры не сохраняются, так как это устраняет необходимость сохранять значение при входе и восстановить его при выходе.

Если вам требуется сохранить слишком мало регистров, вызывающие абоненты становятся заполнен регистром кода сохранения / восстановления. Но если вам нужно слишком много регистры должны быть сохранены, тогда вызываемые абоненты обязаны сохранять и восстановить регистры, о которых вызывающий абонент мог не заботиться. Это особенно важно для конечных функций (функций, которые делают не вызывать никаких других функций).

5 голосов
/ 01 декабря 2011

Предположение:

Если вызывающая сторона сохраняет все регистры, которые ей все еще понадобятся после вызова функции, она теряет время, когда вызываемая функция не изменяет все эти регистры.

Еслиcallee сохраняет все регистры, которые он изменяет, он тратит время, когда вызывающему не нужны значения в этих регистрах снова.

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

4 голосов
/ 01 декабря 2011

Если вы посмотрите немного глубже в используемые регистры , вы поймете, почему они не будут сохранены вызываемым пользователем:

  • EAX: используется для возврата функции, поэтому совершенно очевидно, что она не может быть сохранена.
  • EDX:EAX: используется для возвратов 64-битных функций, также как EAX.
  • ECX: это регистр подсчета, и в прежние времена x86, когда LOOPcc был «крутым», этот регистр бился бы как сумасшедший, даже сегодня есть еще довольно много инструкций, использующих ECX в качестве счетчика (например, REP с префиксными инструкциями). Однако, благодаря появлению __thiscall и __fastcall, он привыкает передавать аргументы, что означает, что вероятность его изменения очень велика, поэтому его сохранение практически не имеет смысла.
  • ESP: это небольшое побочное исключение, поскольку оно на самом деле не сохраняется, оно изменяется в соответствии с изменениями стека. Хотя это может быть сохранено для предотвращения повреждения / безопасности или разбаланса указателя стека благодаря встроенной сборке (через кадры стека).

Теперь это на самом деле становится интуитивно понятным:)

0 голосов
/ 01 декабря 2011

Короче говоря, сохранение звонящего происходит из-за передачи аргумента.Все остальное - звонки, кроме.

...