Как связать сборку ELF32 и файлы C? - PullRequest
2 голосов
/ 10 апреля 2011

Я написал простую часть программного обеспечения для сборки (nasm) и простое приложение на C. Мой C-код вызывает функцию из кода Assembly, но я не знаю, как скомпилировать C-код без получения ошибки «неопределенная ссылка» из «extern int Sum ();» линия.

код C:

#include <stdio.h>

extern int Sum();

main()
{
  int a1, a2, x;

  x = Sum(a1, a2);
  printf("value of x is: %d\n", x);
}

Код сборки:

global _Sum

_Sum:
    push ebp
    mov  ebp, esp

    mov  eax, [ebp+8]
    mov  ecx, [ebp+12]
    add  eax, ecx
    pop  ebp
    ret

Как мне скомпилировать эти два файла по отдельности и впоследствии связать их в один объединенный файл?

Ответы [ 6 ]

2 голосов
/ 10 апреля 2011

В ABI, используемом с ELF, имена C не искажены с начальными _.

2 голосов
/ 10 апреля 2011

Вам нужно собрать файл .asm, чтобы получить файл .o (объект), как вы и сказали.Затем вы должны скомпилировать (но не связывать) файл .c, чтобы получить другой файл .o, например:

gcc -o whatever.o -c whatever.c

Затем вы должны связать их вместе, например:

gcc whatever.o asm.o

Тогда компоновщик будет запущен со всем объектным кодом одновременно и должен иметь возможность разрешать ссылки, в которых он нуждается.

1 голос
/ 16 ноября 2012

Для тех, кто заходит сюда в поисках: ознакомьтесь с кодом и закажите здесь http://www.drpaulcarter.com/pcasm/index.php : Загрузите примеры linux через здесь : Файл, на который вы хотите сослаться, - first.asm - (скомпилируйте его в соответствии с архитектурой: пример 32 бит ниже)

nasm -f elf -d ELF_TYPE asm_io.asm
nasm -f  elf32 first.asm 
gcc -o first first.o driver.c asm_io.o
1 голос
/ 20 июля 2011

Есть две возможности решить эту проблему: скомпилировать исходный код C как C (НЕ C ++), чтобы скомпилировать его как C, вы должны дать ему расширение .c

Второй способ: в коде C ++ (расширение .cpp) имена искажаются, когда вы компилируете код C ++, используйте шестнадцатеричный редактор для поиска в объектном файле и поиска Sum. В моем случае имя становится _Z3Sumii. Если вы измените имя в источнике ассемблера на это, вы обнаружите, что оно работает.

Также измените оператор extern в источнике C ++ на следующий, поскольку он принимает два параметра типа int, например, extern int Sum(int, int);

  global _Z3Sumii
_Z3Sumii:
  push ebp
  mov  ebp, esp
  mov  eax, [ebp+8]
  mov  ecx, [ebp+12]
  add  eax, ecx
  mov  esp, ebp
  pop  ebp
  ret

Для компиляции:

gcc -c file.cpp
nasm -f elf32 sum.asm -o sum.o
gcc file.o sum.o -o file
0 голосов
/ 20 июля 2011

В ваших обстоятельствах:

nasm -f elf -o sumasm.o sumasm.asm
gcc -o sum sumasm.o sum.c 

вам может понадобиться elf32

0 голосов
/ 10 апреля 2011

Наиболее естественным способом является использование GCC toolchain для получения кода на ассемблере вашей программы на C, затем ручная сборка обоих файлов на ассемблере и их связывание.

...