Skip to content

Лабораторная работа 8

Inspirate789 edited this page Apr 20, 2022 · 2 revisions

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

Соглашение о вызове — формализация правил вызова подпрограмм, которое должно включать:

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

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

cdecl32 — соглашение о вызовах, используемое компиляторами для языка Си на 32-разрядных системах.

  1. Аргументы функций передаются через стек, справа налево.
  2. Аргументы, размер которых меньше 4-х байт, расширяются до 4-х байт.
  3. Очистку стека производит вызывающая программа.
  4. Возврат параметров 1, 2, 4 байта (целые числа, указатели) - через eax.
  5. Возврат больших структур, массивов, строк - указателем через eax.

Перед вызовом функции вставляется код, выполняющий следующие действия:

  • сохранение значений регистров, используемых внутри функции;
  • запись в стек аргументов функции. После вызова функции вставляется код, выполняющий следующие действия:
  • очистка стека;
  • восстановление значений регистров. В 64-разрядных системах могут применяться другие соглашения.

Ассемблерная вставка

Составной оператор языка высокого уровня, телом которого является код на языке ассемблера.

Пример вставки на C++ для Visual Studio 2019:

#include <iostream>
int main()
{
    int i;
    __asm {
    mov eax, 5;
    mov i, eax;
    }
    std::cout << i;
    return 0;
}

Пример импортирования программы, написанной на ассемблере, в программу на Си++:

// main.cpp
#include <iostream>
extern "C"
{
    void testAsm(); // подключение в код на Си/Си++ функции
    // на другом языке программирования,
    // выполненной в соответствии с соглашениями
    // о вызовах Си
}

int main()
{
    int i;
    __asm {
    mov eax, 5;
    mov i, eax;
    }
    std::cout << i;
    testAsm();
    __asm {
    mov i, eax;
    }
    std::cout << i;
    return 0;
}
; test.asm
.686
.MODEL FLAT, C
.STACK

.CODE

testAsm PROC
    mov eax, 7
    ret
testAsm ENDP
END

Такая программа выведет в консоль символы 57: первая цифра задана в ассемблерной вставке, вторая - в отдельном файле.