Вызов функции ассемблера из C/C++

Последнее обновление: 18.10.2023

Как код ассмеблера может вызывать функции на С/С++, так и код на C/C++ может использовать функции ассемблера. И в данном случае действуют те же условности по параметрам и возвращаемым результатам.

Linux

Пусть у нас есть следующий файл sum.asm с кодом функции вычисления суммы двух чисел на ассемблере

global sum

section .text
; Функция возвращает сумму двух чисел
; Принимает два параметра:
; rdi - первое число
; rsi - второе число
; Результат функции возвращается через регистр rax
sum:
    mov rax, rdi
    add rax, rsi
    ret

Через регистры rdi и rsi функция принимает два числа, а через rax возвращает сумму. Скомпилируем файл кода в объектный файл:

nasm -f elf64 sum.asm -o sum.o

Пусть главный файл программы на языке С называется app.c, и он использует выше определенную функцию:

#include <stdio.h>

int sum(int, int); // пототип функции из файла на ассемблере

int main(void) {
    int result = sum(4, 2);    // вызываем функцию
    printf("result = %d\n", result);
}

Функция вычисления суммы принимает два числа через регистры rdi и rsi и возвращает число. Соотвествено в файле программы на языке С определяем протип этой функции int sum(int, int)

С помощью компилятора GCC скомплируем программу на языке С:

gcc app.c sum.o -o app

Пример компиляции и выполнения программы:

root@Eugene:~/asm# nasm -f elf64 sum.asm -o sum.o
root@Eugene:~/asm# gcc app.c sum.o -o app
root@Eugene:~/asm# ./app
result = 6
root@Eugene:~/asm#

Windows

Аналогичный код sum.asm на Windows:

global sum

section .text
; Функция возвращает сумму двух чисел
; Принимает два параметра:
; rcx - первое число
; rdx - второе число
; Результат функции возвращается через регистр rax
sum:
    mov rax, rcx
    add rax, rdx
    ret

В отличие от версиии для Linux тут изменены только регистры, через которые передаются параметры. Скомпилируем файл кода в объектный файл:

nasm -f win64 sum.asm -o sum.obj

Файл app.c, который использует эту функцию, ничем не отличается от Linux-версии:

#include <stdio.h>

int sum(int, int); // пототип функции из файла на ассемблере

int main(void) {
    int result = sum(4, 2);    // вызываем функцию
    printf("result = %d\n", result);
}

А вот компиляция на Windows может разнится в зависимости от выбранного компилятора. Если используется компилятор GCC, то скомплируем программу следующим образом:

gcc app.c sum.obj -o app.exe

Если применяется компилятор Visual C++ от Microsoft, то выполняем следующую команду:

cl app.c sum.obj
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850