Сохранены ли регистры rdi и rsi? - PullRequest
1 голос
/ 28 марта 2019

Из соглашения о вызовах из Википедии x86 говорится, что для соглашения о вызовах Microsoft x64:

Регистры RBX, RBP, RDI, RSI , RSP, R12, R13, R14 и R15 считаются энергонезависимыми (сохраненными вызываемыми).

Но для System V AMD64 ABI:

Если вызываемый абонент желает использовать регистры RBX, RBP и R12 – R15, он должен восстановить их исходные значения, прежде чем вернуть управление вызывающей стороне.

Там не упоминалось ничего о rdi и rsi.

Я также читал, что % rax,% rcx,% rdx, % rdi,% rsi ,% rsp и% r8-r11 считаются регистрами сохранения вызовов (из в формате pdf)

У меня такой вопрос, является ли соглашение о вызовах различным на разных платформах? (Я пытаюсь написать какую-то функцию libc в asm для среды unix)

Я не смог найти ни одной статьи, обсуждающей эту тему, также полезны ресурсы по этой теме. Я хотел знать преимущества и недостатки этих соглашений.

1 Ответ

2 голосов
/ 28 марта 2019

Да, во всех соглашениях о вызовах функций, о которых я знаю, регистры прохождения аргументов перекрываются вызовами. (За исключением соглашений о вызовах системных вызовов, где обычно сохраняются все регистры, кромевозвращаемое значение, включая передачу аргументов. За исключением того, что x86-64 syscall уничтожает RCX и R11 ...)

В частности, в x86-64 System V все регистры, кроме RBX, RBP, RSP и R12-R15 замкнуты.(Это включает регистры xmm0-15, x87 / mmx и регистры маски AVX512 zmm0-31 и k0-k7.)

Какие регистры сохраняются при вызове функции linux x86-64 показывает таблицу из документа ABI .


Соглашение о вызовах / ABI определяет состояние регистров как сохраняемых или закрытых.Разные соглашения могут делать разные выборы.

И да, Microsoft Windows выбрала другое соглашение о вызовах от всех остальных: Почему Windows64 использует другое соглашение о вызовах из всех других ОС на x86-64? В Windows x64 RDI сохраняется, как и в большинстве 32-битных соглашений о вызовах.

Но в x86-64 System V разработчики выбирали регистры с нуля, и (как показывает мой ответ на этот связанный вопрос) обнаружил, что при использовании RDI и RSI для первых двух аргументов сохраняются инструкции (при сборке SPECint с ранним портом x86-64 gcc).Вероятно, потому что gcc в то время любил встроить memset или memcpy с использованием rep stosd, или реализация библиотеки использовала это.

(Нет смысла говорить, что RDI изначально * 1027)* call-clobbered, ISA x86-64 не определяет это. Это зависит от каждой платформы.)


Терминология:

IНенавижу терминологию «сохраненный вызывающий абонент» и терминология «сохраненный вызывающий абонент»: вводить в заблуждение взгляды с двух разных точек зрения (вызывающий и вызываемый) и ошибочно подразумевать, что каждый регистр действительно сохраняется где-то на каждом call.Кроме того, имена различаются только на 1 букву, поэтому они не очень визуально различимы при чтении.

"сохранено" или "засорено" отлично;они работают с любой точки зрения.(Что звонящий будет делать с вашими регами, или что вы можете делать с регами звонящего.) Более того, они говорят сами за себя.

...