it-swarm-pt.tech

Executando as etapas do gcc manualmente, compilando, montando, vinculando

Se você tem um programa C simples, como

int main(void) {return 0;}

Pode ser compilado com gcc -o test test.c.

Pelo que entendi, o gcc realiza compilação, montagem e vinculação. Os dois últimos passos são alcançados executando as e ld.

Eu posso gerar o código do Assembly usando gcc -S test.c.

O que você digitaria em um terminal para converter o código do Assembly em um executável?

(a razão para fazer isso é aprender montagem)

33
checkers

Estes são os diferentes estágios usando o gcc

gcc -E  --> Preprocessor, but don't compile
gcc -S  --> Compile but don't assemble
gcc -c  --> Preprocess, compile, and assemble, but don't link
gcc with no switch will link your object files and generate the executable
57
quicoju

gcc test.s -o test irá compilar o test de test.s para voce.

NASM também pode valer o seu tempo - pode ser mais fácil/mais amigável do que gcc para compilar o Assembly.

3
sarnold

Depois que você faz gcc -S -o test.s test.c, tipo gcc -o test test.s.

1
Kerrek SB
// main.c
#include <stdio.h>

int main(void)
{
        printf("Hello World !\n");
        return 0;
}

Para pré-processamento, compilação, montagem e, finalmente, vinculação do programa hello world simples mencionado acima, siga as etapas abaixo:

Etapa 1/4) Pré-processe main.c para gerar main.i:

$: gcc -E main.c -o main.i

Etapa 2/4) Compile main.i para gerar main.s:

$: gcc -S main.i -o main.s

Passo 3/4) Monte main.s para gerar main.o:

$: as main.s -o main.o

NOTA: Você pode combinar as etapas 1, 2 e 3 acima mencionadas, usando o sinalizador -c (C pequeno) do gcc:

$: gcc -c main.s -o main.o

Etapa 4/4) Vincule o main.o a outros arquivos de objetos necessários, a saber, crti.o e crtn.o (eles definem prólogos e epílogos de funções, respectivamente), crt1.o (contém o símbolo _start para iniciar a execução inicial do programa) , caminho libc.so ou sinalizador -lc para libc e, finalmente, defina o nome do vinculador dinâmico, para gerar um executável ELF vinculado dinamicamente:

No x86_64:

$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o -lc main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable

OU (se você quiser especificar o caminho para libc.so)

$: ld /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/x86_64-linux-gnu/crtn.o /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/libc.so main.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main_ELF_executable

No ARM de 32 bits:

$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o -lc main.o -dynamic-linker /lib/ld-linux.so.3 -o main_ELF_executable

OU (se você quiser especificar o caminho para libc.so)

$: ld /usr/lib/arm-linux-gnueabihf/crti.o /usr/lib/arm-linux-gnueabihf/crtn.o /usr/lib/arm-linux-gnueabihf/crt1.o /usr/lib/arm-linux-gnueabihf/libc.so main.o -dynamic-linker /lib/ld-linux.so.3 -o main_ELF_executable

Você pode então executar o executável ELF 'main_ELF_executable':

$: ./main_ELF_executable

Olá Mundo !

Fontes:

https://linux.die.net/man/1/gcc

https://linux.die.net/man/1/ld

https://dev.gentoo.org/~vapier/crt.txt

1
ZeZNiQ

Como você pode ou não saber, os quatro estágios da compilação são pré-processar (-E), compilar no Assembly (-S), montar no código do objeto (-c) e finalmente vincular. O mais difícil para mim foi descobrir como usar a saída do pré-processador. Veja como fazê-lo:

gcc -E hello.c | gcc -S -xc -o hello.s -
gcc -c hello.s -o hello.o
gcc hello.o -o hello
0
Brian H

Você pode ter gcc iniciar e parar o processo de compilação onde quiser. gcc test.s -o test terá que compilar test.s do Assembly para um executável.

0
Kevin