~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ 63315E3477652FEC988915F12F31D1B5__1718355420 ✰
Заголовок документа оригинал.:
✰ Calling convention - Wikipedia ✰
Заголовок документа перевод.:
✰ Соглашение о вызовах — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Calling_convention ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/63/b5/63315e3477652fec988915f12f31d1b5.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/63/b5/63315e3477652fec988915f12f31d1b5__translat.html ✰
Дата и время сохранения документа:
✰ 21.06.2024 12:52:02 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 14 June 2024, at 11:57 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Соглашение о вызовах — Википедия Jump to content

Соглашение о вызовах

Из Википедии, бесплатной энциклопедии

В информатике соглашение о вызовах — это схема уровня реализации (низкоуровневая) того, как подпрограммы или функции получают параметры от вызывающего объекта и как они возвращают результат. [1] Когда некоторый код вызывает функцию, были приняты решения о том, где и как параметры передаются в эту функцию, а также где и как возвращаются результаты из этой функции, причем эти передачи обычно выполняются через определенные регистры или внутри кадра стека при вызове . куча . Существуют варианты дизайна того, как задачи подготовки к вызову функции и восстановления среды после завершения функции распределяются между вызывающим и вызываемым объектом. Некоторые соглашения о вызовах определяют способ вызова каждой функции. Для каждого вызова функции следует использовать правильное соглашение о вызовах, чтобы обеспечить правильное и надежное выполнение всей программы с использованием этих функций.

Введение [ править ]

Соглашения о вызовах обычно считаются частью двоичного интерфейса приложения (ABI). Их можно рассматривать как контракт между вызывающей стороной и вызываемой функцией. [1]

Связанные понятия [ править ]

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

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

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

Для некоторых языков соглашение о вызовах включает детали обработки ошибок или исключений (например, Go , Java ), а для других — нет (например, C++ ).

Для удаленных вызовов процедур существует аналогичная концепция, называемая маршаллингом .

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

Различные соглашения о вызовах [ править ]

Соглашения о вызовах могут отличаться:

  • Где размещаются параметры. Варианты включают регистры , стек вызовов , сочетание того и другого или другие структуры памяти.
  • Порядок передачи параметров. Варианты включают порядок слева направо, справа налево или что-то более сложное.
  • функции, которые принимают переменное количество аргументов ( вариативные функции Как обрабатываются ). Опции включают только что переданные по порядку (при условии, что первый параметр находится в очевидной позиции) или переменные части массива.
  • Как возвращаемые значения доставляются от вызывающего абонента обратно вызывающему. Варианты включают в себя стек, регистр или ссылку на что-то, выделенное в куче.
  • Как долго или комплексные значения обрабатываются, возможно, путем разделения на несколько регистров, внутри кадра стека или со ссылкой на память.
  • Какие регистры гарантированно будут иметь то же значение при возврате вызываемого объекта, что и при вызове вызываемого объекта. Говорят, что эти регистры сохраняются или сохраняются , поэтому они не являются энергозависимыми .
  • Как задача настройки и очистки после вызова функции распределяется между вызывающим и вызываемым объектом. В частности, как кадр стека , чтобы вызывающая сторона могла продолжить работу после того, как вызываемая сторона завершила работу. восстанавливается
  • Передаются ли и как метаданные , описывающие аргументы
  • Здесь хранится предыдущее значение указателя кадра , которое используется для восстановления кадра стека после завершения подпрограммы. Опции включаются в стек вызовов или в определенный регистр. Иногда указатели кадров вообще не используются. [2]
  • Где размещаются какие-либо статические ссылки на область действия для нелокального доступа к данным подпрограммы (обычно в одной или нескольких позициях в кадре стека, но иногда в общем регистре или, для некоторых архитектур, в регистрах специального назначения)
  • Для объектно-ориентированных языков способ обращения к объекту функции.

Соглашения о вызовах внутри одной платформы [ править ]

Иногда на одной платформе появляется несколько соглашений о вызовах; данная платформа и языковая реализация могут предлагать выбор соглашений о вызовах. Причины этого включают производительность, адаптацию соглашений других популярных языков, а также ограничения или соглашения, налагаемые различными « вычислительными платформами ».

Во многих архитектурах имеется только одно широко используемое соглашение о вызовах, часто предлагаемое архитектором. Для RISC, включая SPARC, MIPS и RISC-V , часто используются имена регистров, основанные на этом соглашении о вызовах. Например, регистры MIPS $4 через $7 иметь «имена ABI» $a0 через $a3, что отражает их использование для передачи параметров в стандартном соглашении о вызовах. (ЦП RISC имеют множество эквивалентных регистров общего назначения, поэтому обычно нет аппаратных причин давать им имена, кроме чисел.)

Соглашение о вызовах языка данной программы может отличаться от соглашения о вызовах базовой платформы, ОС или какой-либо библиотеки, с которой связана ссылка. Например, в 32-разрядной версии Windows вызовы операционной системы имеют соглашение о вызовах stdcall , тогда как многие C программы , которые там выполняются, используют соглашение о вызовах cdecl . Чтобы учесть эти различия в соглашении о вызовах, компиляторы часто допускают ключевые слова, определяющие соглашение о вызовах для данной функции. будут Объявления функций включать дополнительные ключевые слова, специфичные для платформы, которые указывают используемое соглашение о вызовах. При правильной обработке компилятор сгенерирует код для вызова функций соответствующим образом.

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

Архитектуры [ править ]

x86 (32-разрядная версия) [ править ]

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

Пример вызова:

 нажать   EAX              ;   передать результат регистра 
  push   dword   [  EBP  +  20  ]   ;   передать некоторую переменную памяти (синтаксис FASM/TASM) 
  push   3                ;   передать некоторый постоянный 
  вызов   Calc             ;   возвращенный результат теперь находится в EAX 

Типичная структура вызываемого объекта: (некоторые или все (кроме ret) приведенные ниже инструкции могут быть оптимизированы с помощью простых процедур). Некоторые соглашения оставляют пространство параметров выделенным, используя обычный ret вместо ret imm16. В этом случае вызывающий абонент может add esp,12 в этом примере или иным образом справиться с изменением ESP.

расчет: 
   нажмите   EBP              ;   сохранить указатель старого кадра 
   mov   EBP  ,  ESP           ;   получить указатель нового кадра 
   sub   ESP  ,  localsize     ;   зарезервируйте место в стеке для местных жителей 
   . 
    .                      ;   выполнить вычисления, оставить результат в EAX 
   . 
    мов   ESP  ,  EBP           ;   свободное место для местных жителей 
   поп   EBP               ;   восстановить указатель старого кадра 
   ret   paramsize         ;   свободное пространство параметров и возврат. 

x86-64 [ править ]

В 64-битной версии архитектуры x86, известной как x86-64 , AMD64 и Intel 64, обычно используются две последовательности вызовов. В Windows используется одна последовательность вызовов, определенная Microsoft; другая последовательность вызовов, указанная в AMD64 System V ABI, используется Unix-подобными системами и, с некоторыми изменениями, OpenVMS . Поскольку x86-64 имеет больше регистров общего назначения, чем 16-битный x86, оба соглашения передают некоторые аргументы в регистрах.

ARM (A32) [ править ]

Стандартное 32-битное соглашение о вызовах ARM распределяет 16 регистров общего назначения следующим образом:

  • r15: Счетчик программ (согласно спецификации набора команд).
  • r14: Регистр связи. Инструкция BL, используемая при вызове подпрограммы, сохраняет адрес возврата в этом регистре.
  • r13: Указатель стека. Инструкции Push/Pop в режиме работы «Thumb» используют только этот регистр.
  • r12: Рабочий регистр внутрипроцедурного вызова.
  • от r4 до r11: локальные переменные.
  • от r0 до r3: значения аргументов, передаваемые в подпрограмму, и результаты, возвращаемые из подпрограммы.

Если тип возвращаемого значения слишком велик, чтобы поместиться в от r0 до r3, или его размер не может быть определен статически во время компиляции, то вызывающая сторона должна выделить место для этого значения во время выполнения и передать указатель на это пространство в r0.

Подпрограммы должны сохранять содержимое от r4 до r11 и указатель стека (возможно, сохраняя их в стек в прологе функции , затем используя их как рабочее пространство, а затем восстанавливая их из стека в эпилоге функции ). В частности, подпрограммы, вызывающие другие подпрограммы, должны сохранить адрес возврата в регистре связи r14 в стеке перед вызовом этих других подпрограмм. Однако таким подпрограммам не требуется возвращать это значение в r14 — им просто нужно загрузить это значение в r15, программный счетчик, чтобы вернуться.

Соглашение о вызовах ARM требует использования полного нисходящего стека. Кроме того, указатель стека всегда должен быть выровнен по 4 байтам и всегда должен быть выровнен по 8 байтам при вызове функции с открытым интерфейсом. [3]

Это соглашение о вызовах приводит к тому, что «типичная» подпрограмма ARM:

  • В прологе поместите r4 в r11 в стек и поместите адрес возврата в r14 в стек (это можно сделать с помощью одной инструкции STM);
  • Скопируйте все переданные аргументы (от r0 до r3) в локальные временные регистры (от r4 до r11);
  • Назначьте другие локальные переменные оставшимся локальным временным регистрам (от r4 до r11);
  • Выполните вычисления и при необходимости вызовите другие подпрограммы с помощью BL, предполагая, что от r0 до r3, r12 и r14 не будут сохранены;
  • Поместите результат в r0;
  • В эпилоге вытащите из стека r4 в r11 и вытащите адрес возврата в программный счетчик r15. Это можно сделать с помощью одной инструкции LDM.

ARM (A64) [ править ]

Соглашение о вызовах 64-битного ARM ( AArch64 ) распределяет 31 регистр общего назначения следующим образом: [4]

  • x31 (SP): указатель стека или нулевой регистр, в зависимости от контекста.
  • x30 (LR): регистр связи процедур, используемый для возврата из подпрограмм.
  • x29 (FP): указатель кадра.
  • от x19 до x28: сохраняется вызываемый абонент.
  • x18 (PR): Регистр платформы. Используется для некоторых специальных целей, специфичных для операционной системы, или для дополнительного регистра, сохраняемого вызывающим абонентом.
  • x16 (IP0) и x17 (IP1): рабочие регистры внутрипроцедурного вызова.
  • От x9 до x15: локальные переменные, вызывающий абонент сохранен.
  • x8 (XR): Косвенный адрес возвращаемого значения.
  • от x0 до x7: значения аргументов, передаваемые подпрограмме, и результаты, возвращаемые из нее.

Все регистры, начинающиеся с x, имеют соответствующий 32-битный регистр с префиксом w . Таким образом, 32-битный x0 называется w0.

Аналогично, 32 регистра с плавающей запятой распределяются следующим образом: [5]

  • от v0 до v7: значения аргументов, передаваемые подпрограмме, и результаты, возвращаемые из нее.
  • v8–v15: сохраняется вызываемый абонент, но необходимо сохранить только нижние 64 бита.
  • v16–v31: локальные переменные, вызывающая сторона сохранена.

RISC-V ISA [ edit ]

RISC-V имеет определенное соглашение о вызовах с двумя вариантами: с плавающей запятой или без нее. [6] Он передает аргументы в регистры, когда это возможно.

POWER, PowerPC и Power ISA [ править ]

Архитектуры POWER одноуровневых , PowerPC и Power ISA имеют большое количество регистров, поэтому большинство функций могут передавать все аргументы в регистры для вызовов . Дополнительные аргументы передаются в стек, и место для аргументов на основе регистров также всегда выделяется в стеке для удобства вызываемой функции в случае, если используются многоуровневые вызовы (рекурсивные или иные) и регистры необходимо сохранить. Это также используется в вариативных функциях , таких как printf(), где к аргументам функции необходимо обращаться как к массиву. Для всех процедурных языков используется единое соглашение о вызовах.

Инструкции ветвления и связи сохраняют адрес возврата в специальном регистре связи , отдельном от регистров общего назначения; процедура возвращается вызывающей стороне с инструкцией ветвления, которая использует регистр связи в качестве адреса назначения. Листовым процедурам не требуется сохранять или восстанавливать регистр связи; неконечные подпрограммы должны сохранять адрес возврата перед вызовом другой подпрограммы и восстанавливать его перед возвратом, сохраняя его с помощью команды «Переместить из регистра специального назначения», чтобы переместить регистр связи в регистр общего назначения и, при необходимости, затем сохранить его в стек и восстановить, если оно было сохранено в стеке, загрузив сохраненное значение регистра связи в регистр общего назначения, а затем используя команду «Переместить в регистр специального назначения» для перемещения регистра, содержащего сохраненную информацию. значение регистра связи в регистр связи.

МИПС [ править ]

О32 [7] ABI является наиболее часто используемым ABI благодаря своему статусу исходного ABI System V для MIPS. [8] Он основан строго на стеке, всего с четырьмя регистрами. $a0-$a3доступен для передачи аргументов. Эта кажущаяся медлительность, а также устаревшая модель с плавающей запятой, состоящая всего из 16 регистров, способствовали распространению многих других соглашений о вызовах. ABI сформировался в 1990 году и никогда не обновлялся с 1994 года. Он определен только для 32-битного MIPS, но GCC создал 64-битный вариант под названием O64. [9]

N64 ABI (не связанный с Nintendo 64 Для 64-разрядной версии чаще всего используется ) от Silicon Graphics. Самым важным улучшением является то, что теперь для передачи аргументов доступны восемь регистров; Это также увеличивает количество регистров с плавающей запятой до 32. Существует также версия ILP32 под названием N32, которая использует 32-битные указатели для меньшего кода, аналогично x32 ABI . Оба работают в 64-битном режиме процессора. [9]

Было предпринято несколько попыток заменить O32 32-битным ABI, который больше напоминает N32. На конференции 1995 года был предложен MIPS EABI, 32-битная версия которого была очень похожа. [10] EABI вдохновил MIPS Technologies предложить более радикальный ABI «NUBI», который дополнительно повторно использует регистры аргументов для возвращаемого значения. [11] MIPS EABI поддерживается GCC, но не LLVM; ни один из них не поддерживает NUBI.

Для всех O32 и N32/N64 адрес возврата хранится в $raрегистр. Это устанавливается автоматически с помощью JAL (перейти и связать) или JALR(регистрация перехода и соединения). Стек растет вниз.

СПАРК [ править ]

Архитектура SPARC , в отличие от большинства RISC- архитектур, построена на окнах регистров . В каждом окне регистров имеется 24 доступных регистра: 8 — «входящие» регистры (%i0-%i7), 8 — «локальные» регистры (%l0-%l7) и 8 — «выходящие» регистры (% о0-%о7). Регистры «in» используются для передачи аргументов вызываемой функции, а любые дополнительные аргументы необходимо помещать в стек . Однако вызываемая функция всегда выделяет пространство для обработки потенциального переполнения окна регистра, локальных переменных и (в 32-битном SPARC) возврата структуры по значению. Чтобы вызвать функцию, аргументы вызываемой функции помещаются в «выходные» регистры; когда функция вызывается, «выходные» регистры становятся «входящими» регистрами, и вызываемая функция получает доступ к аргументам в своих «входящих» регистрах. Когда вызываемая функция завершается, она помещает возвращаемое значение в первый входной регистр, который становится первым выходным регистром при возвращении вызванной функции.

Система V ABI , [12] которому следуют большинство современных Unix -подобных систем, передает первые шесть аргументов в «входящие» регистры от %i0 до %i5, резервируя %i6 для указателя кадра и %i7 для адреса возврата.

IBM System/360 его преемники и

IBM System/360 — еще одна архитектура без аппаратного стека. Приведенные ниже примеры иллюстрируют соглашение о вызовах, использовавшееся в OS/360 и его преемниках до появления 64-разрядной версии z/Architecture ; другие операционные системы для System/360 могут иметь другие соглашения о вызовах.

Вызов программы:

LA 1,ARGS Загрузить адрес списка аргументов
      L 15,=A(SUB) Загрузка адреса подпрограммы
      BALR 14,15 Переход к вызываемой процедуре 1 ...
 ARGS DC A(FIRST) Адрес первого аргумента
      Постоянный ток А (ВТОРОЙ)
      ...
      DC A(THIRD)+X'80000000' Последний аргумент 2 

Вызываемая программа:

SUB EQU * Это точка входа в подпрограмму.
 

Стандартная последовательность ввода:

 ИСПОЛЬЗОВАНИЕ *,15 3 
     STM 14,12,12(13) Сохранить регистры 4 ST 13,SAVE+4 Сохранить адрес области сохранения вызывающего абонента
      LA 12,SAVE Цепочка сохранений
      СТ 12,8(13)
      LR 13,12
      ...
 

Стандартная последовательность возврата:

 Л 13,СОХРАНИТЬ+4 5 ЛМ 14,12,12(13)
      Л 15,РЕТВАЛЬ 6 BR 14 Возврат к абоненту
 СОХРАНИТЬ DS 18F 7 

Примечания:

  1. The BALR Инструкция сохраняет адрес следующей инструкции (адрес возврата) в регистре, указанном первым аргументом (регистр 14), и переходит к адресу второго аргумента в регистре 15.
  2. Вызывающая сторона передает адрес списка адресов аргументов в регистр 1. В последнем адресе установлен старший бит, обозначающий конец списка. Это ограничивает программы, использующие это соглашение, 31-битной адресацией.
  3. Адрес вызываемой процедуры находится в регистре 15. Обычно он загружается в другой регистр, и регистр 15 не используется в качестве базового регистра.
  4. The STMинструкция сохраняет регистры 14, 15 и от 0 до 12 в 72-байтовой области, предоставленной вызывающей стороной, называемой областью сохранения , на которую указывает регистр 13. Вызываемая процедура предоставляет свою собственную область сохранения для использования подпрограммами, которые она вызывает; адрес этой области обычно хранится в регистре 13 на протяжении всей процедуры. Следующие инструкции STM обновить прямую и обратную цепочки, связывающие эту область сохранения с областью сохранения вызывающего абонента.
  5. Последовательность возврата восстанавливает регистры вызывающей стороны.
  6. Регистр 15 обычно используется для передачи возвращаемого значения.
  7. Объявление saveareaстатически в вызываемой подпрограмме делает ее нереентерабельной и нерекурсивной ; реентерабельная программа использует динамический savearea, полученный либо из операционной системы и освобожденный при возврате, либо в памяти, переданной вызывающей программой.

В системе/390 ABI [13] и z/Architecture ABI, [14] используется в Linux:

  • Регистры 0 и 1 энергозависимы.
  • Регистры 2 и 3 используются для передачи параметров и возвращаемых значений.
  • Регистры 4 и 5 также используются для передачи параметров.
  • Регистр 6 используется для передачи параметров и должен быть сохранен и восстановлен вызываемой стороной.
  • Регистры с 7 по 13 предназначены для использования вызываемым абонентом и должны быть им сохранены и восстановлены.
  • Регистр 14 используется для обратного адреса.
  • Регистр 15 используется как указатель стека.
  • Регистры с плавающей запятой 0 и 2 используются для передачи параметров и возвращаемых значений.
  • Регистры с плавающей запятой 4 и 6 предназначены для использования вызываемым абонентом и должны быть им сохранены и восстановлены.
  • В z/Architecture регистры с плавающей запятой 1, 3, 5 и с 7 по 15 предназначены для использования вызываемым объектом.
  • Регистр доступа 0 зарезервирован для использования системой.
  • Регистры доступа с 1 по 15 предназначены для использования вызываемым абонентом.

Дополнительные аргументы передаются в стек.

СуперХ [ править ]

регистр Windows CE 5.0 GCC Ренесас
Р0 Возвращаемые значения. Временно для расширения псевдоинструкций сборки. Неявный источник/назначение для 8/16-битных операций. Не сохранилось. Возвращаемое значение, вызывающий абонент сохраняет Переменные/временные. Не гарантировано
Р1..Р3 Служит временными регистрами. Не сохранилось. Звонивший сохранил царапину. Адрес структуры (сохранение звонящего по умолчанию) Переменные/временные. Не гарантировано
Р4..Р7 Первые четыре слова целочисленных аргументов. Область построения аргументов обеспечивает пространство, в которое могут попасть аргументы, содержащие R4–R7. Не сохранилось. Передача параметров, сохранение вызывающего абонента Аргументы. Не гарантировано.
Р8..Р13 Служит постоянными регистрами. Сохранено. Вызов сохранений Переменные/временные. Гарантировано.
Р14 Указатель кадра по умолчанию. (R8-R13 также может служить указателем кадра, а листовые процедуры могут использовать R1-R3 в качестве указателя кадра.) Сохраняется. Указатель кадра, FP, сохранение вызываемого абонента Переменные/временные. Гарантировано.
15 рэндов Служит указателем стека или постоянным регистром. Сохранено. Указатель стека, SP, сохранение вызываемого абонента Указатель стека. Гарантировано.

Примечание: «сохраненные» резервы для сохранения вызываемого абонента; то же самое касается и «гарантированного».

68к [ править ]

Наиболее распространенное соглашение о вызовах для серии Motorola 68000 : [15] [16] [17] [18]

  • d0, d1, a0 и a1 — рабочие регистры.
  • Все остальные регистры сохраняются вызываемым абонентом.
  • a6 — указатель кадра, который можно отключить с помощью опции компилятора.
  • Параметры помещаются в стек справа налево.
  • Возвращаемое значение сохраняется в d0.

IBM 1130 [ править ]

IBM 1130 представлял собой небольшую 16-битную машину с пословной адресацией. В нем было всего шесть регистров плюс индикаторы состояния и не было стека. Регистрами являются регистр адреса инструкции (IAR) , аккумулятор (ACC) , расширение аккумулятора (EXT) и три индексных регистра X1–X3. Вызывающая программа отвечает за сохранение ACC, EXT, X1 и X2. [19] Есть две псевдооперации для вызова подпрограмм: CALL кодировать неперемещаемые подпрограммы, напрямую связанные с основной программой, и LIBF для вызова подпрограмм перемещаемой библиотеки через вектор передачи . [20] Обе псевдооперации разрешаются в IAR Branch и Store ( BSI) машинная инструкция, которая сохраняет адрес следующей инструкции по ее эффективному адресу (EA) и переходит к EA+1.

Аргументы следуют за BSI‍—‌обычно это адреса аргументов, состоящие из одного слова‍—‌вызываемая подпрограмма должна знать, сколько аргументов ожидать, чтобы она могла пропустить их при возврате. Альтернативно аргументы могут передаваться в регистрах. Подпрограммы функций возвращали результат в ACC для реальных аргументов или в ячейку памяти, называемую псевдоаккумулятором действительных чисел (FAC). Аргументы и адрес возврата были адресованы с использованием смещения значения IAR, хранящегося в первом месте подпрограммы.

* 1130 пример подпрограммы
      ENT SUB Объявить «SUB» внешней точкой входа.
  SUB DC 0 Зарезервированное слово в точке входа, обычно кодируемое «DC *-*»
  * Код подпрограммы начинается здесь
  * Если были аргументы, адреса можно загрузить косвенно из адреса возврата.
      LDX I 1 SUB Загрузить в X1 адрес первого аргумента (например)
  ...
  * Возвратная последовательность
      LD RES Загрузить целочисленный результат в ACC
  * Если аргументы не были предоставлены, выполняется косвенный переход к сохраненному обратному адресу.
      BI SUB Если аргументы не были предоставлены
      КОНЕЦ ПОДПИСКИ
 

Подпрограммы в IBM 1130, CDC 6600 и PDP-8 (все три компьютера были представлены в 1965 году) хранят обратный адрес в первом месте подпрограммы. [21]

Соглашения о вызовах вне машинных архитектур [ править ]

Резьбовой код [ править ]

Многопоточный код возлагает всю ответственность за настройку и очистку после вызова функции на вызываемый код. Вызывающий код ничего не делает, а лишь выводит список вызываемых подпрограмм. Это помещает весь код настройки и очистки функции в одно место — пролог и эпилог функции — а не во многих местах, где функция вызывается. Это делает многопоточный код наиболее компактным соглашением о вызовах.

Поточный код передает все аргументы в стек. Все возвращаемые значения возвращаются в стек. Это делает наивные реализации медленнее, чем соглашения о вызовах, которые сохраняют больше значений в регистрах. Однако реализации многопоточного кода, которые кэшируют в регистрах несколько значений верхнего уровня стека, в частности адрес возврата, обычно работают быстрее, чем соглашения о вызове подпрограмм, которые всегда помещают и извлекают адрес возврата в стек. [22] [23] [24]

ПЛ/И [ править ]

Соглашение о вызовах по умолчанию для программ, написанных на языке PL/I, передает все аргументы по ссылке , хотя при желании можно указать и другие соглашения. Аргументы обрабатываются по-разному для разных компиляторов и платформ, но обычно адреса аргументов передаются через список аргументов в памяти. Может быть передан окончательный скрытый адрес, указывающий на область, содержащую возвращаемое значение. Из-за большого разнообразия типов данных, поддерживаемых PL/I, также может быть передан дескриптор данных, чтобы определить, например, длину символьных или битовых строк, размерность и границы массивов ( дополнительные векторы ) или макет и содержимое. данных структуры . Фиктивные аргументы создаются для аргументов, которые являются константами или не соответствуют типу аргумента, ожидаемого вызываемой процедурой.

См. также [ править ]

Ссылки [ править ]

  1. ^ Перейти обратно: а б «Соглашения о вызовах» . cs.cornell.edu . Проверено 5 марта 2024 г.
  2. ^ «/Oy (пропуск указателя кадра)» . Learn.microsoft.com . 3 августа 2021 г. Проверено 14 июня 2024 г.
  3. ^ «Стандарт вызова процедур для архитектуры ARM» . 2021.
  4. ^ «Параметры в регистрах общего назначения» . Руководство программиста серии ARM Cortex-A для ARMv8-A . Проверено 12 ноября 2020 г.
  5. ^ «Параметры в NEON и регистрах с плавающей запятой» . Developer.arm.com . Проверено 13 ноября 2020 г.
  6. ^ «Соглашение о вызовах RISC-V» (PDF) .
  7. ^ «Краткий справочник по набору инструкций MIPS32» .
  8. ^ Свитмен, Доминик. См. MIPS Run (2-е изд.). Издательство Морган Кауфманн . ISBN  0-12088-421-6 .
  9. ^ Перейти обратно: а б «История MIPS ABI» .
  10. ^ Кристофер, Эрик (11 июня 2003 г.). "Документация mips eabi" . [email protected] (список рассылки) . Проверено 19 июня 2020 г.
  11. ^ «НУБИ» .
  12. ^ Дополнение к процессору SPARC для бинарного интерфейса приложения System V (3-е изд.).
  13. ^ «Дополнение к двоичному интерфейсу приложения S / 390 ELF» .
  14. ^ «Дополнение к двоичному интерфейсу приложения zSeries ELF» .
  15. ^ Смит, доктор Майк. «Сравнение регистров SHARC (21k) и 68k» .
  16. ^ XGCC: Языковая система Gnu C/C++ для разработки встраиваемых систем (PDF) . Корпорация инструментов встроенной поддержки. 2000. с. 59.
  17. ^ «COLDFIRE/68K: ThreadX для семейства Freescale ColdFire» . Архивировано из оригинала 2 октября 2015 г.
  18. ^ Мошовос, Андреас. «Продолжение подпрограмм: передача аргументов, возврат значений и распределение локальных переменных» . все регистры, кроме d0, d1, a0, a1 и a7, должны сохраняться во время вызова.
  19. ^ Корпорация IBM (1967). Система IBM 1130 Disk Monitor, введение в систему версии 2 (C26-3709-0) (PDF) . п. 67 . Проверено 21 декабря 2014 г.
  20. ^ Корпорация IBM (1968). Язык ассемблера IBM 1130 (C26-5927-4) (PDF) . стр. 24–25.
  21. ^ Смотерман, Марк (2004). «Поддержка вызовов подпрограмм и процедур: Ранняя история» .
  22. ^ Родригес, Брэд. «Движение вперед, часть 1: проектные решения в ядре Forth» . На 6809 или Zilog Super8 DTC работает быстрее, чем STC.
  23. ^ Эртль, Антон. «Скорость различных методов отправки переводчиков» .
  24. ^ Залески, Мэтью (2008). «Глава 4: Разработка и реализация эффективной интерпретации» . YETI: постепенно расширяемый интерпретатор трассировок . Хотя известно, что интерпретаторы с прямым потоком имеют плохие свойства прогнозирования ветвления... задержка вызова и возврата может быть больше, чем при косвенном переходе.

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: 63315E3477652FEC988915F12F31D1B5__1718355420
URL1:https://en.wikipedia.org/wiki/Calling_convention
Заголовок, (Title) документа по адресу, URL1:
Calling convention - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)