Understanding C runtime environment (ARM) - where to start

前端 未结 5 1885
青春惊慌失措
青春惊慌失措 2021-02-06 01:54

I\'am embedded developer working with ARM Cortex-M devices mainly. Recently I\'ve switched to Linux and decided to learn more about the build/assemble/link process, how to write

5条回答
  •  执念已碎
    2021-02-06 02:26

    That's quite a big question, but I'll try to answer it and give you an overview of all steps that are required to turn a "hello world" into an actual arm executable. I'll focus on the commands to show every step rather than explaining every single detail.

    #include 
    
    int main()
    {
            printf("Hello world!\r\n");
            return 0;
    }
    

    I will use gcc on ubuntu 17.04 for this example. arm-none-eabi-gcc (15:5.4.1+svn241155-1) 5.4.1 20160919

    1. Preprocessing

    It basically takes care of every line starting with a #. To show the output of the preprocessor use arm-none-eabi-gcc -E or arm-none-eabi-cpp.

    arm-none-eabi-gcc -E main.c

    The output is very long because of all the things that happen when you #include and it still contains "unreadable" lines like # 585 "/usr/include/newlib/stdio.h" 3

    If you use the arguments -E -P -C the output becomes a lot clearer.

    arm-none-eabi-gcc -E -P -C main.c -o main-preprocessed.c

    Now you can see that #include just copied all the contents from stdio.h to your code.

    2. Compiling

    This step translates the preprocessed file to assembly instructions, which are still human readable. To get machine code use -S.

    arm-none-eabi-gcc -S main.c

    You should end up with a file called main.s that contains your assembly instructions.

    3. Assembling

    Now it starts to get a lot less human readable. Pass -c to gcc to see the output. This step is also the reason why inline assembly is possible.

    arm-none-eabi-gcc -c main.c

    You should end up with a main.o file which can be displayed with hexdump or xxd. I would recommend xxd because it shows you the ascii representation next to the raw hexadecimal numbers.

    xxd main.o

    4. Linking

    The final stage, after that your program is ready to be executed by the target system. The linker adds the "missing" code. For example there was no sign of the printf() function or anything from stdio.h.

    arm-none-eabi-gcc main.c --specs=nosys.specs -o main

    For the --specs=nosys.specs see here: https://stackoverflow.com/a/23922211/2394967

    This is just a rough overview, but you should be able to find a lot more information on every step here on stackoverflow. (example for the linker: What do linkers do? )

提交回复
热议问题