Нередко код программы состоит не из одного файла, а из нескольких файлов. Разбиение программы на отдельные файлы позволяет упростить работу над логикой приложения. Функционал из одной файла, например, какие-то отдельные функции, можно легко переностить и повторно использовать в других программах. В связи с этим возникает вопрос организации программы. И тут у нас есть различные варианты. Рассмотрим на примере.
Пусть у нас есть следующий файл 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.
Пусть главный файл программы называется hello.s, и он использует выше определенную функцию:
.globl _start .text _start: movq $3, %rdi movq $2, %rsi call exponent movq %rax, %rdi movq $60, %rax syscall
Через регистры %rdi и %rsi передаем в функцию некоторые параметры и вызываем функцию. Результат функции из %rax перемещаем в %rdi.
Первый способ организации различных файлов в приложение представляет компиляция всех файлов с исходным кодом в один объектный файл. В этом случае при комплиции ассемблеру передаются все файлы с исходным кодом:
as hello.s exponent.s -o hello.o
Здесь из обоих файлов компилируется один объектный файл hello.o. Пример компиляции и выполнения программы:
root@Eugene:~/asm# as hello.s exponent.s -o hello.o root@Eugene:~/asm# ld hello.o -o hello root@Eugene:~/asm# ./hello root@Eugene:~/asm# echo $? 9 root@Eugene:~/asm#
Второй подход представляет раздельную компиляцию в файлов в разные объектные файлы, а при компоновке они объединяются в один исполныемый файл:
root@Eugene:~/asm# as exponent.s -o exponent.o root@Eugene:~/asm# as hello.s -o hello.o
В данном случае у нас получаются два объектных файла: exponent.o и hello.o. Затем компонуем их в один исполняемый файл программы:
root@Eugene:~/asm# ld hello.o exponent.o -o hello
В данном случае опять же создается один исполняемый файл "hello".