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 передают аргументы в стек. Возвращаемое значение (или указатель на него) возвращается в регистр. В некоторых соглашениях для первых нескольких параметров используются регистры, что может улучшить производительность, особенно для очень часто вызываемых коротких и простых листовых подпрограмм (т. е. подпрограмм, которые не вызывают другие подпрограммы).

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

 push EAX            ; pass some register result
 push dword [EBP+20] ; pass some memory variable (FASM/TASM syntax)
 push 3              ; pass some constant
 call calc           ; the returned result is now in EAX

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

calc:
  push EBP            ; save old frame pointer
  mov EBP,ESP         ; get new frame pointer
  sub ESP,localsize   ; reserve stack space for locals
  .
  .                   ; perform calculations, leave result in EAX
  .
  mov ESP,EBP         ; free space for locals
  pop EBP             ; restore old frame pointer
  ret paramsize       ; free parameter space and return.

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

Стандартное 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.

Соглашение о вызовах 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 имеет определенное соглашение о вызовах с двумя вариантами: с плавающей запятой или без нее. [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      Load argument list address
     L   15,=A(SUB)  Load subroutine address
     BALR 14,15      Branch to called routine1
     ...
ARGS DC A(FIRST)     Address of 1st argument
     DC A(SECOND)
     ...
     DC A(THIRD)+X'80000000' Last argument2

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

SUB  EQU *            This is the entry point of the subprogram

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

     USING *,153
     STM 14,12,12(13) Save registers4
     ST  13,SAVE+4    Save caller's savearea addr
     LA  12,SAVE      Chain saveareas
     ST  12,8(13)
     LR  13,12
     ...

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

     L   13,SAVE+45
     LM  14,12,12(13)
     L   15,RETVAL6
     BR  14          Return to caller
SAVE DS  18F         Savearea7

Примечания:

  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, сохранение вызываемого абонента Указатель стека. Гарантировано.

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

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

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

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 subroutine example
     ENT  SUB        Declare "SUB" an external entry point
 SUB DC   0          Reserved word at entry point, conventionally coded "DC *-*"
 *                   Subroutine code begins here
 *                   If there were arguments the addresses can be loaded indirectly from the return address
     LDX I 1 SUB     Load X1 with the address of the first argument (for example)
 ...
 *                   Return sequence
     LD      RES     Load integer result into ACC
 *                   If no arguments were provided, indirect branch to the stored return address
     B   I   SUB     If no arguments were provided
     END  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" . [электронная почта защищена] (список рассылки) . Проверено 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
Номер скриншота №: 7304bf31bc9ae77c5d4da3fb112eabf0__1720812660
URL1:https://arc.ask3.ru/arc/aa/73/f0/7304bf31bc9ae77c5d4da3fb112eabf0.html
Заголовок, (Title) документа по адресу, URL1:
Calling convention - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)