Per essere più precisi, si tratta di convertire da un linguaggio di programmazione a un livello inferiore di un linguaggio di programmazione. Per esempio, oggi quando si scrive un'applicazione Android, generalmente si scrive in Java. Poi si chiama javac, compilatore java per compilarlo in Java bytecode, che è un linguaggio binario che la JVM (Java Virtual Machine) interpreta ed esegue. Ma Android non usa JVM e Java Bytecode. Usa il bytecode ottimizzato per Android, chiamato DEX. Quindi il sistema di compilazione di Android compila il tuo bytecode java in bytecode DEX e lo impacchetta in un apk (file applicazione, simile a java jar). Sui droidi moderni, con ART (android runtime), una volta installata l'applicazione, la compila in file OAT che sono binari che girano direttamente sulla CPU del telefono.
Sono tutti linguaggi di programmazione, Java, java bytecode, DEX e codice macchina. Ai vecchi tempi, i programmatori scrivevano codice macchina. Poi sono stati inventati i compilatori (alla fine degli anni '50, il primo vero linguaggio simbolico era fortran). C'è ancora gente che scherza con i microcontrollori, e li programma in binario azionando interruttori (ogni interruttore è un bit di istruzione), e vedendo i risultati sui LED che rappresentano ciascuno un bit. Ma questo è come un hipster che porta una macchina da scrivere al suo bar locale per scrivere poesie (mentre ha un iPhone in tasca)...