source

gcc 스텝 수동 실행, 컴파일, 조립, 링크

factcode 2022. 7. 21. 23:31
반응형

gcc 스텝 수동 실행, 컴파일, 조립, 링크

간단한 C프로그램이 있다면

int main(void) {return 0;}

컴파일 할 수 있습니다.gcc -o test test.c.

gcc는 컴파일, 조립, 링크를 하는 것으로 알고 있습니다.후자의 2단계는 실행함으로써 실현됩니다.as그리고.ld.

다음을 사용하여 어셈블리 코드를 생성할 수 있습니다.gcc -S test.c.

어셈블리 코드를 실행 파일로 변환하려면 단말기에 무엇을 입력하시겠습니까?

(그 이유는 조립을 배우기 위해서입니다.)

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
// main.c
#include <stdio.h>

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

앞서 말한 간단한 hello world 프로그램을 전처리, 컴파일, 조립 및 링크하려면 다음 절차를 따릅니다.

스텝 1/4) main.c를 전처리하여 main을 생성합니다.i:

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

메모: C 프리프로세서를 직접 호출할 수도 있습니다.

$: cpp main.c -o main.i

스텝 2/4) main.i를 컴파일하여 main을 생성합니다.s:

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

스텝 3/4) 메인(main)을 조립하여 메인(main)을 생성합니다.o:

$: as main.s -o main.o

메모: gcc의 -c(작은 C) 플래그를 사용하여 위의 순서 1, 2, 3을 조합할 수 있습니다.

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

단계 4/4)링크 main.o 다른 필요한 개체 파일로 즉, crti.o&crtn.o(그들은 &, epilogs 각각 기능 prologs을 정의하는),crt1.o(이 프로그램의 초기 실행 부츠 트래핑에_start 상징이 포함되어 있),libc.so경로나 libc에-lc 깃발 그리고 드디어 동적 연결자의 이름, 동적으로 linke으로 생성됩니다.d게하고에코 가능:

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

OR(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

32비트 ARM의 경우:

$: 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

OR(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-armhf.so.3 -o main_ELF_executable

그런 다음 ELF 실행 파일 'main_'을 실행할 수 있습니다.ELF_executable':

$: ./main_ELF_executable

헬로 월드!

출처:

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

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

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

gcc test.s -o test를 컴파일 합니다.test부터test.s널 위해서.

또한 NASM은 시간을 들일 가치가 있을 수 있습니다. NASM이 더 쉽고 친근한 솔루션일 수 있습니다.gcc컴파일 어셈블리에 사용합니다.

하고 나서gcc -S -o test.s test.c,유형gcc -o test test.s.

컴파일의 4단계는 전처리(-E), 컴파일(-S), 오브젝트코드(-c)로 조립, 마지막으로 링크하는 것입니다.가장 이해하기 어려웠던 것은 프리프로세서의 출력을 어떻게 사용하는가 하는 것이었습니다.방법은 다음과 같습니다.

gcc -E hello.c | gcc -S -xc -o hello.s -
gcc -c hello.s -o hello.o
gcc hello.o -o hello

당신은 가질 수 있다gcc원하는 장소에서 컴파일 프로세스를 시작 및 중지합니다. gcc test.s -o test will have it compile test.s from assembly into an executable.

what I did was first I run the preprocessor by clang++ test.cpp -E > test.i then compiled it with ... clang++ -S test.i it should create a assembly file test.s ... then make the machine insturction file by as test.s -o test.o now you need to link it which is kinda confusing for dumb peoples like me ... so we don't know the arguments for our last process which is linking ... to find out ... run clang++ -v test.s it should give you some big text of something ... find this line "-dynamic-linker" ... there's definately a -dynamic-linker in your output text ... now copy the text from -dynamic-linker to rest of the output ... just copy everything afterwards including "-dynamic-linker" ... now what i got is ...

-dynamic-linker /system/bin/linker -o a.out /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtbegin_dynamic.o -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0 -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../.. -L/data/data/com.termux/files/usr/lib -L/system/lib /data/data/com.termux/files/usr/tmp/test-169b42.o -lc++_shared -lgcc -ldl -lm -lc -lgcc -ldl /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtend_android.o

in this what you have to change is where your object file is ... in my case it is /data/data/com.termux/files/usr/tmp/test-169b42.o ... i need to change it to where my test.o file is ... /data/data/com.termux/files/home/CPP/Cpp_Log/hello_world/test.o ... this is where my test.o file is ... so the argument we have to pass is ...

-dynamic-linker /system/bin/linker -o a.out /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtbegin_dynamic.o -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0 -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../.. -L/data/data/com.termux/files/usr/lib -L/system/lib /data/data/com.termux/files/home/CPP/Cpp_Log/hello_world/main.o -lc++_shared -lgcc -ldl -lm -lc -lgcc -ldl /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtend_android.o

now to link ... use the ld ... so the command is ld args -o test or in our case ...

ld -dynamic-linker /system/bin/linker -o a.out /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtbegin_dynamic.o -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0 -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib -L/data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../.. -L/data/data/com.termux/files/usr/lib -L/system/lib /data/data/com.termux/files/home/CPP/Cpp_Log/hello_world/main.o -lc++_shared -lgcc -ldl -lm -lc -lgcc -ldl /data/data/com.termux/files/usr/lib/gcc/arm-linux-androideabi/11.1.0/../../../../lib/crtend_android.o -pie -o test ...

since andriod 5+ can only run pie elf executables ... i also added the "-pie" (position independent executable) before the -o test ...

now it should give you a executable file test ... just run it by ./test

it should work

ReferenceURL : https://stackoverflow.com/questions/8527743/running-gccs-steps-manually-compiling-assembling-linking

반응형