Sembra che tu abbia preso in prestito un po 'di vocabolario dall'informatica teorica (riguardo le parole "set" e "lingua"), e ho cercato di usarlo per interpretare la descrizione da manuale dei sistemi di computer di livello inferiore (CPU e hardware). / p>
La parola "set" come in "instruction set architecture" si riferisce all'insieme di opcode predefiniti che sono validi per la specifica architettura della CPU.
Ad esempio, questa pagina (elenchi di istruzioni x86, su Wikipedia) elenca gli opcode che ci si possono aspettare su varie generazioni di l'architettura IA32. Ogni opcode è un membro di questo "set di istruzioni".
Quando l'autore dice "... non è del tutto preciso", suppongo che si riferisca al fatto che nessuna grammatica ci si potrebbe aspettare da una sequenza di istruzioni della macchina.
Per chiarire ulteriormente, la CPU legge i byte di istruzioni e, se è un'istruzione di macchina valida, verrà eseguita. In caso contrario, verrà generata un'eccezione hardware di "istruzione non valida", che interromperà l'esecuzione corrente e il controllo del trasferimento su un altro programma (probabilmente appartenente al sistema operativo).
Tuttavia, non esiste una grammatica che definisca quale sia una sequenza valida di istruzioni della macchina. In un certo senso, non esiste una struttura o una gerarchia che ci si possa aspettare che tutte le sequenze valide delle istruzioni della macchina siano conformi.
Le istruzioni della macchina trovate nella maggior parte dei programmi software compilati sono formate con una certa struttura; tuttavia, non tutti lo fanno. La CPU eseguirà felicemente una "sequenza spaghetti di istruzioni macchina", eseguendo salti incondizionati o condizionali mentre incontra ognuno; e fino a poco tempo fa, è possibile che una sequenza di istruzioni macchina modificasse parti di se stessa.
Alcune istruzioni della CPU sono progettate per facilitare la programmazione strutturata:
- il registro dello stack e le istruzioni push / pop
- il registro dell'indirizzo di ritorno e le istruzioni di call / return per l'esecuzione di subroutine (note anche come procedure o funzioni)
- istruzioni loop (incrementa o decrementa un registro, controlla un limite, quindi salta a un indirizzo specificato se il limite non è stato raggiunto)
- istruzioni di copia delle stringhe (un'istruzione di ciclo che copia ripetutamente i byte da un intervallo di indirizzi a un altro intervallo di indirizzi)
Anche se alcune di queste istruzioni sembrano formare coppie (push vs pop, call vs return), in realtà una sequenza valida di istruzioni della macchina non deve necessariamente corrispondere a queste coppie. Cioè, si potrebbe scrivere il successivo valore del contatore del programma nell'indirizzo di memoria indicato dal registro stack (simulando una spinta), e quindi eseguire un salto all'inizio di una subroutine (che, insieme alla spinta precedente, diventa una simulazione di una chiamata di subroutine). La subroutine potrebbe usare le normali istruzioni di ritorno.