Emulatore x86 scritto in CSS: esperimento assurdo che però funziona davvero

x86CSS è un emulatore di CPU Intel x86 scritto interamente in CSS. Il progetto dimostra la completezza di Turing del linguaggio e simula registri, memoria e istruzioni nel browser senza JavaScript.

Un emulatore di CPU Intel x86 eseguito interamente all’interno del browser, senza JavaScript e basato unicamente su fogli di stile, può sembrare un paradosso. Il progetto x86CSS sviluppato da Lyra Rebane dimostra invece che il linguaggio CSS, nato per definire l’aspetto delle pagine Web, è in grado di simulare un computer funzionante.

La sperimentazione si inserisce in un percorso storico che parte dal 1996, anno in cui il World Wide Web Consortium introdusse i Cascading Style Sheets (CSS) per separare contenuto e layout delle pagine HTML. Nel corso di quasi 30 anni il linguaggio si è arricchito di selettori, pseudo-classi e meccanismi logici che ne hanno ampliato notevolmente le possibilità espressive, fino a consentire strutture computazionali non banali.

L’esperimento di Rebane (sorgente su GitHub) dimostra in modo concreto che il CSS è “Turing-completo“, cioè capace in teoria di eseguire qualsiasi tipo di calcolo, mostrando come sia possibile simulare operazioni logiche (come condizioni e decisioni) e meccanismi di memoria direttamente all’interno del motore di rendering del browser, che è il sistema incaricato di interpretare e visualizzare le pagine Web.

CPU x86 Intel emulata in CSS da browser Web

Dal linguaggio di stile alla computazione generale

CSS è progettato per definire colori, layout e tipografia, ma l’introduzione progressiva di selettori avanzati, come le pseudo-classi e gli operatori condizionali, ha trasformato il linguaggio in un sistema più potente di quanto inizialmente previsto.

La proprietà “Turing-completo“, citata in precedenza, indica la capacità di un linguaggio di esprimere qualsiasi algoritmo computabile, a condizione di avere tempo e memoria sufficienti.

x86CSS sfrutta questa caratteristica combinando selettori, stati e transizioni per rappresentare registri, memoria e istruzioni. In questo contesto, il DOM (Document Object Model, la struttura ad albero che rappresenta gli elementi di una pagina Web) non è impiegato come contenitore logico del programma, ma come base su cui il motore CSS applica trasformazioni successive, emulando le diverse fasi del ciclo di esecuzione di una CPU, ossia la sequenza ordinata di operazioni con cui un processore elabora le istruzioni.

Architettura dell’emulatore x86CSS

Il progetto replica una versione estremamente semplificata dell’architettura Intel x86, limitandosi a un sottoinsieme di istruzioni e registri.

Ogni componente della CPU è rappresentato da elementi HTML stilizzati tramite classi e attributi, mentre le regole CSS definiscono lo stato e l’evoluzione dei dati. Le istruzioni sono codificate come stati discreti del sistema e le transizioni tra stati avvengono grazie all’applicazione sequenziale di selettori condizionali.

La memoria è modellata come una sequenza di nodi DOM in cui ogni nodo rappresenta una cella. Le istruzioni sono eseguite modificando lo stato delle celle e dei registri attraverso regole CSS con priorità e specificità controllate. In assenza di JavaScript, la temporizzazione del ciclo di clock è gestita con animazioni CSS. In modalità completamente priva di script, l’animazione stessa funge da temporizzatore, dimostrando che l’intero processo può funzionare anche senza supporto JavaScript.

Prestazioni e limiti tecnici

Nonostante la correttezza funzionale, x86CSS evidenzia i limiti di un approccio non progettato per la computazione generale.

Il motore di rendering del browser non è ottimizzato per eseguire logica complessa a livello di CSS, e ogni aggiornamento dello stato richiede il ricalcolo delle regole e il ridisegno della pagina. Di conseguenza, le prestazioni risultano molto inferiori rispetto a un emulatore tradizionale scritto in linguaggi come C o JavaScript.

L’uso di selettori complessi e la gestione della specificità possono inoltre introdurre comportamenti imprevedibili su browser diversi, con differenze di compatibilità tra motori.

Come il CSS rappresenta l’esecuzione del programma e dove risiede il codice

Nell’implementazione di x86CSS la simulazione della CPU è costruita come una macchina a stati finiti in cui ogni fase del ciclo di istruzione (fetch, decode, execute) è modellata tramite selettori CSS che diventano veri o falsi in base alla configurazione del DOM.

Come accennato in precedenza, il “tempo” è scandito da un clock CSS ottenuto con animazioni @keyframes che alternano classi di stato su un elemento radice; ogni frame dell’animazione rappresenta un micro-step della pipeline.

I registri della CPU (AX, BX, CX, DX, SI, DI, SP, BP, IP e i segmenti) sono codificati come gruppi di elementi HTML, in cui ogni bit è rappresentato da un nodo o da una combinazione di classi.

Il programma eseguito dalla CPU non è caricato dinamicamente ma è incorporato nella pagina come sequenza di celle di memoria. Ogni byte del codice macchina è rappresentato da un gruppo di elementi DOM contigui, tipicamente identificati da attributi come data-addr o classi numerate, che fungono da indirizzo logico.

Nella struttura congegnata da Rebane, il “binario” del programma e la logica della CPU convivono nello stesso documento: il primo è codificato nel DOM, la seconda nei fogli di stile. Il motore di rendering del browser, applicando iterativamente le regole CSS a ogni ciclo di animazione, svolge il ruolo di unità di controllo e ALU virtuale, trasformando una tecnologia pensata per la presentazione di elementi visuali in un ambiente di esecuzione completo.

Applicazioni didattiche e implicazioni

Il valore principale del progetto risiede nella sua funzione dimostrativa. x86CSS aiuta a comprendere in modo tangibile come un linguaggio non progettato per la programmazione possa comunque eseguire calcoli arbitrari.

Dal punto di vista della sicurezza, l’esperimento mostra che il CSS va considerato come un sistema con vere capacità di calcolo, che potrebbe quindi essere sfruttato in contesti di abuso o per pratiche di offuscamento, cioè tecniche che nascondono il comportamento del codice rendendolo difficile da analizzare.

Sul piano didattico, l’emulatore rappresenta uno strumento utile per comprendere come funzionano le CPU e le macchine virtuali, poiché rende osservabile direttamente nel browser il ciclo di esecuzione delle istruzioni.

Rebane sottolinea infatti come l’iniziativa abbia un valore principalmente creativo. L’implementazione di una CPU in CSS non mira a sostituire approcci tradizionali, ma a esplorare i limiti del linguaggio e a dimostrare quanto sia flessibile il modello di rendering del Web moderno.

Ti consigliamo anche

Link copiato negli appunti