Мы с вами уже говорили о том, что в различных языках программирования используются различные правила вызова подпрограмм, и что для совместимости с ними в языке Delphi существуют директивы register, stdcall, pascal и cdecl. Применение этих директив становится особенно актуальным при разработке динамически загружаемых библиотек, которые используются в программах, написанных на других языках программирования.
 Чтобы разобраться с применением директив, обратимся к механизму вызова подпрограмм. Он основан на использовании стека.
 Стек — это область памяти, в которую данные помещаются в прямом порядке, а и извлекаются в обратном, по аналогии с наполнением и опустошением магазина патронов у стрелкового оружия. Очередность работы с элементами в стеке обозначается термином LIFO (от англ. Last In, First Out — последним вошел, первым вышел). (Существует еще обычная очередность работы с элементами, обозначаемая термином FIFO (от англ. First In, First Out — первым вошел, первым вышел)).
 Для каждой программы на время работы создается свой стек. Через него передаются параметры подпрограмм и в нем же сохраняются адреса возврата из этих подпрограмм. Именно благодаря стеку подпрограммы могут вызывать друг друга, или даже рекурсивно сами себя.
 Вызов подпрограммы состоит из «заталкивания» в стек всех аргументов и адреса следующей команды (для возврата к ней), а затем передачи управления на начало подпрограммы. По окончании работы подпрограммы из стека извлекается адрес возврата с передачей управления на этот адрес; одновременно с этим из стека выталкиваются аргументы. Происходит так называемая очистка стека. Это общая схема работы и у нее бывают разные реализации. В частности, аргументы могут помещаться в стек либо в прямом порядке (слева направо, как они перечислены в описании подпрограммы), либо в обратном порядке (справа налево), либо вообще, не через стек, а через свободные регистры процессора для повышения скорости работы. Кроме того, очистку стека может выполнять либо вызываемая подпрограмма, либо вызывающая программа. Выбор конкретного соглашения о вызове обеспечивают директивы register, pascal, cdecl и stdcall.
 Их смысл поясняет следующая таблица соглашений о вызове подпрограмм.
   |  Директива
  |   Порядок занесения аргументов в стек
  |   Кто отвечает за очистку стека
  |   Передача аргументов через регистры
  |  
  |  register
  |   Слева направо
  |   Подпрограмма
  |   Да
  |  
  |  pascal
  |   Слева направо
  |   Подпрограмма
  |   Нет
  |  
  |  cdecl
  |   Справа налево
  |   Вызывающая программа
  |   Нет
  |  
  |  stdcall
  |   Справа налево
  |   Подпрограмма
  |   Нет
  |  
 
 Примечание: директива register не означает, что все аргументы обязательно передаются через регистры процессора. Если число аргументов больше числа свободных регистров, то часть аргументов передается через стек.
 Возникает резонный вопрос: какое соглашение о вызове следует выбирать для процедур и функций динамически загружаемых библиотек. Ответ — соглашение stdcall:
   | procedure BubleSort(var Arr: array of Integer); stdcall;procedure QuickSort(var Arr: array of Integer); stdcall; |  
 
 Именно соглашение stdcall, изначально предназначенное для вызова подпрограмм операционной системы, лучше всего подходит для взаимодействия программ и библиотек, написанных на разных языках программирования. Все программы так или иначе используют функции операционной системы, следовательно они обязательно поддерживают соглашение stdcall.