⚙️ De C a 0 i 1 · El viatge del compilador

📘 Segueix el camí del teu codi hello.c pas a pas, des del text que entens fins al binari que executa l'ordinador.
// hello.c
#include <stdio.h>

int main() {
    printf("Hello World");
    return 0;
}
🧑‍🍳

1. Preprocessador #include & #define

Què fa? Prepara els ingredients. Agafa totes les línies que comencen per # i les substitueix.

🔹 Agafa el fitxer stdio.h i enganxa TOT el seu contingut al teu codi (així el compilador sap que existeix printf). També substitueix les macros (si n'hi ha).

📄 Sortida: Un codi C més llarg, però encara 100% text llegible.
🔍

2. Compilador (C → Assembler) Traducció

Què fa? Aquí es fa la traducció principal. Comprova la sintaxi (punt i coma, claus) i converteix el C en un llenguatge intermedi anomenat Assembler.

🔹 L'Assembler encara és text (instruccions com MOV, ADD, CALL), però és molt més bàsic i proper al metall.

🔄 Exemple: printf("Hello World") es tradueix a call _printf (crida a la funció).
🏭

3. Assembrador (Assembler → Objecte) Primers 0 i 1

Què fa? Converteix el text de l'Assembler en codi màquina (0 i 1). Genera un fitxer .o o .obj.

🔹 Atenció! Aquest fitxer ja conté 0 i 1, però està incomplet. La funció printf encara no hi és, només hi ha una "referència pendent". Si l'obrissis amb un bloc de notes, veuries caràcters estranys.

📦 Fitxer generat: hello.o (conte 0 i 1, però li falta la biblioteca).
🔗

4. Enllaçador (Linker) El mestre d'obres

Què fa? Agafa el teu hello.o (ple de 0 i 1) i el fusiona amb les biblioteques de C (com libc).

🔹 Busca la referència a printf dins de la biblioteca, agafa el seu codi binari (0 i 1) i l'enganxa al teu fitxer. Després, resol totes les adreces de memòria perquè les instruccions sàpiguen on saltar.

✅ Sortida final: L'executable a.out (Linux) o hello.exe (Windows). Ja és complet!
🚀

5. Execució i codi de retorn El 0 final

Què passa? El sistema operatiu carrega l'executable a la memòria RAM. El processador llegeix els 0 i 1, i executa les instruccions una per una.

🔹 Quan arriba a return 0;, el compilador ja ha traduït això a una instrucció que deixa el valor 0 en un registre intern del processador. Quan el programa acaba, el sistema operatiu mira aquest registre. Si veu un 0, sap que tot ha anat bé. Si veu un 1 (o altre número), sap que hi ha hagut un error.

💻 A la terminal: ./a.out → mostra "Hello World" i retorna 0 (èxit).

🧠 Resum en 3 frases: