Prefisso segmento di programma - Program Segment Prefix

Il Program Segment Prefix (PSP) è una struttura dati utilizzata nei sistemi DOS per memorizzare lo stato di un programma . Assomiglia alla Zero Page nel sistema operativo CP/M . Il PSP ha la seguente struttura:

Immagini offset Taglia Contenuti
00h-01h 2 byte (codice) Uscita simile a CP/M-80 (contiene sempre INT 20h )
02h-03h parola (2 byte) Segmento del primo byte oltre la memoria allocata al programma
04h byte Riservato
05:00-09:00 5 byte (codice) Immissione chiamata remota simile a CP/M-80 in DOS e dimensione del segmento di programma
0Ah-0Dh dword (4 byte) Termina indirizzo del programma precedente (vecchio INT 22h )
0Eh-11h dword Indirizzo di pausa del programma precedente (vecchio INT 23h )
12h-15h dword Indirizzo errore critico del programma precedente (vecchio INT 24h )
16h-17h parola Segmento PSP del genitore (di solito COMMAND.COM - interno)
18h-2Bh 20 byte Tabella file lavoro (JFT) (interna)
2Ch-2Dh parola Segmento ambiente
2Eh-31h dword SS:SP in ingresso all'ultima chiamata INT 21h (interna)
32h-33h parola Dimensione JFT (interna)
34h-37h dword Puntatore a JFT (interno)
38h-3Bh dword Puntatore alla PSP precedente (usato solo da SHARE in DOS 3.3 e versioni successive)
3Ch-3Fh 4 byte Riservato
40h-41h parola Versione DOS da restituire (DOS 4 e successivi, modificabile tramite SETVER in DOS 5 e successivi)
42h-4Fh 14 byte Riservato
50h-52h 3 byte (codice) Voce di chiamata remota simile a Unix in DOS (contiene sempre INT 21h + RETF)
53h-54h 2 byte Riservato
55h-5Bh 7 byte Riservato (può essere utilizzato per trasformare il primo FCB in un FCB esteso)
5Ch-6Bh 16 byte FCB standard non aperto 1
6Ch-7Fh 20 byte FCB standard 2 non aperto (sovrascritto se FCB 1 è aperto)
80 ore 1 byte Numero di byte sulla riga di comando
81h-FFh 127 byte Coda della riga di comando (terminata da 0Dh )

La PSP viene spesso utilizzata per ottenere gli argomenti della riga di comando di un programma DOS; ad esempio, il comando "FOO.EXE /A /F" esegue FOO.EXE con gli argomenti '/A' e '/F'.

Se la voce PSP per la lunghezza della riga di comando è diversa da zero e il puntatore al segmento di ambiente non è né 0000h né FFFFh, i programmi dovrebbero prima provare a recuperare la riga di comando dalla variabile di ambiente %CMDLINE% prima di estrarla dalla PSP. In questo modo, è possibile passare righe di comando più lunghe di 126 caratteri alle applicazioni.

L'indirizzo del segmento della PSP viene passato nel registro DS quando il programma viene eseguito. Può anche essere determinato in un secondo momento utilizzando la funzione Int 21h 51h o la funzione Int 21h 62h. Entrambe le funzioni restituiranno l'indirizzo PSP nel registro BX.

In alternativa, nei programmi .COM caricati in offset 100h, è possibile indirizzare direttamente la PSP semplicemente utilizzando gli offset elencati sopra. L'offset 000hpunta all'inizio della PSP, 0FFhpunta alla fine, ecc.

Ad esempio, il codice seguente visualizza gli argomenti della riga di comando:

org   100h      ; .COM - not using ds

; INT 21h subfunction 9 requires '$' to terminate string
xor   bx,bx
mov   bl,[80h]
cmp   bl,7Eh
 ja   exit      ; preventing overflow

mov   byte [bx+81h],'$'

; print the string
mov   ah,9
mov   dx,81h
int   21h

exit:
mov   ax,4C00h  ; subfunction 4C
int   21h

In DOS 1.x, era necessario che il registro CS (Code Segment) contenesse lo stesso segmento della PSP alla fine del programma, quindi la pratica di programmazione standard prevedeva il salvataggio del registro DS nello stack all'avvio del programma (poiché il registro DS è caricato con il segmento PSP) e terminando il programma con un'istruzione RETF, che farebbe uscire dallo stack il valore del segmento salvato e salterebbe all'indirizzo 0 della PSP, che conteneva un'istruzione INT 20h.

; save
push  ds
xor   ax,ax
push  ax

; move to the default data group (@data)
mov   ax,@data
mov   ds,ax

; print message in mess1 (21h subfunction 9)
mov   dx,mess1
mov   ah,9
int   21h

retf

Se l'eseguibile era un file .COM, questa procedura non era necessaria e il programma poteva essere terminato semplicemente con un'istruzione INT 20h diretta oppure chiamando INT 21h Funzione 0. Tuttavia, il programmatore doveva comunque assicurarsi che il registro CS contenesse l'indirizzo del segmento della PSP al termine del programma. Così,

jmp   start

mess1 db 'Hello world!$'

start:
mov   dx,mess1
mov   ah,9
int   21h

int   20h

In DOS 2.x e versioni successive, la terminazione del programma è stata eseguita invece con INT 21h Function 4Ch che non richiedeva che il registro CS contenesse il valore del segmento della PSP.

Guarda anche

Riferimenti

Ulteriori letture

link esterno