Вызов функции на языке Си из модуля на языке ассемблера

Пример с главным модулем на Ассемблере.

Модуль на Си (func.c):

#include <stdio.h>

void func() {
    printf("Hello!\n");
}

Главный модуль на Ассемблере (main.s):

.text

# Функция main
.globl  main
.type   main, @function        
main:
        # Пролог функции
        pushl   %ebp
        movl    %esp, %ebp

        # Вызов функции из модуля на Си
        call    func

        # Вернуть 0 из main
        movl    $0, %eax

        # Эпилог
        movl %ebp, %esp
        popl %ebp
        ret

Трансляция модуля на Си в объектный файл func.o (ключ -с отменяет запуск редактора связей ld):

gcc -m32 -c func.c

Ассемблирование модуля в объектный файл main.o:

as --32 -o main.o main.s

Редактирование связей, получение исполняемого файла main:

gcc -m32 -o main main.o func.o

В данном случае использование редактора связей ld нецелесообразно , т. к. требуется подключение дополнительных объектных модулей среды выполнения Си, в частности объектных файлов crt0.o или crt1.o, содержащих символьное имя точки входа - метку _start и обеспечивающих вызов функции main (метку _start мы сами не определяем). Для этого подключения нужно задавать ld аргументы, определяющие местонахождение модулей среды выполнения Си. Компилятор gcc сам будет формировать вызов ld с необходимыми аргументами. Реально используемые при таком вызове gcc аргументы ld (включая пути к дополнительным объектным файлам) можно увидеть, если добавить к команде gcc выше ключ -v.

При запуске ./main будет выведено сообщение Hello!, что обеспечивается вызовом printf в func.

Автор: М. А. Крышень

Created: 2020-01-27 Пн 07:49

Validate