Организация программы

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

Нередко код программы состоит не из одного файла, а из нескольких файлов. Разбиение программы на отдельные файлы позволяет упростить работу над логикой приложения. Функционал из одной файла, например, какие-то отдельные функции, можно легко переностить и повторно использовать в других программах. В связи с этим возникает вопрос организации программы. И тут у нас есть различные варианты. Рассмотрим на примере.

Пусть у нас есть следующий файл 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".

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850