Пусть у нас есть следующий файл exponent.s с кодом функции возведения в степень на ассемблере
.globl exponent .text # Функция возвращает число в определенной степени # Принимает два параметра: # %rdi - число, возводимое в степень # %rsi - степень, в которую надо возвести число # Результат функции возвращается через регистр %rax exponent: movq $1, %rax # результат в %rax jmp condition # переход к проверке условия mainloop: mulq %rdi # %rax = %rax *%rdi decq %rsi condition: cmpq $0, %rsi jnz mainloop ret
Через регистр %rdi функция принимает число, которое надо возвести в степень, а через регистр %rsi - показатель степени. С помощью циклической конструкции последовательно уменьшаем значение в регистре %rax на %rdi, пока значение в %rsi не станет равным 0.
Стоит отметить, что в данном случае для примера мы предполагаем, что показатель степени у нас всегда будет положительный, в крайнем случае равен 0.
Пусть главный файл программы на языке С называется app.c, и он использует выше определенную функцию:
#include <stdio.h> int exponent(int, int); // пототип функции из файла на ассемблере int main(void) { int result = exponent(4, 2); // вызываем функцию printf("result = %d\n", result); }
Функция возведения в степень принимает два числа через регистры %rdi и %rsi и возвращает число. Соотвествено в файле программы на языке С определяем протип этой функции int exponent(int, int)
С помощью компилятора GCC скомплируем программу на языке С:
gcc app.c exponent.s -o app
Пример компиляции и выполнения программы:
root@Eugene:~/asm# gcc app.c exponent.s -o app root@Eugene:~/asm# ./app result = 16 root@Eugene:~/asm#
В примере выше код на языке С и код ассемблера сразу компилируются в один файл приложения. Но также возможно раздельная компиляция, при которой файл с кодом ассемблера предварительно компилируется в объектный файл:
root@Eugene:~/asm# as exponent.s -o exponent.o
Затем компилятору GCC передаем скомпилированный объектный файл:
gcc exponent.o app.c -o app