See also ebooksgratis.com: no banners, no cookies, totally FREE.

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
Privacy Policy Cookie Policy Terms and Conditions
Соглашение вызова — Википедия

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

Материал из Википедии — свободной энциклопедии

Соглашение вызова (англ. Calling convention) — часть двоичного интерфейса приложений, которая регламентирует технические особенности вызова подпрограммы, передачи параметров, возврата из подпрограммы и передачи результата вычислений в точку вызова.

Содержание

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

Соглашение вызова определяет следующие особенности процесса использования подпрограмм:

  • Расположение входных параметров подпрограммы и возвращаемых ею значений. Наиболее распространённые варианты:
  • Порядок передачи параметров. При использовании для параметров стека определяет, в каком порядке параметры должны быть помещены в стек, при использовании регистров — порядок сопоставления параметров и регистров. Варианты:
    • прямой порядок — параметры размещаются в том же порядке, в котором они перечислены в описании подпрограммы. Преимущество — единообразие кода и записи на языке высокого уровня;
    • обратный порядок — параметры передаются в порядке от конца к началу. Преимущество — при любом количестве параметров на вершине стека после адреса возврата оказывается сначала первый параметр, за ним второй и так далее. Это упрощает реализацию подпрограмм с неопределённым числом параметров произвольных типов.
  • Кто возвращает указатель стека на исходную позицию:
    • вызываемая подпрограмма — это сокращает объём команд, необходимых для вызова подпрограммы, поскольку команды восстановления указателя стека записываются только один раз, в конце подпрограммы;
    • вызывающая программа — в этом случае вызов становится сложнее, но облегчается использование подпрограмм с переменным количеством и типом параметров.
  • Какой командой вызывать подпрограмму и какой — возвращаться в основную программу. Например, в стандартном режиме x86 подпрограмму можно вызвать через call near, call far и pushf/call far (для возврата применяются соответственно retn, retf, iret).
  • Содержимое каких регистров процессора подпрограмма обязана восстановить перед возвратом.

Соглашения вызова зависят от архитектуры целевой машины.

[править] Когда это важно

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

[править] Наиболее распространённые соглашения вызова на 32-битном x86

Список неполный, написаны основные из применяемых по сей день.

Во всех нижеперечисленных соглашениях подпрограмма обязана обеспечить восстановление перед возвратом значений сегментных регистров процессора, а также регистров ESP и EBP. Значения остальных могут не восстанавливаться. Возвращаемое значение функции хранится в регистре eax. Если его размер слишком велик для размещения в регистре, то оно размещается на верхушке стека, а значение в регистре eax будет указывать на него.

[править] cdecl

Основной способ вызова для Си (отсюда название, сокращение от «c-declaration»). Параметры закладываются в стек в обратном порядке. Указатель стека на исходную позицию возвращает вызывающая программа.

[править] pascal

Основной способ вызова для Паскаля, также применялся в Windows 3.x. Параметры закладываются в стек с начала. Указатель стека на исходную позицию возвращает подпрограмма.

[править] winapi / stdcall

Применяется в Win32. Параметры закладываются в стек с конца. Указатель стека на исходную позицию возвращает подпрограмма.

[править] fastcall

Передача параметров через регистры, обычно самая быстрая; если все параметры и промежуточные результаты умещаются в регистрах, манипуляции со стеком вообще не нужны. Fastcall не стандартизирован, поэтому используется только в функциях, которые программа не экспортирует наружу. Например, у Borland параметры передаются слева направо в eax, ecx, edx и, если параметров больше трёх, в стеке. Указатель стека на исходное значение возвращает подпрограмма.

Fastcall Borland применяется по умолчанию в Delphi.

[править] safecall

Обеспечивает более удобный для использования в распространённых языках высокого уровня способ вызова методов интерфейсов при использовании модели COM.

Все методы интерфейсов COM представляют собой функции, возвращающие код завершения типа HRESULT, который должен анализироваться в месте вызова. Как правило, это не вполне удобно: большинство используемых с этой технологией языков имеют механизмы обработки исключений, и в них удобнее использовать обычные вызовы функций и процедур, возвращающие прикладные значения, а для обработки ошибок применять исключения. Именно такую возможность предоставляет safecall.

Можно считать, что вызов

function DoSomething(a: DWORD): DWORD; safecall;

в действительности представляет собой вызов

function DoSomething(a: DWORD; out Result: DWORD): HResult; stdcall;

причём организованный таким образом, что если возвращённое значение типа HRESULT будет содержать флаг ошибки, то в результате вызова будет сгенерировано исключение с кодом и текстом, соответствующим обнаруженной ошибке.


На других языках


aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -