2010-11-10 21 views
5

Sto cercando di imparare l'intera catena realizzazione opere in modo da poter capire meglio cosa succede quando faccio costruire/link/compilare ecccomprendere la necessità di compilatori per diverse piattaforme

Un punto che sto avendo difficoltà con questo: Se il compilatore trasforma la sorgente in assembly nativo, perché lo stesso programma non può girare su diversi SO? L'assemblaggio non viene eseguito direttamente dalla CPU? Quindi lo stesso codice macchina dovrebbe essere eseguito su ogni sistema operativo, purché sia ​​la stessa architettura, no? Perchè no?

EDIT: maggior parte delle risposte finora sono di chiamare le API del sistema operativo. Questo ovviamente è un problema. La mia domanda riguarda il codice macchina diritto. Viene passato direttamente alla CPU o no? Se avessi scritto un programma in assembly, avrei ancora bisogno di compilare separatamente per ciascun sistema operativo? (side point: se ho usato C++ standard/cout, è dipendente dal sistema operativo, devo compilare per dirigere l'I/O di assemblaggio o la risposta dipende dal compilatore?)

risposta

8

Diversi sistemi operativi supportano diversi formati binari (es. ELF vs COFF), diversi linker dinamici (con file * .so, * .dll e * .dylib collegato in fase di esecuzione, dopo aver distribuito il file binario) e fornito diversi set di funzioni e librerie per l'utilizzo delle funzionalità fornite dal sistema operativo.

Diverse serie di funzioni possono essere indirizzate, ad esempio, dalla specifica UNIX singola/Std IEEE. 1003.1 (POSIX), che impone un singolo set di funzioni da fornire su tutti i sistemi operativi per varie attività del sistema operativo (purtroppo non tutti i sistemi operativi - ahem, - conformi). Per quanto riguarda i formati binari (e anche l'architettura di set di istruzioni della CPU), un modo per gestire questo è distribuire un formato binario di livello superiore (bytecode), quindi eseguire una trasformazione just-in-time nell'insieme di istruzioni di destinazione e formato binario (anche se questo è più sul cambiamento quando lo fai ... deve ancora essere fatto). La macchina virtuale di basso livello (LLVM), ad esempio, prevede tale trasformazione.

5

Perché, per prima cosa, la capacità di l'interfaccia con il sistema operativo non è coerente tra le piattaforme. Anche tra Linux/x86, Windows e Mac/Intel (che potrebbero tutti utilizzare la stessa CPU), il modo di fare le cose potrebbe essere molto diverso.

Così mentre un compilatore può produrre file oggetto che funzionerebbero, nel momento in cui si collegano questi oggetti a librerie specifiche della piattaforma, diventano intrinsecamente non portabili.

Un esempio è l'allocazione della memoria. Quando si desidera richiedere più memoria dal sistema operativo in UNIX, è possibile utilizzare la funzione di libreria brk o sbrk. Questa è la non la parte della libreria standard C, più una specifica per UNIX.

D'altra parte, Windows può fornire una funzione Win32GetMem per fare la stessa cosa.

0

Sì Il codice macchina viene eseguito direttamente dalla CPU. Ma anche il set di istruzioni "x86" a 32 bit che è il codice macchina ha subito revisioni nel corso degli anni. Ma in generale il codice compilato per un'architettura dovrebbe essere eseguito su altri sistemi. Un problema più grande sarebbe che compilatore e sistema operativo sono stati compilati in

0

Sì, lo fa. Ad esempio, è possibile eseguire applicazioni Windows in Linux con Wine. È possibile eseguire il programma direttamente per più di un motivo. Ad esempio, il formato del tuo eseguibile è diverso in sistemi diversi, quindi i sistemi normalmente non hanno la minima idea di come caricare ed eseguire gli altri eseguibili.Inoltre la maggior parte dei programmi vorranno chiamare routine di sistema e chiamare alcune funzioni della libreria, e qui stiamo parlando di serie di accordi completamente diversi su come è fatto in ogni sistema.

1

Hai ragione, in quanto un compilatore si preoccuperà solo di generare le istruzioni di assemblatore corrette per una specifica CPU di destinazione. Ma il compilatore non funziona da solo: un'applicazione deve normalmente interfacciarsi con il sistema operativo host per funzionare correttamente.

Quindi il problema non è con il compilatore stesso, ma l'insieme di librerie standard che ogni sistema operativo fornisce per fare cose comuni come accedere ai file, allocare memoria o interagire con il sistema di finestre grafico. Mentre il codice per, diciamo, Windows XP e Solaris x86 verrebbe compilato con lo stesso insieme di istruzioni del codice macchina, il codice dovrebbe effettuare chiamate diverse per interfacciarsi con il sistema operativo.

I compilatori proprietari vengono forniti in bundle solo con intestazioni e librerie per il sistema operativo per cui sono realizzati. Altri compilatori più agnostici come GNU GCC condividono un sacco di codice per la compilazione sullo stesso tipo di CPU tra diversi sistemi operativi.

8

Si tratta del sistema operativo API e ABI.

Diversi sistemi operativi forniscono diversi system calls e diversi meccanismi per richiamare tali chiamate di sistema. Ad esempio, mentre POSIX fornisce fork e execv per creare un nuovo processo, Windows fornisce CreateProcess.

Inoltre, ci sono differenze a livello di assemblaggio. Quale codice assembly usi per chiamare una funzione? Diversi sistemi operativi si aspettano diversi calling conventions. Anche i sistemi operativi non concordano necessariamente sulla formattazione del file eseguibile, né concordano su altri meccanismi come il collegamento dinamico.

Un altro punto da considerare è la concorrenza e il modo in cui il sistema operativo lo gestisce. Alcuni sistemi operativi riconoscono i thread a livello di kernel, mentre altri no. Alcuni potrebbero preferire semplicemente l'utilizzo di più processi e alcuni potrebbero utilizzare un modello completamente diverso. Le API sono diverse e le astrazioni potrebbero essere diverse. Ad esempio, un sistema operativo potrebbe utilizzare serrature e semafori, un altro potrebbe utilizzare il passaggio dei messaggi.

0

La tua domanda, "Quindi lo stesso codice macchina dovrebbe essere eseguito su ogni sistema operativo, purché sia ​​la stessa architettura, no?" non è corretto. Il codice macchina viene eseguito sull'hardware non sul sistema operativo. Un sistema operativo fornisce servizi all'utente/programma di sistema e questi servizi sono implementati in modo diverso in ciascun sistema operativo. Dillo per argomento, se dovessi prendere il codice macchina del tuo programma dal SO "X" sull'arco "A" e inviarlo direttamente a un sistema con OS "Y" con lo stesso arco "A", la CPU sarà in grado di per eseguire le istruzioni, ma questo potrebbe (e sarà quasi sempre) causare un arresto anomalo del programma (a causa dei diversi problemi di implementazione come altri hanno già menzionato).

Problemi correlati