[1] Forse gli unici casi in cui esiste un buon grado di sicurezza sono quelli in cui il vettore punta ad un indirizzo nel quale è davvero improbabile (se non impossibile) che si trovi codice eseguibile (ad esempio un vettore pari a 0000:0000 è sicuramente inutilizzato).

[2] In tutto 5: uno per l'opcode dell'istruzione JMP FAR e quattro per il vettore a 32 bit.

[3] Il cast a puntatore a interrupt evita che il compilatore, assegnando tale tipo di dato a una locazione che dovrebbe contenere un long, segnali un conflitto tra i tipi di dato.

[4] Se la funzione contenente i dati è definita, nel sorgente, prima di ogni altra, il programma può terminare come un TSR e lasciare residente in memoria quella soltanto (oltre, naturalmente, allo startup code). Dal momento che la funzione è in realtà un'area di "parcheggio" per dati, il programma non è un vero TSR, in quanto nessuna sua parte rimane attiva in memoria. Si tratta, ancora una volta, di un trucco...

[5] Direi, anzi, assolutamente fondamentale.

[6] Anche i gestori scritti in linguaggio C devono comunque mantenere una rigorosa coerenza con le particolari regole di interfacciamento con il sistema seguite dagli interrupt.

[7] Se non lo conoscessero, come potrebbero passare i parametri eventualmente richiesti ed interpretare correttamente il valore restituito?

[8] Si può usare l'istruzione INT solo se si tratta di gestori di interrupt.

[9] Il compilatore genera in testa alla funzione, in modo automatico e trasparente al programmatore, le istruzioni assembler per la gestione dello stack (le solite PUSH BP e MOV BP,SP seguite, se nella funzione sono definite variabili locali, dall'istruzione per il decremento di SP). Un'istruzione JMP FAR seguita dai 4 byte di indirizzo si collocherebbe inevitabilmente dopo dette istruzioni: sarebbe il disastro. Vi è una sola scappatoia semplice, peraltro onerosa e restrittiva dal punto di vista logico: dichiarare tutte le funzioni installabili prive di parametri e di variabili locali, e compilare senza standard stack frame. Chi volesse invece eccedere negli stratagemmi potrebbe riservare i 5 byte in testa alla funzione e poi inizializzare, con una procedura runtime, i primi byte della funzione con gli opcode necessari alla FAR JMP e alla gestione dello stack nell'ordine necessario, scrivendoli all'indirizzo puntato dal vettore, come se si avesse a che fare con un buffer piuttosto che con una funzione. Come nel caso del buffer, deve poi incrementare il puntatore alla funzione (non il vettore, ma il puntatore con esso inizializzato) di 5 perché esso punti effettivamente all'inizio del codice eseguibile. Occorre però una buona conoscenza delle modalità di gestione dello stack e può tornare utile qualche occhiatina al sorgente assembler prodotto dal compilatore (opzione ­S). Forse, dopo tutto, è preferibile correre qualche rischio: se si lavora con attenzione, la probabilità che il vettore prescelto sia gia utilizzato è, in concreto, molto piccola.