[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.
[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.
[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.