Как код ассмеблера может вызывать функции на С/С++, так и код на C/C++ может использовать функции ассемблера. И в данном случае действуют те же условности по параметрам и возвращаемым результатам.
Пусть у нас есть следующий файл 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#
Аналогичный код 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