Domanda Dubbio teoria libreria C

Il minimo sindacale per programmare è l'header <stdio.h>, che ti permette di usare i flussi di input/output.
Non c'è un' alternativa?



 
Non necessariamente, puoi compilare senza la standard library di C o specificarne un'altra (gcc opzione -nodefaultlibs, MSVC opzione /NODEFAULTLIB). Tieni in considerazione che potrebbe essere necessario reimplementare alcune feature del linguaggio, mi riferisco a funzioni come memset (e.g. char test[20] = {0}; chiama memset internamente), quelle aritmetiche a 64 bit in programmi a 32 bit (e.g. alldiv, allshr...), operazioni con float e double... Comunque nella pratica sono pochi i casi dove serve, perché puoi sempre linkarla staticamente se il problema è la dipendenza con libc.
 
Ultima modifica:
Non c'è un' alternativa?



Ci sono alternative come ha scritto Junk, ma sono svantaggiose e secondo me, a meno di particolarissime esigenze, non servono quasi mai.
 
  • Mi piace
Reazioni: Eletronick
Perché ti serve un alternativa?
Mah noo. E' solo per risolvere un dubbio teorico in mente. L' altro giorno mi sono imbattuato su una pagina web di un os **. Riguardava una versione passata di un os ** a cui stata aggiunta [O implementata?] la standard library C. Essendo scritto anche in C, mi sono chiesto: come si faceva a quei tempi nella versione precedente a programmare in C {magari era K&R o una versione precedente?}, se non c' era la standard library C?

** Non mi ricordo se era unix research, bsd, 386bsd diventato os bsd oppure Freebsd.
Non necessariamente, puoi compilare senza la standard library di C o specificarne un'altra (gcc opzione -nodefaultlibs, MSVC opzione /NODEFAULTLIB). Tieni in considerazione che potrebbe essere necessario reimplementare alcune feature del linguaggio, mi riferisco a funzioni come memset (e.g. char test[20] = {0}; chiama memset internamente), quelle aritmetiche a 64 bit in programmi a 32 bit (e.g. alldiv, allshr...), operazioni con float e double... Comunque nella pratica sono pochi i casi dove serve, perché puoi sempre linkarla staticamente se il problema è la dipendenza con libc.
Per fortuna che non devo farlo perchè questo è arabo per me, ahah.
Google mi dice che gcc e MSVC hanno la standard C library e sono superset Stessa cosa per BSD library. Se non c'è la standard library C nella vecchia versione del so, posso dedurre che ci non siano queste 3 superset? Giusto?


Ci sono alternative come ha scritto Junk, ma sono svantaggiose e secondo me, a meno di particolarissime esigenze, non servono quasi mai.
Capito. Mi viene il dubbio se era possibile programmare con questo linguaggio o un suo antenato, se non era impletamentata nell' so la standard library c.
 
È una cosa che tipicamente si fa quando si scrive un sistema operativo da zero oppure quando si programma per un microcontrollore. Per alcune funzioni come strlen non c'è problema, se non le hai disponibili ti copi il codice (che è esattamente quello che fa #include) e il gioco è fatto. Altre funzioni, tipo malloc e printf, sono inutilizzabili finché non implementi e inizializzi la parte del kernel che gestisce le syscall. Syscall è un'istruzione assembly che serve a chiamare il sistema operativo (system call) e, ovviamente, se il sistema operativo non ce l'hai ancora perché lo stai scrivendo da zero le syscall non le puoi usare finché non sei tu stesso a implementarle. Se il sistema operativo lo scrivi in un linguaggio più ad alto livello magari oltre alla standard library devi disabilitare alche alcune alcune features del linguaggio stesso; per esempio, se scrivi un sistema operativo in C++ devi disabilitare le eccezioni (-fno-exceptions) finché non vai ad implementare un exception handler a livello di sistema operativo.

Google mi dice che gcc e MSVC hanno la standard C library e sono superset Stessa cosa per BSD library. Se non c'è la standard library C nella vecchia versione del so, posso dedurre che ci non siano queste 3 superset? Giusto?
Probabilmente c'era solo una parte della libreria standard. Se ci pensi bene non è così strano. Se vai a programmare per un microcontrollore funzioni come printf non hanno senso di esistere amenoché il tuo device non abbia un display e funzioni come scanf non hanno senso di esistere amenoché non abbia una tastiera di qualche tipo. E anche in questo caso la standard library dovrai implementarla tu stesso perché magari non hai nessun sistema operativo e funzioni come la printf (ammettendo che hai un display e ammettendo che la vuoi creare) la andrai ad implementare senza chiamare nessuna syscall, magari l'ISA del tuo microcontrollore nemmeno ce l'ha la syscall.
 
È una cosa che tipicamente si fa quando si scrive un sistema operativo da zero oppure quando si programma per un microcontrollore. Per alcune funzioni come strlen non c'è problema, se non le hai disponibili ti copi il codice (che è esattamente quello che fa #include) e il gioco è fatto. Altre funzioni, tipo malloc e printf, sono inutilizzabili finché non implementi e inizializzi la parte del kernel che gestisce le syscall. Syscall è un'istruzione assembly che serve a chiamare il sistema operativo (system call) e, ovviamente, se il sistema operativo non ce l'hai ancora perché lo stai scrivendo da zero le syscall non le puoi usare finché non sei tu stesso a implementarle. Se il sistema operativo lo scrivi in un linguaggio più ad alto livello magari oltre alla standard library devi disabilitare alche alcune alcune features del linguaggio stesso; per esempio, se scrivi un sistema operativo in C++ devi disabilitare le eccezioni (-fno-exceptions) finché non vai ad implementare un exception handler a livello di sistema operativo.

Quindi non esiste anche una versione in C delle syscall o un mix tra C e assembly?
Probabilmente c'era solo una parte della libreria standard. Se ci pensi bene non è così strano. Se vai a programmare per un microcontrollore funzioni come printf non hanno senso di esistere amenoché il tuo device non abbia un display e funzioni come scanf non hanno senso di esistere amenoché non abbia una tastiera di qualche tipo. E anche in questo caso la standard library dovrai implementarla tu stesso perché magari non hai nessun sistema operativo e funzioni come la printf (ammettendo che hai un display e ammettendo che la vuoi creare) la andrai ad implementare senza chiamare nessuna syscall, magari l'ISA del tuo microcontrollore nemmeno ce l'ha la syscall.

Per me non è strano.
Può essere che magari allora non c' era l' ansi C?

Mi hanno detto che ci sono micro compatibile con l' ansi c, In questo caso c' è la questa standard library?
 
Quindi non esiste anche una versione in C delle syscall o un mix tra C e assembly?
Puoi scrivere assembly dentro il C in questo modo asm("syscall");, ma non è garantito che funzioni su tutti i compilatori perché è una parte opzionale dello standard e le stringhe assembly non sono per niente portable. Visto che puoi scrivere assembly dentro il C puoi anche creare una funzione syscall. Esiste in linux, ma non ha particolarmente senso usarla direttamente perché quando usi syscall (in assembly) vai a svegliare il sistema operativo per dirgli di eseguire una funzione che nel kernel è implementata in C, quindi tanto vale usarla direttamente in C. Al posto di scrivere syscall(SYS_write, 1, "Hello, World\n", 13); puoi scrivere write(1, "Hello, World\n", 13); oppure puoi usare la printf come si fa di solito perché tanto l'assembly generato è identico. Nota che write non è una funzione standard perché le syscall (in assembly) dipendono dal sistema operativo.

Mi hanno detto che ci sono micro compatibile con l' ansi c, In questo caso c' è la questa standard library?
Sì, amenoché non specificano altrimenti. Magari definiscono cose tipo stdin e stdout in modo particolare, per esempio potrebbero dirti che se non hai collegato nessuna interfaccia di output allora stdout è l'equivalente di /dev/null in linux (butta via tutto e non stampare niente da nessuna parte).
 
  • Mi piace
Reazioni: Eletronick
Ultima modifica:
Nota che write non è una funzione standard perché le syscall (in assembly) dipendono dal sistema operativo.
Hai ragione quando dici che le syscall dipendono dal sistema operativo, però un po' meno quando hai detto che la funzione write() non è standard. Su Windows esiste una funzione diversa che è WriteFile(), se non erro. Però è pur vero che esistono delle API standard che i sistemi operativi utilizzano per fare le chiamate di sistema. Tralasciando Windows, che fa sempre le cose a parte. I sistemi Posix hanno quasi tutti la stessa interfaccia per le chiamate di sistema e in questo caso write() è standard su questi SO. Così come anche le funzioni close(), open(), ecc.
 
  • Mi piace
Reazioni: Eletronick
Ultima modifica:
Puoi scrivere assembly dentro il C in questo modo asm("syscall");, ma non è garantito che funzioni su tutti i compilatori perché è una parte opzionale dello standard e le stringhe assembly non sono per niente portable.
Con questa opzione ci sono uno o più header nel programma?

Mentre per quanto riguarda la seconda parte vale anche per i compilatori per una stessa architettura (es. Amd64) e per lo stesso sistema operativo?

Esiste in linux, ma non ha particolarmente senso usarla direttamente perché quando usi syscall (in assembly) vai a svegliare il sistema operativo per dirgli di eseguire una funzione che nel kernel è implementata in C, quindi tanto vale usarla direttamente in C. Al posto di scrivere syscall(SYS_write, 1, "Hello, World\n", 13); puoi scrivere write(1, "Hello, World\n", 13); oppure puoi usare la printf come si fa di solito perché tanto l'assembly generato è identico.
@CrazyMonk

Sono andato vedere sia il link che dei sorgenti (partendo da syscall.c) di ricerca su Gnu-Linux. Ci sono diverse librerie ed header interfacciati tra loro. Più si cerca e più spuntano uno o più header con la relativa libreria. E' un casino per me da capire e ci ho rinunciato. Da quel poco che ho visto solo una piccola parte è in assembly.

Come si fa ad implementarla in C? Come hanno fatto in passato?
Suppongo che sia possibile avere un unico file HelloWorld.c con tutto il codice necessario senza nessuna dipendenza da header e librerie. Però chissà come si fa e come si è fatto in passato. E' un mistero per me da risolvere ahah.

Questo può riguarda il mio caso?



Vedi: https://www.reddit.com/r/programming/comments/33koxz/hello_world_in_c_without_libraries_or_similar/


viene linkato questo: https://gynvael.coldwind.pl/?id=477

Però tra i commenti leggo questo boh "
It isn't, because this code just emulates what printf/puts etc. already do, except poorly and nonportably.
Sure, it's nice to look at, but that's it.
Apart from that, it still depends on syscalls... A hello world that results in a kernel panic somehow displaying the string "Hello world", now that would be impressive. :)"
 
Per poter capire a pieno questo argomento non basta che rispondiamo alle singole domande o dovremmo scendere troppo nel dettaglio. Devi approfondire prima gli argomenti di portabilità, formati file eseguibili (PE, ELF...) e come si interfacciano con il sistema operativo e gli altri programmi. Capisci che un codice C senza librerie esterne e senza syscall può agire solo nell'area di memoria che gli compete, se vuoi fare una printf sulla finestra della console è ovvio che stiamo parlando di un contesto user-mode. Le syscall ti danno modo di accedere alle risorse fuori dal tuo processo: se vuoi leggere il contenuto di un file e caricarlo in un area di memoria nel tuo address space dovrai usare più syscall per aprire, leggere e chiudere il file, allo stesso modo il concetto di stream di output è fornito dal kernel: la printf non fa altro che formattare la stringa e scriverla su stdout con una syscall. Se non fosse così il processo che gestisce la finestra della console non potrebbe ricevere e visualizzare ciò che scrivi.
 
  • Mi piace
Reazioni: Eletronick
Ultima modifica:
Con questa opzione ci sono uno o più header nel programma?

Mentre per quanto riguarda la seconda parte vale anche per i compilatori per una stessa architettura (es. Amd64) e per lo stesso sistema operativo?
No, non ha bisogno di nessun header. È una keyword, non una funzione, ed è una funzionalità che fa parte dello standard ma è opzionale. Ognuno può implementarla un po' come gli pare. Puoi scrivere un compilatore che non la implementa proprio, puoi implementarla usando la sintassi che vuoi (eg., AT&T o Intel o roba che ti inventi tu) e ovviamente è anche un po' dipendente dall'hardware perché l'assembly stesso dipende dall'hardware.

Facciamo un passo indietro. Posso scrivere un codice C che non usa la libreria standard? Sì, eccolo int main () { return 0; }. Un esempio un pelino meno banale è questo:
C:
int main(int argc, char *argv[]) {
  int sum = 0;
  for (int i = 1; i < argc; i++) {
    int value = 0;
    for (int j = 0; argv[i][j] != '\0'; j++)
      value = value * 10 + argv[i][j] - '0';
    sum += value;
  }
  return sum;
}
Su linux puoi compilarlo in questo modo gcc sum.c -o sum, eseguirlo in questo modo ./sum 8 6 10 9 2 74 e l'output (109) lo trovi nell'exit status che puoi stampare a schermo scrivendo echo $? subito dopo aver eseguito il programma. Un esempio ancora meno banale di programma che non usa nessuna libreria potrebbe essere un programma senza nessun main che va a definire una funzione che calcola il prodotto di matrici in modo efficiente. Questo programma particolare senza nessun main si chiama libreria e per usarlo lo devi compilare e poi richiamare da un altro programma, magari scritto in un linguaggio di programmazione diverso e meno efficiente.

Se sei su linux e vuoi scrivere un programma in C che stampa un messaggio a schermo senza usare nessuna libreria (nemmeno quella standard) devi usare l'istruzione assembly syscall (usando l'inline assembly oppure programmando direttamente in assembly) per usare la funzionalità "stampa un messaggio a schermo" implementata in C nel kernel linux. Se vuoi fare la stessa cosa su una scheda elettronica costruita da te dovrai scrivere il codice che va a controllare i pin del microcontrollore in modo tale da accendere i led nel display che gli hai collegato.

Un normale computer senza sistema operativo puoi immaginartelo come una complessa scheda elettronica, perché alla fine è di quello che si tratta. In realtà non è proprio così. Scrivere un messaggio a schermo in un computer senza sistema operativo è difficile, ma è comunque molto più semplice che pensare all'intero computer come un ammasso di hardware. I computer sono già stati progettati per fare alcune cose che facilitano l'avvio di un sistema operativo. C'è il BIOS, ci sono i firmware, il processore ha un'area di memoria dedicata alla VGA e ci sono un sacco di altre menate che non sto qui a spiegarti. Non voglio mettere troppa carne al fuoco visto che mi sembra che già ci stai capendo poco. Per adesso accontentati di capire cosa avviene quando sotto c'è un sistema operativo (chiami syscall) e cosa devi fare quando hai una scheda elettronica scritta da te (controlli lo stato dei pin). Il computer senza sistema operativo è un po' una via di mezzo tra i due: alla fine vai sempre a controllare l'hardware, ma lo fai attraverso un sacco di automatismi e astrazioni che sono presenti anche senza sistema operativo.

In generale, quando vuoi capire come funziona un computer partendo da zero mettiti nei panni "ho un microcontrollore costruito da me attaccato ad una scheda elettronica costruita da me". Questo ti permette di capire come ci si interfaccia con l'hardware senza doverti scontrare con le complessità di un computer vero e proprio. Se poi vuoi sapere i dettagli, devi leggerti almeno un paio di libri.

Magari sono io che non ho capito la tua domanda ma a me sembra che quel link non spiega quello che ti interessa. Quel post ti fa vedere come si riesce a chiamare una libreria andandola a pescare dalla memoria invece che importandola esplicitamente.
 
Per poter capire a pieno questo argomento non basta che rispondiamo alle singole domande o dovremmo scendere troppo nel dettaglio.
Hai perfettamente ragione.
Considera che mi interessa solo a livello molto generale, la realizzazione da zero di Sycall ed altre librerie, all' interno per es. di Gnu-linux ,vedendo codice già fatto di cose semplici e molto semplice.

Le syscall ti danno modo di accedere alle risorse fuori dal tuo processo: se vuoi leggere il contenuto di un file e caricarlo in un area di memoria nel tuo address space dovrai usare più syscall per aprire, leggere e chiudere il file, allo stesso modo il concetto di stream di output è fornito dal kernel: la printf non fa altro che formattare la stringa e scriverla su stdout con una syscall. Se non fosse così il processo che gestisce la finestra della console non potrebbe ricevere e visualizzare ciò che scrivi.

@St3ve Se non ho capito male andando ad utilizzare la libreria standard C, di conseguenza si va pure ad utilizzare anche le relative syscall in C, giusto?

Se è così vorrei capire quali possano essere i pro e i vantaggi di andare utilizzare la libreria standard C, e quindi le relative funzioni, quando si possono le sycall in C. Forse perchè la libreria standard C permette di poter fare determinate cose che con le sycall in C non è possibile fare a meno che uno non si implementi il tutto da zero utilizzando le sycall in C?

In entrambi i casi ci sono o più header da includere nel programma che sono collegi alla rispettiva libreria.

Ho trovato la prima versione del compilatore in C


Capisci che un codice C senza librerie esterne e senza syscall può agire solo nell'area di memoria che gli compete, se vuoi fare una printf sulla finestra della console è ovvio che stiamo parlando di un contesto user-mode.

Le syscall considerando il C non sono librerie? Da quello che ho visto mi viene da dire di si.
Facciamo un passo indietro. Posso scrivere un codice C che non usa la libreria standard? Sì, eccolo int main () { return 0; }. Un esempio un pelino meno banale è questo:
C:
int main(int argc, char *argv[]) {
int sum = 0;
for (int i = 1; i < argc; i++) {
int value = 0;
for (int j = 0; argv[i][j] != '\0'; j++)
value = value * 10 + argv[i][j] - '0';
sum += value;
}
return sum;
}
Su linux puoi compilarlo in questo modo gcc sum.c -o sum, eseguirlo in questo modo ./sum 8 6 10 9 2 74 e l'output (109) lo trovi nell'exit status che puoi stampare a schermo scrivendo echo $? subito dopo aver eseguito il programma.
Qui l' Ansi C non prevede di includere nel programma stdio.h essendoci int main?
Sum , è un funzione?
Se sei su linux e vuoi scrivere un programma in C che stampa un messaggio a schermo senza usare nessuna libreria (nemmeno quella standard) devi usare l'istruzione assembly syscall (usando l'inline assembly oppure programmando direttamente in assembly) per usare la funzionalità "stampa un messaggio a schermo" implementata in C nel kernel linux.

Con la prima opzione, in cui si utilizza l' assembly inline, poi si bypasserà del tutto la dipendenza con le sycall in C nel kernel Linux?

Un' altra opzione è creare una syscall in C però bypassando del tutto quelle su Linux?

Poi non se è possibile a livello tenico creare una propria libreria ed inserirla all' interno del codice del programma. Se si chissà se servirà scrivere nello stesso file anche il codice dell' header.


Per adesso accontentati di capire cosa avviene quando sotto c'è un sistema operativo (chiami syscall) e cosa devi fare quando hai una scheda elettronica scritta da te (controlli lo stato dei pin).

Considera che non mi interessa quando non c'è il sistema operativo. C'è un' altra cosa che mi interessa a livello generale e divulgativa e riguarda la realizzazione dei driver su Gnu-linux (tra cui l' accelerazione gpu). Merita una discussione tutta sua e non specifica su un linguaggio di programmazione. Però ho visto che a livello divulgativo è complessa la cosa quindi non ho ancora deciso se è bene aprire la discussione oppure no.

In aggiunta mi interessa anche considerare il caso in cui c'è il sistema operativo però ad es. la libreria standard C non è implementa oppure non so è mai stato possibile un sistema operativo senza syscall. Nel caso di Gnu-linux forse è da considerare il caso in cui qualcuno vada a cancellare i file delle syscall ahah.

P.S. per curiosità quali sono i libri in questione?

Nel frattempo ringrazio tutti per le spiegazioni e l' aiuto :)

Magari sono io che non ho capito la tua domanda ma a me sembra che quel link non spiega quello che ti interessa. Quel post ti fa vedere come si riesce a chiamare una libreria andandola a pescare dalla memoria invece che importandola esplicitamente.

Se quel post fa vedere questo che hai detto allora non mi interessa.
 
Come già è stato detto le syscall "risvegliano" il sistema operativo. In pratica non sono altro che interrupt che segnalano al processore di passare il controllo dell'esecuzione al kernel. è bene sottolineare che le syscall sono implementate e gestite a livello kernel e hardware, la libc e altre librerie le chiamano soltanto. Funziona in questo modo: ogni syscall ha un ID numerico, facciamo finta che vuoi scrivere un file e su questo kernel la syscall write ha id 123 (costante SYS_write): potresti fare mov eax, 123 syscall ret (x86 intel), ovviamente passando prima tutti gli argomenti richiesti da write via stack o registri. Per eseguire syscall dal tuo programma C senza librerie dovrai mettere l'ID in un registro della CPU e poi fare syscall (in Assembly x86 intel rappresentata dall'opcode, little endian, 0x050F), questo avrà l'effetto di fare un "jump" nel kernel, esso controllerà l'ID presente nel registro per sapere che tipo di operazione vuoi eseguire e la chiamerà, te lo puoi immaginare come un grosso switch o una mappa ID -> puntatore alla funzione kernel. Per fare una syscall non devi per forza usare un header, se conosci l'ID puoi chiamarla direttamente dall'inline assembly, le syscall vengono sempre eseguite in questo modo, la libreria standard serve sia ad usarle con più semplicità, sia per essere portatile (altrimenti dovresti avere gli ID per le syscall di ogni possibile OS dove deve girare). Le syscall non sono librerie, sono invece l'interfaccia principale con il sistema operativo, quando si parla di librerie di solito si parla anche di linking, un altro argomento importante per capire come i programmi comunicano tra di loro.
 
  • Mi piace
Reazioni: Eletronick
Le syscall considerando il C non sono librerie? Da quello che ho visto mi viene da dire di si.
Syscall è un'istruzione assembly presente in alcune architetture che ti permette di chiamare il sistema operativo e chiedergli di fare qualcosa. Comunemente si chiamano syscall anche le funzioni all'interno del kernel che vanno ad implementare una funzionalità che poi potrà essere eseguita usando l'istruzione assembly syscall (la funzione write che ho usato in precedenza è una syscall in questo senso).

Se non ho capito male andando ad utilizzare la libreria standard C, di conseguenza si va pure ad utilizzare anche le relative syscall in C, giusto?
Alcune funzioni nella libreria standard C sono implementate attraverso una syscall. Per fare un discorso terra terra, se vuoi leggere un file su disco devi chiedere al sistema operativo (syscall) di leggerlo al posto tuo: controllare la testina dell'hard disk per andare a leggere un file è un'operazione complessa che se fai male ti porta a fare danni al componente hardware, quindi il kernel ti vieta di controllare manualmente l'hard disk e ti fornisce (attraverso l'uso di syscall) delle astrazioni che ti permettono di svolgere un compito ad alto livello tipo "leggi un file".

Se è così vorrei capire quali possano essere i pro e i vantaggi di andare utilizzare la libreria standard C, e quindi le relative funzioni, quando si possono le sycall in C. Forse perchè la libreria standard C permette di poter fare determinate cose che con le sycall in C non è possibile fare a meno che uno non si implementi il tutto da zero utilizzando le sycall in C?
Semplificando, lo standard C è ad alto livello mentre le syscall sono a basso livello. Lo standard C ti dice cose del tipo "per stampare un carattere su standard output si usa putc". Chi ha scritto gcc e linux (o meglio, come ha detto CrazyMonk, chi ha scritto lo standard POSIX) ti dice "lo standard output è lo stream principale della linea di comando e per stampare su standard output devi usare la syscall write sul file descriptor 1". La funzionalità descritta dallo standard C la puoi implementare anche se non hai nessuna command line. Quando definisci le cose in modo troppo preciso (più a basso livello) diventano inevitabilmente meno portable e chi ha inventato il C voleva farlo girare un po' ovunque, non solo su un hardware ben preciso.

Qui l' Ansi C non prevede di includere nel programma stdio.h essendoci int main? Sum , è un funzione?
No, sum è una variabile e per scrivere una funzione (il main) non serve nessun header file. Se non sai nemmeno la sintassi di base è inutile che provi a capire quello che c'è scritto nei file del kernel linux, sono impegnativi da seguire anche per chi è molto pratico di C.

Con la prima opzione, in cui si utilizza l' assembly inline, poi si bypasserà del tutto la dipendenza con le sycall in C nel kernel Linux?
No, la funzione assembly syscall è dipendente dal sistema operativo per definizione. Le syscall in linux sono diverse dalle syscall in windows proprio nel senso che lo stesso codice assembly può fare cose completamente diverse sui due sistemi operativi. Se stai implementando un sistema operativo non puoi usare l'istruzione assembly syscall finché non vai ad implementare (in C o in un altro linguaggio) il syscall handler all'interno del kernel.

Un' altra opzione è creare una syscall in C però bypassando del tutto quelle su Linux?
Syscall vuol dire system call che in italiano si traduce con "chiamata al sistema (operativo)". Se stai usando il sistema operativo linux, quando chiami l'istruzione syscall vai ad eseguire codice all'interno del kernel linux. Creare una syscall che bypassa il sistema operativo è un ossimoro perché il termine syscall lo possiamo tradurre come "passa per il sistema operativo" e "passare per il sistema operativo bypassando il sistema operativo" non ha alcun senso. Se non vuoi passare per il sistema operativo basta che non usi la syscall.

Poi non se è possibile a livello tenico creare una propria libreria ed inserirla all' interno del codice del programma. Se si chissà se servirà scrivere nello stesso file anche il codice dell' header.
Sì ed è una cosa che i programmatori, anche quelli super dilettanti, fanno quotidianamente.

In aggiunta mi interessa anche considerare il caso in cui c'è il sistema operativo però ad es. la libreria standard C non è implementa oppure non so è mai stato possibile un sistema operativo senza syscall.
È possibilissimo scrivere un sistema operativo che non supporta lo standard C (l'hai trovato tu stesso!) ed è possibilissimo scrivere un sistema operativo che non usa nessuna syscall, però non sarà un sistema operativo sicuro perché le syscall sono state inventate per fornire un meccanismo di protezione: alcune funzioni (eg. spostare la testina dell'hdd, controllare la velocità con cui gira il lettore cd, etc.) le deve svolgere il kernel, non chi programma gli applicativi in userspace perché se lo fai male rischi di rompere il computer. Anche qui, in realtà non è proprio così perché alcune cose vengono controllate dal firmware... però bear with me e accontentati della spiegazione semplificata.

P.S. per curiosità quali sono i libri in questione?
Un qualsiasi libro che parla di computer architecture e un qualsiasi libro che parla di operating systems.


Comunque da questo ultimo post ho capito che stai facendo domande tecniche senza avere le basi per poter comprendere le risposte. A questo punto sono io che non ho ben chiaro cosa sai, cosa non sai, cosa ti interessa sapere e perché ti interessa saperlo. Capisco il fattore curiosità, ma se mi chiedi cose come "posso creare una syscall che bypassa il sistema operativo?" allora non sai nemmeno tu cosa mi stai chiedendo. Se ti resta ancora qualche dubbio, prova a spiegarci meglio quello che hai in testa, quello che vuoi fare o quello che vuoi capire. Se vuoi semplicemente sapere se si possono scrivere librerie in C che non usano la libreria standard e non usano syscall: sì, nel post precedente ti ho scritto due codici che lo fanno e ti ho riportato un esempio realistico.
 
Come già è stato detto le syscall "risvegliano" il sistema operativo. In pratica non sono altro che interrupt che segnalano al processore di passare il controllo dell'esecuzione al kernel. è bene sottolineare che le syscall sono implementate e gestite a livello kernel e hardware, la libc e altre librerie le chiamano soltanto. Funziona in questo modo: ogni syscall ha un ID numerico, facciamo finta che vuoi scrivere un file e su questo kernel la syscall write ha id 123 (costante SYS_write): potresti fare mov eax, 123 syscall ret (x86 intel), ovviamente passando prima tutti gli argomenti richiesti da write via stack o registri. Per eseguire syscall dal tuo programma C senza librerie dovrai mettere l'ID in un registro della CPU e poi fare syscall (in Assembly x86 intel rappresentata dall'opcode, little endian, 0x050F), questo avrà l'effetto di fare un "jump" nel kernel, esso controllerà l'ID presente nel registro per sapere che tipo di operazione vuoi eseguire e la chiamerà, te lo puoi immaginare come un grosso switch o una mappa ID -> puntatore alla funzione kernel. Per fare una syscall non devi per forza usare un header, se conosci l'ID puoi chiamarla direttamente dall'inline assembly, le syscall vengono sempre eseguite in questo modo, la libreria standard serve sia ad usarle con più semplicità, sia per essere portatile (altrimenti dovresti avere gli ID per le syscall di ogni possibile OS dove deve girare). Le syscall non sono librerie, sono invece l'interfaccia principale con il sistema operativo, quando si parla di librerie di solito si parla anche di linking, un altro argomento importante per capire come i programmi comunicano tra di loro.
Ho capito.

Comunemente si chiamano syscall anche le funzioni all'interno del kernel che vanno ad implementare una funzionalità che poi potrà essere eseguita usando l'istruzione assembly syscall (la funzione write che ho usato in precedenza è una syscall in questo senso).

Qual è il nome corretto così non si confonde?
Alcune funzioni nella libreria standard C sono implementate attraverso una syscall. Per fare un discorso terra terra, se vuoi leggere un file su disco devi chiedere al sistema operativo (syscall) di leggerlo al posto tuo: controllare la testina dell'hard disk per andare a leggere un file è un'operazione complessa che se fai male ti porta a fare danni al componente hardware, quindi il kernel ti vieta di controllare manualmente l'hard disk e ti fornisce (attraverso l'uso di syscall) delle astrazioni che ti permettono di svolgere un compito ad alto livello tipo "leggi un file".
Intendi tipo: syscall.c , unistd.c , errno.c ?
Chi ha scritto gcc e linux (o meglio, come ha detto CrazyMonk, chi ha scritto lo standard POSIX) ti dice "lo standard output è lo stream principale della linea di comando e per stampare su standard output devi usare la syscall write sul file descriptor 1". La funzionalità descritta dallo standard C la puoi implementare anche se non hai nessuna command line.
Io ho trovato questo , https://en.wikipedia.org/wiki/Write_(system_call) che però non essendo in assembly non è la vera syscall ma una funzione che va poi a richiamare la syscall, giusto?


No, sum è una variabile e per scrivere una funzione (il main) non serve nessun header file.
Ah si giusto è una variabile. Bisogna sempre guardare le cose con più attenzione se no poi si fanno questi errori ahah.

A funzionare funziona però l' ansi C dice che va incluso. Invece nel primo libro dei creatori del C, uscito prima dell' ansi C fanno capire che non è obbligatorio. Così io ricordo. Però poi alla fine chissene dell' ansi C ahah.


Creare una syscall che bypassa il sistema operativo è un ossimoro perché il termine syscall lo possiamo tradurre come "passa per il sistema operativo
Non ho scritto che bypassa il sistema operativo ma la syscall che c'è :). Però come la syscall che c'è si deve interfaccia con il sistema operativo.
Con "syscall" mi riferivo ai file con estensione .c che ho menzionato sopra. Uno dei quei file ha ad es. del codice in assembly che però non è da rimpiazzare.

Però essendo Linux un kernel monolitico mi viene il dubbio che forse per fare questo bisogna avere una versione custom. Però ditemi voi esperti.

Sì ed è una cosa che i programmatori, anche quelli super dilettanti, fanno quotidianamente.
Are you serious?
È possibilissimo scrivere un sistema operativo che non supporta lo standard C (l'hai trovato tu stesso!) ed è possibilissimo scrivere un sistema operativo che non usa nessuna syscall, però non sarà un sistema operativo sicuro perché le syscall sono state inventate per fornire un meccanismo di protezione: alcune funzioni (eg. spostare la testina dell'hdd, controllare la velocità con cui gira il lettore cd, etc.) le deve svolgere il kernel, non chi programma gli applicativi in userspace perché se lo fai male rischi di rompere il computer. Anche qui, in realtà non è proprio così perché alcune cose vengono controllate dal firmware... però bear with me e accontentati della spiegazione semplificata.
Ora capisco il perchè implementarle all' interno di un sistema operativo.
No, la funzione assembly syscall è dipendente dal sistema operativo per definizione. Le syscall in linux sono diverse dalle syscall in windows proprio nel senso che lo stesso codice assembly può fare cose completamente diverse sui due sistemi operativi. Se stai implementando un sistema operativo non puoi usare l'istruzione assembly syscall finché non vai ad implementare (in C o in un altro linguaggio) il syscall handler all'interno del kernel.
Forse è per questo che ci sono determinate funzioni su Gnu-Linux in C che non ci sono su Windows in C, e viceversa.

Syscall handler riguarda il signal handler?
Comunque da questo ultimo post ho capito che stai facendo domande tecniche senza avere le basi per poter comprendere le risposte.
Non sono del settore. Svariate cose scritte qui le ho capite. Poi c'è pure google, per fortuna, tra cui youtube. Poi per le cose che continuo a non capire, come accade anche in altri ambiti, beh le metto da parte e vado avanti.

Oltre alla curiosità, ci sono i dubbi ed il mistero (per me almeno) da risolvere :) .


Se ti resta ancora qualche dubbio, prova a spiegarci meglio quello che hai in testa, quello che vuoi fare o quello che vuoi capire.
Vorrei capire a livello generale e semplice cos'è per es. il syscall hadler, com'è struttura la libreria c tra cui i file .c che ho menzionato sopra e che però non contengono le funzioni usate da chi programma in C. Mi viene l' ipotesi che sia una doppia struttura dove i file .c che ho menzionato (conterranno anche uno o file .c) facciano da ponte dalle syscall (scritte in assembly) ed i file .c dove ci sono invece le funzioni utilizzate per la programmazione in C.

Se può essere utile ho trovato il compilatore C che deriva dal compilatore C di Ritchie e che ha subito delle modifiche fino alla sua ultima versione.
 
Ho capito.



Qual è il nome corretto così non si confonde?

Intendi tipo: syscall.c , unistd.c , errno.c ?

Io ho trovato questo , https://en.wikipedia.org/wiki/Write_(system_call) che però non essendo in assembly non è la vera syscall ma una funzione che va poi a richiamare la syscall, giusto?



Ah si giusto è una variabile. Bisogna sempre guardare le cose con più attenzione se no poi si fanno questi errori ahah.

A funzionare funziona però l' ansi C dice che va incluso. Invece nel primo libro dei creatori del C, uscito prima dell' ansi C fanno capire che non è obbligatorio. Così io ricordo. Però poi alla fine chissene dell' ansi C ahah.



Non ho scritto che bypassa il sistema operativo ma la syscall che c'è :). Però come la syscall che c'è si deve interfaccia con il sistema operativo.
Con "syscall" mi riferivo ai file con estensione .c che ho menzionato sopra. Uno dei quei file ha ad es. del codice in assembly che però non è da rimpiazzare.

Però essendo Linux un kernel monolitico mi viene il dubbio che forse per fare questo bisogna avere una versione custom. Però ditemi voi esperti.


Are you serious?

Ora capisco il perchè implementarle all' interno di un sistema operativo.

Forse è per questo che ci sono determinate funzioni su Gnu-Linux in C che non ci sono su Windows in C, e viceversa.

Syscall handler riguarda il signal handler?

Non sono del settore. Svariate cose scritte qui le ho capite. Poi c'è pure google, per fortuna, tra cui youtube. Poi per le cose che continuo a non capire, come accade anche in altri ambiti, beh le metto da parte e vado avanti.

Oltre alla curiosità, ci sono i dubbi ed il mistero (per me almeno) da risolvere :) .



Vorrei capire a livello generale e semplice cos'è per es. il syscall hadler, com'è struttura la libreria c tra cui i file .c che ho menzionato sopra e che però non contengono le funzioni usate da chi programma in C. Mi viene l' ipotesi che sia una doppia struttura dove i file .c che ho menzionato (conterranno anche uno o file .c) facciano da ponte dalle syscall (scritte in assembly) ed i file .c dove ci sono invece le funzioni utilizzate per la programmazione in C.

Se può essere utile ho trovato il compilatore C che deriva dal compilatore C di Ritchie e che ha subito delle modifiche fino alla sua ultima versione.
@Eletronick, i ragazzi del forum hanno risposto in modo più che esaustivo a molte delle tue domande. Se ne hai tantissime altre, studia da solo in modo più approfondito l'argomento. Non è possibile né opportuno rispondere, in un singolo thread, a tutte le domande riguardanti una materia così vasta e complessa come quella dei Sistemi Operativi. 😉
 
@Eletronick, i ragazzi del forum hanno risposto in modo più che esaustivo a molte delle tue domande. Se ne hai tantissime altre, studia da solo in modo più approfondito l'argomento. Non è possibile né opportuno rispondere, in un singolo thread, a tutte le domande riguardanti una materia così vasta e complessa come quella dei Sistemi Operativi. 😉

Non ho altre domande sull' argomento. Lo studio e l' appronfondimento non c' entrano nulla con questo thread che riguarda invece solamente la divulgazione. Poi le domande erano per Gnu-linux e non la materia sistemi operativi.

Essendo un forun ogni utente decide se e quando rispondere.
 
Ti rispondo giusto per chiudere il discorso che abbiamo iniziato, ma ha ragione CrazyMonk. Si fa fatica a farti capire bene perché dici di essere interessato al concetto generale ma stai in realtà facendo domande tecniche e piuttosto precise (sei andato anche a citare i file .c del kernel linux) su cose di cui non hai ancora le competenze per poter comprendere appieno. Il concetto generale te lo possiamo anche spiegare e penso che tu hai le capacità per capirlo, ma sei finito per fare domande tecniche senza aver capito bene il funzionamento di base. In realtà negli ultimi post ci siamo anche un po' ripetuti. Mi rendo conto che sono argomenti complicati, ma stai facendo domande di cui hai già avuto una risposta.

Qual è il nome corretto così non si confonde?
Il nome corretto è syscall. Si usa questo termine sia per l'istruzione assembly che ha questo nome, che per le funzioni C (eg., la syscall write che hai linkato da wikipedia) che servono per richiedere l'intervento del sistema operativo e sia per l'implementazione di queste funzioni.

A funzionare funziona però l' ansi C dice che va incluso. Invece nel primo libro dei creatori del C, uscito prima dell' ansi C fanno capire che non è obbligatorio. Così io ricordo. Però poi alla fine chissene dell' ansi C ahah.
No, l'ANSI C non dice questa cosa e in nessuna edizione del K&R c'è scritto così. Sentiti libero di scattarmi una foto della pagina che dice il contrario se proprio sei convinto di quello che dici. Non devi includere proprio niente amenoché non ce n'è il bisogno. Gli esempi che ti ho fatto io non includono niente e sono corretti nel 2023 così come sarebbero stati corretti anche se fossimo nel 1980, prima che il C diventasse standard.

Non ho scritto che bypassa il sistema operativo ma la syscall che c'è :). Però come la syscall che c'è si deve interfaccia con il sistema operativo.
Con "syscall" mi riferivo ai file con estensione .c che ho menzionato sopra. Uno dei quei file ha ad es. del codice in assembly che però non è da rimpiazzare.

Però essendo Linux un kernel monolitico mi viene il dubbio che forse per fare questo bisogna avere una versione custom. Però ditemi voi esperti.
Non ho capito niente di questa frase anche perché mi sembra che non abbia proprio senso. Magari descrivi uno scenario invece di fare confusione con i termini tecnici.

Vorrei capire a livello generale e semplice cos'è per es. il syscall hadler, com'è struttura la libreria c tra cui i file .c che ho menzionato sopra e che però non contengono le funzioni usate da chi programma in C. Mi viene l' ipotesi che sia una doppia struttura dove i file .c che ho menzionato (conterranno anche uno o file .c) facciano da ponte dalle syscall (scritte in assembly) ed i file .c dove ci sono invece le funzioni utilizzate per la programmazione in C.
Okay, questa è l'unica domanda abbastanza generale e con i piedi per terra su cui mi sento di poterti dare una risposta alla tua portata. La libreria standard del C è implementata in C. Alcune funzioni sono completamente indipendenti, per esempio la funzione per calcolare la lunghezza di una stringa la puoi implementare (in C) con 5 righe di codice senza chiamare nessun'altra funzione. Altre funzioni, per esempio la funzione per stampare un messaggio a schermo, devono interfacciarsi con l'hardware. Interfacciarsi con l'hardware è un'operazione delicata (se la fai male rompi l'hardware) e per questa ragione le cpu x86 hanno un meccanismo che dice "questa istruzione qui è privilegiata e la puoi fare solo se sei in modalità kernel". Se stai scrivendo il kernel puoi stampare un messaggio a schermo perché puoi utilizzare queste istruzioni privilegiate, se stai scrivendo un programma in userspace non puoi andare direttamente a stampare un messaggio a schermo ma puoi chiamare il kernel e chiedergli di farlo al posto tuo. Per fare questa cosa si usano le syscall (syscall = chiama il sistema). Quando esegui l'istruzione assembly syscall il tuo codice si ferma e parte una sezione di codice all'interno del kernel che si chiama syscall handler (gestore di syscall). Questo codice all'interno del kernel è scritto in C, come quasi tutto il resto del kernel, e si occupa di identificare la richiesta che è stata fatta (eg., "stampa un messaggio a schermo") e decidere se svolgerla o meno. Altre operazioni che richiedono l'uso di syscall sono, per esempio, quella per spawnare un nuovo thread e quella per aprire una socket: ti serve una syscall non sono solo quando devi usare l'hardware, ma più in generale anche per tutte quelle operazioni che hanno bisogno di smanettare con il sistema operativo.

Questo è quello che succede in termini generali. Se poi vuoi sapere dove si trova tutta sta roba all'interno del kernel linux, eh... è una bestia da 8 milioni di linee di codice e per lo più è un sistema operativo, non proprio un programmino facile facile da comprendere. Non mi sembra che hai le competenze né l'interesse di comprendere un codice di questa portata, ma ti faccio vedere un paio di cose giusto per toglierti lo sfizio e perché lo trovo interessante anche io:
  1. dispatching delle syscall
  2. implementazione della syscall write in kernel space
  3. implementazione della syscall write in user space (quella che che puoi usare normalmente)
  4. parte finale (long story short) con inline assembly e istruzione syscall della syscall write in user space chiama la syscall write in kernel space.
Bonus point, visto che l'abbiamo citata, implementazione della funzione syscall dello standard POSIX.

Un programmatore che vuole stampare "hello world" a schermo chiama (indirettamente, tipo tramite printf) la syscall write che vedi nel punto 3 che va ad eseguire le istruzioni che vedi al punto 4. In queste istruzioni è presente l'istruzione assembly syscall che ti fa eseguire quello che vedi nel punto 1 con i parametri neccessari per entrare nel codice che vedi al punto 2. Nel codice al punto 2 c'è l'effettiva implementazione di "stampa un messaggio a schermo", che in realtà è "scrivi su un file" ma in linux "everything is a file".
 
  • Love
Reazioni: --- Ra ---