[1] Circa la ricorsione vedere il paragrafo dedicato.

[2] Vogliamo proprio essere precisi? Il DOS gestisce tre stack interni, ciascuno dei quali è costituito da un'area di memoria di circa 200 byte (non si tratta, dunque, di stack nel senso letterale del termine, bensì di buffer statici). Il primo e il secondo sono utilizzati dall'int 21h, per le funzioni 00h­0Ch e, rispettivamente, per tutte quelle restanti; il terzo è usato dall'int 24h nelle situazioni di errore critico.

[3] In particolare, per quanto riguarda l'InDOS flag, va osservato che quando esso non è nullo un servizio DOS è in corso di esecuzione, pertanto i TSR non devono utilizzare alcun servizio dell'int 21h, al fine di evitare la distruzione del contenuto dello stack del DOS. Controllando lo stato del flag, un TSR è in grado di determinare quando è possibile invocare funzioni DOS senza pericolo di compromettere lo stato del sistema. Tuttavia esiste una complicazione: l'interprete di comandi COMMAND.COM ed alcuni altri programmi trascorrono gran parte del tempo in attesa di input dalla tastiera mediante la funzione 0Ah (GetString) dell'int 21h: l'InDOS flag, in tale circostanza, è non­nullo. E' possibile aggirare il problema intercettando l'int 28h, chiamato in loop dai servizi 00h­0Ch, oppure dotando il TSR di un gestore dell'int 21h in grado di intercettare le chiamate alla funzione 0Ah nel modo seguente:

1)Non invocare il servizio 0Ah immediatamente; eseguire invece un loop costituito da un ritardo seguito da una chiamata al servizio 0Bh dell'int 21h (GetInputStatus).
2)Continuare ad eseguire il loop sino a quando non venga segnalato (dal servizio 0Bh) che un tasto è pronto nel buffer della tastiera.
3)Solo a questo punto eseguire la chiamata alla funzione 0Ah: per tutto il tempo in cui viene eseguito e rieseguito il loop, il TSR può utilizzare i servizi DOS liberamente.


[4] Codice del file IBMDOS.COM (o MSDOS.SYS). Chi desiderasse complicarsi la vita, potrebbe ricercare una sequenza simile, invece di decrementare l'offset dell'indirizzo dell'InDOS flag, anche nelle versioni di DOS dalla 3.1 in poi:

test ss:[NearByte],0FFH
jne  NearLabel
push ss:[NearWord]
int  28H

[5] Responsabile è la _restorezero(), routine non documentata di servizio della keep(). La _restorezero() provvede anche a ripristinare i vettori degli int 00h, 04h e 06h, per i quali valgono dunque le affermazioni riguardanti l'int 05h.

[6] Il cast è (void(interrupt *)()).

[7] Si ricordi che il compilatore Borland C++ genera le istruzioni necessarie alla gestione di BP ed SP anche nelle funzioni dichiarate void funzione(void), mentre ciò non avviene con il compilatore TURBO C 2.0. Utilizzando quest'ultimo è quindi indispensabile eliminare l'istruzione POP BP che precede la IRET. A complicare ulteriormente le cose giunge il fatto che il modello huge salva DS sullo stack in ingresso alla funzione e lo ripristina in uscita: occorre tenerne conto se si compila il TSR con detto modello di memoria.

[8] Forse è opportuno spendere qualche parola sulle modalità di gestione, realizzata attraverso quattro puntatori, del buffer della tastiera. Il suo indirizzo nella RAM è dato dal puntatore all'inizio: questo e il puntatore al byte successivo alla fine ne segnano dunque i confini. Il buffer è inoltre scandito da altri due puntatori, dei quali il primo (puntatore alla testa) indica la posizione del primo tasto estratto dal buffer stesso, mentre il secondo (puntatore alla coda) indica l'indirizzo al quale è "parcheggiato" il successivo tasto premuto (cioè i suoi codici di scansione e ASCII). Quando deve essere inserito un tasto nel buffer, il puntatore alla coda viene incrementato; se il suo valore supera quello del puntatore alla fine viene "riavvolto" al valore del puntatore all'inizio. Se, a seguito di questo algoritmo, esso eguaglia il puntatore alla testa si verifica la condizione di buffer pieno: il puntatore è decrementato. Si noti che in questo caso il tasto è regolarmente inserito all'indirizzo indicato dal puntatore alla coda prima dell'incremento, ma viene ignorato: il buffer di tastiera può pertanto "trattare" un tasto in meno rispetto a quanto consentito dallo spazio allocato (normalmente 15 battute, ciascuna delle quali impegna una word dei 32 byte disponibili). Quando invece deve essere letto un tasto dal buffer, è incrementato il puntatore alla testa: se esso eguaglia il puntatore alla coda, allora il buffer è vuoto. Un'ultima precisazione: i quattro puntatori esprimono offset rispetto all'indirizzo di segmento 400h.

[9] I valori da 00h7Fh sono riservati al DOS (PRINT usa AH = 01h, ASSIGN usa AH = 02h, SHARE usa AH = 10h); le applicazioni possono dunque utilizzare uno qualsiasi dei valori restanti (80h­FFh).

[10] Inoltre, una word (anziché un byte) consente di esprimere un maggior numero di combinazioni: il gestore dell'int 2Fh potrebbe utilizzare altri registri per effettuare il controllo (ad esempio BX, o qualunque altro registro non utilizzato da altri servizi dello stesso interrupt), per diminuire la probabilità di conflitto con altre applicazioni. L'algoritmo qui descritto è, come si è detto, quello consigliato da Microsoft (e, pertanto, ufficiale), ma attualmente non esistono motivi di carattere tecnico che impediscano al programmatore di utilizzare metodi alternativi.

[11] L'ordine dei parametri formali, lo ripetiamo, è rigido. Per il compilatore Borland esso è: BP, DI, SI, DS, ES, DX, CX, BX, AX, IP, CS, FLAGS, seguiti da eventuali parametri definiti dal programmatore. Non è necessario dichiarare tutti i parametri elencati; è però della massima importanza che la dichiarazione abbia inizio dal primo registro (BP) e includa tutti i registri referenziati nel codice della funzione, senza escludere quelli in posizione intermedia eventualmente non utilizzati.