En informàtica, un emulador de codi és un programari que permet executar codi màquina o programes d'ordinador en una plataforma (arquitectura maquinari o sistema operatiu) diferent d'aquella per la qual van ser escrits originalment. A diferència d'un simulador, que només tracta de reproduir el comportament del programa, un emulador tracta de modelar de forma precisa el dispositiu que s'està emulant. Es pot emular la CPU, i fins i tot el codi d'entrada sortida a perifèrics o les crides al BIOS.
En sentit teòric, la tesi de Church-Turing implica que qualsevol ambient funcional pot ser emulat dins de qualsevol altre. A la pràctica, això pot resultar realment difícil, particularment quan el comportament exacte del sistema emulat no està documentat i ha de ser deduït mitjançant enginyeria inversa. Tampoc es parla en la tesi sobre les diferències en sincronització, si l'emulador no actua tan ràpidament com el maquinari original, el programari d'emulació anirà més lent que si fos el maquinari original.
Un dels primers emuladors (dins del món dels ordinadors personals) va ser el "Sweet 16" (1968) de Wozniak que emulava una màquina de 16 bits dins d'un Apple II i un dels emuladors més populars va ser el "SoftPC", que emulava un Ordinador personal dins d'un MAC. Més tard el MAC ha canviat dues vegades de CPU (de 68k a PowerPC per acabar a Intel) i el canvi ha estat quasi imperceptible als usuaris, ja que han implementat un emulador de codi de la CPU anterior.
Són també molt populars els emuladors de videojocs de màquines recreatives o consoles en un ordinador personal, o en altres videoconsoles. L'emulació de videojocs de sistemes antics (programari descatalogat) en les modernes computadores personals i videoconsoles d'avui dia resulta generalment més còmoda i pràctica que en els dispositius originals. No obstant això, pot ser requerit als creadors d'emuladors una llicència de programari per escriure programes originals que dupliquen la funcionalitat de la Memòria ROM i BIOS del maquinari original, el que comunament es denomina high-level emulation o emulació d'alt nivell.
La majoria dels emuladors només emulen una determinada configuració arquitectura de maquinari - si el sistema d'explotació (o sistema operatiu) també es requereix per a emular cert programa de llavors ha de ser emulat també. Tant el sistema d'explotació com el programa han de ser interpretats per l'emulador, com si estigués executant en l'equip original. A part de la interpretació del llenguatge de la màquina emulada, cal emular la resta de l'equip, com els dispositius d'entrada i sortida, de forma virtual: si escriure en una regió específica de la memòria ha d'influir en el contingut en pantalla, per exemple, això també ha de ser emulat.
En comptes d'una emulació completa de l'equip, una compatibilitat superficial pot ser suficient. Això tradueix les crides al sistema emulat a crides al sistema amfitrió.
Els desenvolupadors de programes per a màquines amb sistemes computats i consoles de videojoc comunament utilitzen emuladors especialment exactes anomenats simulador és abans d'executar en l'equip real. Això permet que el programa pugui ser produït i provat abans que la versió final de l'equip per al qual s'està desenvolupant sigui produïda en grans quantitats, d'aquesta manera pot ser provat sense haver de copiar el programa a l'equip, de manera que puguin ser eliminats errors en un nivell baix sense tenir els efectes col·laterals d'un depurador.
Típicament, un emulador es divideix en mòduls que corresponen de manera precisa als subsistemes de l'equip emulat. El més comú, és que un emulador aquest compost pels següents mòduls:
El més comú és que els Buses no siguin emulats, per raons de simplicitat i rendiment, i perquè els perifèric virtuals es comuniquin directament amb la UCP i els subsistemes de memòria.
El Simulador de CPU (Unitat Central de Procés) és sovint la part més complexa d'un emulador. Molts emuladors són escrits utilitzant simuladors de CPU "pre-empaquetat", per així poder realitzar una emulació fidel i eficient d'una màquina específica.
El simulador de CPU més simple seria un Intèrpret informàtic, que segueix el flux d'execució del codi de programació emulat i, per cada instrucció de codi de la màquina emulada, s'executa en el processador en què es carrega, instruccions semànticament equivalents a les originals.
Això és possible assignant una variable a cada registre i flag de la CPU simulada. La lògica de la CPU simulada pot ser més o menys traduïda directament a algorismes de programari, creant una re-implementació del programari que bàsicament reflecteix la implementació original de l'maquinari.
L'exemple següent il·lustra la manera com la simulació de CPU per un intèrpret. En aquest cas, les interrupcions es revisen després de l'execució de cada instrucció, encara que aquest comportament no és usual en els emuladors en la realitat, per raons de rendiment.
void Execute (void){
if (Interrupt ! = INT_NONE){
SuperUser = TRUE;
WriteMemory (++StackPointer, ProgramCounter);
ProgramCounter = InterruptPointer;
}
switch (ReadMemory (ProgramCounter++)){
//Handling of every valid instruction
default:
Interrupt = INT_ILLEGAL;
}
}
Els intèrprets són molt populars en el cas dels simuladors de CPU, ja que són més senzills d'implementar que altres solucions alternatives de millor rendiment, i la seva velocitat és més que adequada per a emular computadares de fa més d'una dècada a màquines modernes.
Tot i així, la penalització de velocitat inherent en la interpretació pot ser un problema en emular computadors la velocitat de processador està en el mateix ordre de magnitud que la màquina hoste. Fins no fa tants anys, l'emulació en aquestes situacions era considerada impracticable.
El que permet el trencament d'aquesta restricció són les tècniques avançades de recompilació dinàmica . Una translació simple a priori del codi del programa emulat al codi que corre en l'arquitectura original és normalment impossible per diverses raons:
Diverses formes de recompilació dinàmica, incloent la popular tècnica de compilació en temps d'execució (compilació JIT), tracta de vorejar aquests temes esperant fins que el procés de control de flux es mogui fins on aquesta la part on està localitzat el codi sense traduir, i és només llavors{"en temps d'execució") quan els blocs traduïts del codi al codi amfitrió poden ser executats.
El codi traduït es manté en l' codi cache , i el codi original no es perd ni és afectat; d'aquesta manera, fins i tot els segments de data poden ser traslladats pel recompilar, resultant només en una despesa de temps de trasllat.
La majoria dels emuladors, com dit anteriorment, no emulen el sistema principal bus; cada dispositiu d'entrada i sortida és tractat sovint com un cas especial, i no hi ha una interfície constant per als perifèrics virtuals.
Això pot resultar en un avantatge en el funcionament, proveint que cada mòdul d'entrada i sortida pugui ser adaptat a les característiques del dispositiu emulat; dissenys basats en un estàndard, entrades i sortides unificades per mitjà d'API poden però proveir models més simples, ia més tenen l'avantatge addicional de permetre de forma "automàtica" la utilització de serveis plugin s per a proveir dispositius virtuals de tercers en l'emulador.
Les entrades i sortides unificades per mitjà d'API no necessàriament reflecteixen l'estructura del bus del maquinari real: el disseny del bus està limitat per diversos paràmetres elèctrics i la necessitat del maneig de programació paral·lela que l'majoria de les vegades pot ser ignorada en la implementació del programari.
Encara els emuladors que tracten cada dispositiu com un cas especial tenen una infraestructura bàsica en comú per a això:
Els emuladors arrenquen imatges ROM (o simplement ROM), és a dir el contingut dels cartutxos, disquets o cintes que es feien servir amb els sistemes antics. Físicament en les PC les ROM són fitxers binaris que es poden carregar a la memòria. És a dir, l'emulador és un programa que fa les funcions de la consola, per exemple la Game Boy Advance o una PDA, i la ROM és un arxiu que fa de cartutx, CD-ROM, o cinta, per exemple "Mario Bros".
També hi ha una vessant en l'emulació que pot ser realitzada per virtualització, consistent a crear una capa d'abstracció, però executant instruccions en una màquina del mateix tipus, i dona com a resultats obtenir un ordinador dins d'una altra. Exemples d'això són:
Els emuladors de consoles són programes d'ordinadors dissenyats per a emular una o més consoles i així poder jugar un joc que pertany a aquesta (s). Els emuladors múltiples solen emular consoles amb característiques similars (per exemple MEKae emula totes les consoles de Sega de 8 bits i la Colecovision)