De reis van voor mensen leesbare instructies (zoals een C++-programma of een Python-script) naar binaire code die door een computer wordt uitgevoerd, bestaat uit meerdere stappen:
1. Broncode: Dit is de code die door een programmeur is geschreven in een programmeertaal op hoog niveau (zoals Python, Java, C++, enz.). Deze code is op tekst gebaseerd en maakt gebruik van voor mensen leesbare opdrachten en syntaxis.
2. Compilatie (of interpretatie): Dit is de cruciale stap waarbij de voor mensen leesbare code wordt vertaald in voor machines begrijpelijke code. Er zijn twee belangrijke benaderingen:
* Compilatie: Een compiler neemt de volledige broncode en vertaalt deze in één keer naar een complete set machine-instructies (objectcode). Deze objectcode wordt vervolgens vaak gekoppeld aan andere objectcode (zoals bibliotheken) om een uitvoerbaar bestand te creëren. Dit uitvoerbare bestand is in wezen een reeks binaire instructies. Talen als C++ en Java (vóór de JVM-stap) maken doorgaans gebruik van compilers.
* Interpretatie: Een tolk vertaalt en voert de broncode regel voor regel uit, zonder een apart uitvoerbaar bestand te creëren. Talen als Python en JavaScript gebruiken tolken. Hoewel ze niet direct binaire code produceren op dezelfde manier als een compiler, is de tolk zelf een programma dat in een gecompileerde taal is geschreven en uiteindelijk afhankelijk is van binaire instructies om te worden uitgevoerd. De geïnterpreteerde code wordt nog steeds uitgevoerd met behulp van binaire instructies, maar de vertaling gebeurt dynamisch, regel voor regel.
3. Assemblagetaal (soms): In sommige gevallen kan een compiler als tussenstap assembleertaal genereren. Assembleertaal is een programmeertaal op laag niveau die geheugensteuntjes (korte afkortingen) gebruikt om machine-instructies weer te geven. Een assembler vertaalt deze assemblagecode vervolgens naar machinecode (binair). Deze stap is vaak verborgen voor de programmeur.
4. Machinecode (binair): Dit is de laatste fase. Machinecode bestaat uit een reeks binaire cijfers (0s en 1s). Elke instructie wordt weergegeven door een uniek binair patroon dat de CPU direct kan begrijpen en uitvoeren. Deze binaire code vertegenwoordigt zaken als:
* Opcodes: Instructies die de CPU vertellen welke bewerking moet worden uitgevoerd (bijvoorbeeld optellen, aftrekken, geheugentoegang).
* Operanden: Gegevens- of geheugenadressen waarop de instructie werkt.
Voorbeeld (vereenvoudigd):
Laten we zeggen dat een eenvoudige instructie in een taal op hoog niveau `x =y + 5;` is. Na compilatie zou dit zich (zeer grofweg en afhankelijk van de architectuur) kunnen vertalen in iets als dit in binaire vorm (dit is een zeer vereenvoudigde illustratie en echte binaire instructies zijn veel complexer):
* Laad de waarde van `y` in een register: `0001 1010 0000 0010` (hypothetische binaire instructie)
* Voeg 5 toe aan het register: `0010 0101 0000 0101` (hypothetische binaire instructie)
* Sla het resultaat op in de geheugenlocatie `x`: `0011 1100 0000 0011` (hypothetische binaire instructie)
De specifieke binaire representatie hangt volledig af van de CPU-architectuur (x86, ARM, etc.) en de gebruikte compiler/interpreter. Het proces is complex, maar het kernidee is dat instructies op hoog niveau worden opgesplitst in een reeks eenvoudige binaire instructies die de CPU direct kan begrijpen en uitvoeren. |