Da assembly a c++

rob25111

Nuovo Utente
38
0
Mettiamo che voglia creare un linguaggio di programmazione partendo dal codice assembly del processore.
Come si fa il passaggio ?
Come si costruisce la semantica e eventuali compilatori linker ?

compilatori e linker sono mediamente programmati utilizzando sempre un basso linguaggio di programmazione ? (Come assembly)

Qualche testo che potrebbe schiarirmi questo tipo di dubbi?Possibilmente qualche cosa di soft che faccia capire in panoramica generale per poi approfondire solo dopo architetture precise (!!?)!
 

theprogrammer.99

Nuovo Utente
96
34
Puoi usare linguaggi come il C/C++ ... (potenzialmente anche altri).

Ovviamente non è una cosa banale e le conoscenze da avere sono tante (non ti svegli la mattina e lo fai ...).
 
Ultima modifica da un moderatore:
  • Mi piace
Reazioni: rob25111

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Mettiamo che voglia creare un linguaggio di programmazione partendo dal codice assembly del processore.
Come si fa il passaggio ?
Come si costruisce la semantica e eventuali compilatori linker ?

compilatori e linker sono mediamente programmati utilizzando sempre un basso linguaggio di programmazione ? (Come assembly)

Qualche testo che potrebbe schiarirmi questo tipo di dubbi?Possibilmente qualche cosa di soft che faccia capire in panoramica generale per poi approfondire solo dopo architetture precise (!!?)!

Non ho capito che cosa intendi in realtà. I linguaggi di programmazione hanno come target l'architettura, e quindi producono del codice assembly in base al target.

Compilatori e linker sono scritti con linguaggio di "alto livello" (come dice theprogrammer99, C/C++ sono tra questi). Dovresti creare un parser, occuparti dell'analisi semantica etc etc. e solo in ultimo step produrre codice macchina eseguibile sul target.
Il libro più famoso è quello del draghetto, "Compilers: Principles, Techniques, and Tools", ma è un testo avanzato sull'argomento. Io conosco anche "Language implementation patterns".
Ma in generale puoi guardare ad esempio Lexical Analysis o sempre Wiki, per farti un'idea Compiler - Three stage compiler structure.

Dall'oggetto del topic invece si comprende la cosa contraria, ovvero che dall'assembly vuoi fare il procedimento inverso (un pò come fa Hex Rays).
Se il caso è questo dipende dal codice macchina che stai analizzando, e quindi dipende dall'architettura (o dalla famiglia). In questo caso dipende, se è un codice macchina ARM è relativamente più semplice in quanto la lunghezza delle istruzioni è sempre la medesima; con Intel (x86/x64) il discorso cambia molto, in quanto l'effettiva lunghezza la riconosci solo decodificando alcuni byte o addirittura bits.

Sto facendo una cosa analoga in un progetto che ormai rilascerò... a giorni (?). Non ho ancora introdotto la conversione in mnemonici (assembly) nè tantomeno in uno pseudo linguaggio di alto livello (e me ne guardo bene, per ora...), ma riconosco le lunghezze ed i campi che compongono le istruzioni.

Un estratto preso dal readme, giusto per fare un esempio concreto.

Data questa istruzione:
MOV DWORD PTR SS:[LOCAL.38],0

La decodifico come:
Codice:
RAW bytes (hex): C7 85 68 FF FF FF 00 00 00 00
Instr. length: 10
Print instruction fields:
        Located Prefixes 0:
        OP: 0xC7
        mod_reg_rm: 0x85
        disp (4): 0xFFFFFF68
        Iimm: 0x0

Data quest'altra, ad esempio:
MOVUPS DQWORD PTR SS:[ECX+EBP-94],XMM0

Viene decodificata come:
Codice:
RAW bytes (hex): 0F 11 84 0D 6C FF FF FF
Instr. length: 8
Print instruction fields:
        Located Prefixes 1:
                0xF
        OP: 0x11
        mod_reg_rm: 0x84
        SIB byte: 0xD
        disp (4): 0xFFFFFF6C

"raw bytes" sono i singoli bytes che compongono l'istruzione.
 
  • Mi piace
Reazioni: rob25111

theprogrammer.99

Nuovo Utente
96
34
Dato che non è possibile pubblicare il riferimento ad un forum cosiddetto "concorrente" ... ti posto la lista della bibliografia

- Abelson, Sussman, "Structure and Interpretation of Computer Programs, 2nd ed.", MIT Press
- Aho, Sethi, Ullman, "Compilers - Principles, techniques, and tools", Addison-Wesley Longman
- Kaplan, "Constructing language processors for little languages", John Wiley & Sons
- Mak, "Writing compilers and interpreters", John Wiley & Sons
- Gries, "Principi di progettazione dei compilatori", Franco Angeli Editore
- Morgan, "Building an optimizing compiler", DP Digital Press
- Kennedy & Allen, "Optimizing Compilers for Modern Architectures", Morgan Kaufmann
- Winskel, "La semantica formale dei linguaggi di programmazione", UTET
- Bruno, "Linguaggi formali e compilatori", UTET
- Srikant & Shankar, "The Compiler Design Handbook", CRC Press
- Kaspersky, "Code Optimization", A-List Publishing
 
  • Mi piace
  • Adoro
Reazioni: Mursey e rob25111
U

Utente cancellato 371741

Ospite
Se ci fosse una cpu, venduta nel mondo senza un compilatore, allora dovresti scrive su carta un programma in assembly, tradurlo in codici operativi, e scrivere il binario risultate sul supporto di boot, solo al fine di avere un primo programma d'avvio.

Ovviamente per ogni nuova cpu nel mercato non si fa questo. I compilatori hanno gran parte della loro logica riutilizzabile/compatibile, si cambia magari solo la parte che traduce in codici operativi. Vedi "cross-compilazione", da un pc x86_64 compili per un motorola Coldfire, o arm, o indifferente, ci sono toolchain per ogni architettura, fatte appunto con una logica modulare.

Oggi appunto su linux hai gcc ringraziando Stallman che ha creato gcc partendo dai sorgenti di un altro compilatore (Pastel) :)
http://www.softpanorama.org/People/Stallman/history_of_gcc_development.shtml

Per cui, per scrivere il "tuo" compilatore, che sarebbe cosa relativamente semplice per un micro PIC 8 bit, o uno z80, ma non per un x86_64, lo puoi fare utilizzando gcc esistente.

Piu semplice di tutto, come prima esperienza, ti consiglio di scriverti un interprete, in C o come vuoi, purche il generato sia binario eseguibile. Interprete che genera pseudo opcode risultanti dal tuo linguaggio "pipposcript". Piu complesso invece e' compilare per arrivare a veri e propri codici operativi, perche ci sono tante e tante cose da sapere, non solo come tradurre in codici operativi, ma mooolto di piu.

Buona fortuna.
 
Ultima modifica da un moderatore:
U

Utente 16812

Ospite
Mettiamo che voglia creare un linguaggio di programmazione partendo dal codice assembly del processore.
Come si fa il passaggio ?
Come si costruisce la semantica e eventuali compilatori linker ?

compilatori e linker sono mediamente programmati utilizzando sempre un basso linguaggio di programmazione ? (Come assembly)

Qualche testo che potrebbe schiarirmi questo tipo di dubbi?Possibilmente qualche cosa di soft che faccia capire in panoramica generale per poi approfondire solo dopo architetture precise (!!?)!

Salve @rob25111,
se intendi passare da un codice Assembly già stilato (non vedo il senso di programmare in Assembly per poi "tradurlo" in un codice ad alto livello se non per puro esercizio) ad un codice "equivalente" ad alto livello (perché è quello ciò che otterrai, un Assembly "simile" al C o al Pascal e non un "puro" codice C/Pascal), compi un'operazione impropriamente detta di "reverse engineering", vale a dire che hai bisogno di un "decompiler" (decompilatore), un compilatore che funziona "a rovescio", che nel migliore dei casi non funzionerà (non puoi "ripristinare" un sorgente originale decompilando) ma che nessuno vieta di implementare (di sicuro non è una soluzione) ?
Tralasciando gli aspetti legali (il software è protetto dal copyright degli autori) su cui non intendo discutere per ora (ripeto, se il codice ASM lo stili tu non ci sono problemi, è tutto tuo, ma non ne vedo il senso), esistono parecchi decompilatori di cui uno è Snowman: https://derevenets.com/ ?
Come primo passo, devi conoscere bene sia il codice macchina/Assembly (riferito all'architettura hardware su cui si sta lavorando: ARM, PIC, IA-32, IA-64, ecc.) che il linguaggio "high level" nel quale vuoi decompilare, poi, in linea di massima, è possibile separare "blocchi" di codice ASM per catalogarli secondo le varie funzioni (le assegnazioni, le condizioni, le diramazioni, le "chiamate" alle funzioni, ecc.) del linguaggio C (o Pascal).
Se non sono richieste ottimizzazioni, si può fare una "traduzione" linea per linea del codice (nella maggior parte dei casi si tratta di memorizzare dei valori nei registri di sistema) e poi eliminare le istruzioni ridondanti ma la cosa è tutt'altro che semplice (molte cose ho tralasciato, ho cercato di "banalizzare" al massimo il concetto) ?
Un altro decompilatore è RetDec (credo che la decompilazione sia fatta sul loro server, non in locale): https://retdec.com/
A presto ?

P.S. https://en.wikibooks.org/wiki/X86_Disassembly/Disassemblers_and_Decompilers ?
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili