Я додам ще одну відповідь, щоб розглянути деякі тангенціальні дискусії, що відбулися.
C ABI (двійковий інтерфейс програми) спочатку закликав передавати аргументи на стеку у зворотному порядку (тобто - натисканням справа наліво), де абонент також звільняє сховище стека. Сучасний ABI фактично використовує регістри для передачі аргументів, але багато міркувань щодо керування повертаються до передачі цього оригінального аргументу стека.
Оригінальний Pascal ABI, навпаки, відсунув аргументи зліва направо, і виклик повинен був викласти аргументи. Оригінальний C ABI перевершує оригінальний Pascal ABI у двох важливих моментах. Порядок поштовху аргументів означає, що зміщення стеку першого аргументу завжди відомо, дозволяючи функціям, які мають невідому кількість аргументів, де ранні аргументи контролюють, скільки інших аргументів є (алаprintf
).
Другий спосіб перевершити C ABI - це поведінка у випадку, якщо абонент та позивач не погоджуються щодо кількості аргументів. У випадку С, якщо ви фактично не отримаєте доступ до аргументів минулого, нічого поганого не відбувається. У Паскалі неправильна кількість аргументів вискакує зі стека, і вся стека зіпсована.
Оригінальний Windows 3.1 ABI був заснований на Pascal. Як такий, він використовував Паскаль ABI (аргументи в лівому та правому порядку, виклику виклику). Оскільки будь-яка невідповідність аргументації може призвести до корупції, склалася схема керування. Кожне ім'я функції було змінено числом, що вказує на розмір, в байтах, його аргументів. Отже, на 16-бітній машині функція (синтаксис C):
int function(int a)
Був розіграний function@2
, бо int
шириною два байти. Це було зроблено для того, що якщо невідповідність декларації та визначення, лінкер не зможе знайти функцію, а не пошкодить стек під час виконання. І навпаки, якщо програма посилається, то ви можете бути впевнені, що правильна кількість байтів вискакує зі стека в кінці дзвінка.
32-бітний Windows і далі використовуйте stdcall
ABI. Він схожий на Pascal ABI, за винятком того, що порядок натискань є як у C, справа наліво. Як і ABC Pascal, ім'я mangling змінює розмір байту аргументів у ім'я функції, щоб уникнути пошкодження стека.
На відміну від претензій, викладених деінде тут, C ABI не манить назви функцій навіть у Visual Studio. І навпаки, функції керування, прикрашені stdcall
специфікацією ABI, не властиві лише VS. GCC також підтримує цей ABI, навіть при компіляції для Linux. Це широко використовується Wine , що використовує власний завантажувач, щоб дозволити час запуску ліній компільованих бінарних файлів Linux до компільованих DLL файлів Windows.