Tag: c

  • C Language Compiled Code

    C Language Compiled Code

    C Language Compiled Code refers to the machine-readable version of a program written in the C programming language. When you write C source code in human-readable files (.c and .h), it cannot be executed directly by a computer. A compiler translates this source code through several stages including preprocessing, compilation to assembly, assembling into object code, and linking with libraries to produce a standalone executable file. The resulting compiled code consists of binary instructions that the CPU can interpret and run directly. This makes compiled code fundamentally different from the original C source code, which is intended for humans to read, write, and modify.

    Source Code

    The code is in C language (.c and .h files)

    cat # Command used to display the contents of a file
    test.c # The C source file whose contents will be printed to the terminal

    (host) cat test.c

    #include <stdio.h> // Includes the Standard Input/Output library so we can use functions like printf()

    int main(){ // The main function: program execution starts here
      printf(“Hello World!”); // Prints the text “Hello World!” to the standard output (usually the terminal)
      return 0; // Ends the program and returns 0 to the operating system indicating successful execution
    }

    #include <stdio.h>

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

    Pre-Processor

    This step includes the headers and expand the macros, the generated file have the .i, .ii extensions  

    gcc # GNU C Compiler
    -E # Tells gcc to run only the preprocessor (expands #include, #define, etc.)
    test.c # The C source file being processed
    | # Pipe operator; sends the output of the command on the left to the command on the right
    head # Displays only the first 10 lines of the output

    (host) gcc -E test.c | head

    # 0 "test.c"
    # 0 "<built-in>"
    # 0 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 0 "<command-line>" 2
    # 1 "test.c"
    # 1 "/usr/include/stdio.h" 1 3 4
    # 28 "/usr/include/stdio.h" 3 4

    Compiler

    The expanded code/preprocessed code gets converted into assembly code, the generated file have the .s, .asm extensions 

    gcc # GNU C Compiler
    -S # Tells gcc to compile the code into assembly language but not create an executable
    test.c # The C source file being compiled

    (host) gcc -S test.c

    cat # Command used to display the contents of a file
    test.s # The generated assembly language file from the compilation step

    (host) cat test.s

            .file   "test.c"
            .text
            .section        .rodata
    .LC0:
            .string "Hello World!"
            .text
            .globl  main
            .type   main, @function
    main:
    .LFB0:
            .cfi_startproc
            pushq   %rbp
            .cfi_def_cfa_offset 16
            .cfi_offset 6, -16
            movq    %rsp, %rbp
            .cfi_def_cfa_register 6
            leaq    .LC0(%rip), %rax
            movq    %rax, %rdi
            movl    $0, %eax
            call    printf@PLT
            movl    $0, %eax
            popq    %rbp
            .cfi_def_cfa 7, 8
            ret
            .cfi_endproc
    .LFE0:
            .size   main, .-main
            .ident  "GCC: (Debian 14.2.0-16) 14.2.0"
            .section        .note.GNU-stack,"",@progbits

    Assembler

    The assembly code gets converted into object code/machine code, the generated file have the .o, .obj extensions  

    gcc # GNU C Compiler
    -c # Compile the source code into an object file (machine code) without linking
    test.c # The C source file being compiled

    (host) gcc -c test.c

    cat # Outputs the contents of the file
    test.o # Object file containing compiled machine code
    | # Pipe operator; sends output of the left command to the right command
    xxd # Converts binary data into a hexadecimal (hex) and ASCII representation
    | # Pipe operator again
    head # Displays only the first 10 lines of the hex output

    (host) cat test.o | xxd | head

    00000000: cffa edfe 0c00 0001 0000 0000 0100 0000  ................
    00000010: 0400 0000 b801 0000 0020 0000 0000 0000  ......... ......
    00000020: 1900 0000 3801 0000 0000 0000 0000 0000  ....8...........
    00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00000040: 6800 0000 0000 0000 d801 0000 0000 0000  h...............
    00000050: 6800 0000 0000 0000 0700 0000 0700 0000  h...............
    00000060: 0300 0000 0000 0000 5f5f 7465 7874 0000  ........__text..
    00000070: 0000 0000 0000 0000 5f5f 5445 5854 0000  ........__TEXT..
    00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
    00000090: 3400 0000 0000 0000 d801 0000 0200 0000  4...............
    ...
    ...
    ...

    Linker

    The last step is combining the object code/machine code and .lib/.a static library files, the generated file have the .exe, elf, bin extensions

    gcc # GNU C Compiler used to compile and link the program
    test.c # The C source file being compiled
    -o # Option to specify the name of the output file
    test.bin # Name of the final executable binary file that will be created

    (host) gcc test.c -o test.bin

    cat # Outputs the contents of the file
    test.bin # The compiled executable binary file
    | # Pipe operator; sends output of one command to another
    xxd # Converts binary data into hexadecimal and ASCII representation
    | # Pipe operator again
    head # Displays the first 10 lines of the output

    (host) cat test.bin | xxd | head

    00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
    00000010: 0300 3e00 0100 0000 5010 0000 0000 0000  ..>.....P.......
    00000020: 4000 0000 0000 0000 9036 0000 0000 0000  @........6......
    00000030: 0000 0000 4000 3800 0e00 4000 1f00 1e00  ....@.8...@.....
    00000040: 0600 0000 0400 0000 4000 0000 0000 0000  ........@.......
    00000050: 4000 0000 0000 0000 4000 0000 0000 0000  @.......@.......
    00000060: 1003 0000 0000 0000 1003 0000 0000 0000  ................
    00000070: 0800 0000 0000 0000 0300 0000 0400 0000  ................
    00000080: 9403 0000 0000 0000 9403 0000 0000 0000  ................
    00000090: 9403 0000 0000 0000 1c00 0000 0000 0000  ...............
    ...
    ...