Discussione [Codegolf] Emulare (parzialmente) la CPU Intel 8086

DispatchCode

Moderatore
24 Maggio 2016
505
15
380
264
Voglio proporre una "challenge" un pò insolita ma secondo me interessante/stimolante, trovata alcuni anni fa su codegolf: Emulate an Intel 8086 CPU.



Si tratta di emulare parzialmente una CPU Intel 8086. Riporto le specifiche originali alle quali attenersi:
  • Only the following opcodes need to be implemented:
    • mov, push, pop, xchg
    • add, adc, sub, sbb, cmp, and, or, xor
    • inc, dec
    • call, ret, jmp
    • jb, jz, jbe, js, jnb, jnz, jnbe, jns
    • stc, clc
    • hlt, nop
  • As a result of this, you only need to calculate the carry, zero and sign flags
  • Don't implement segments. Assume cs = ds = ss = 0.
  • No prefixes
  • No kinds of interrupts or port IO
  • No string functions
  • No two-byte opcodes (0F..)
  • No floating point arithmetic
  • (obviously) no 32-bit things, sse, mmx, ... whatever has not yet been invented in 1979
  • You do not have to count cycles or do any timing
Start with ip = 0 and sp = 100h.

Input: Your emulator should take a binary program in any kind of format you like as input (read from file, predefined array, ...) and load it into memory at address 0.
Output: The video RAM starts at address 8000h, every byte is one (ASCII-)character. Emulate a 80x25 screen to console. Treat zero bytes like spaces.

Example:
Codice:
08000   2E 2E 2E 2E 2E 2E 2E 2E 2E 00 00 00 00 00 00 00   ................
08010   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
08020   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
08030   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
08040   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
08050   48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00 00 00   Hello,.world!...

Allego lo zip contenente il programma di test che dovrà essere eseguito, e il relativo codice (sono i medesimi del post originale). Il programma di test è un ".com".

Eseguendo quel programma di test dovrete ottenere il seguente output:
Codice:
.........                                                                       
Hello, world!                                                                   
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 


################################################################################
##                                                                            ##
##  0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987                          ##
##                                                                            ##
##  0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400     ##
##                                                                            ##
##  2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97    ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
##                                                                            ##
################################################################################

Ovviamente potete utilizzare il linguaggio che preferite: dal JS al C passando per Java, Go, PHP e altri.
Se volete implementare più opcodes o funzionalità aggiuntive, ben venga.

Alcune risorse utili sono:
Secondo me tra le risorse migliori c'è quella allegata: da pagina 26 è presente la decodifica delle istruzioni; l'ultima pagina mostra le modalità di indirizzamento oltre ai registri e le relative codifiche.
Potete trovare molte altre informazioni anche online.


Se avete soluzioni parziali, domande, difficoltà o altro... scrivete comunque, senza timori. ;)
Buon divertimento a chi sceglierà di partecipare!
 

Allegati

  • codegolf_8086.zip
    1.6 KB · Visualizzazioni: 11
  • 231455.pdf
    380.3 KB · Visualizzazioni: 12
In alcune di queste serate l'ho scritto in Rust approfittando dell'occasione per iniziare a guardarmi un nuovo linguaggio. L'avevo già scritto in C tempo addietro, ed ho avuto passate esperienze con l'emulazione, quindi sapevo cosa aspettarmi. A parte qualche momento traumatico dovuto a qualche bug, sono giunto al risultato :)

Lascio lo screenshot sotto spoiler:
rust_nate.png

Il codice completo lo si può trovare sul mio Github: https://github.com/DispatchCode/nate-rust
Chiaramente essendo il primo codice Rust che scrivo (e conoscendo ben poco il linguaggio) ci saranno tante cose migliorabili.

Faccio una brevissima panoramica:
mca8086 (Machine Code Analyzer, è la forma molto più snella di ciò che uso in un mio progetto, e prima o poi pubblicherò proprio questa parte) si occupa di disassemblare le istruzioni. In sostanza ne riconosce i diversi campi che la compongono; per la decodifica mi appoggio a degli array che utilizzo come lookup-table: ci sono array per i valori immediati (che consentono di sapere se un OP ha un valore immediato) e per il byte chiamato ModRm. Una delle informazioni più importanti che ne consegue è poi la lunghezza dell'istruzione.

cpu_exec utilizzo un array per memorizzare gli indirizzi delle funzioni che "emulano" le varie operazioni: accedendo alla posizione N dell'array verrà chiamata la funzione N:

Codice:
FUNCS[instr.op as usize](cpu, &instr);

cpu inizializza solamente le strutture con i valori di default specificati nel primo post.
 
  • Mi piace
Reazioni: CrashTest