Beboer program

Et resident program (eller TSR-program , fra engelsk.  Terminate and Stay Resident  - "complete and remain resident") - i MS-DOS- operativsystemet , et program , der returnerede kontrol til operativsystemets shell ( command.com ) eller en tilføjelse til operativsystemet ( Norton Commander osv.), men forbliver i RAM'en på en personlig computer [1] . Et resident program aktiveres hver gang der opstår en afbrydelse , hvis vektor programmet har ændret til adressen på en af ​​dets procedurer .

Når man arbejdede med MS-DOS, blev residente programmer i vid udstrækning brugt til at nå forskellige mål (for eksempel tastaturcrackere , LAN - adgangsprogrammer , forsinkede printmanagere , vira ).

Ved hjælp af initialisering og aktivering af operativsystemet skal residente programmer skelnes fra "rigtige" MS-DOS- drivere , som er indlejret af operativsystemet i dets kerne ved opstart.

I en tid med multitasking OS kaldes programmer, der konstant indlæses og kører i baggrunden, nogle gange for residente programmer. Men brugen af ​​dette udtryk er forkert i forhold til multitasking OS.

Grundlæggende begreber

Resident-programmer kan overtage håndteringen af ​​afbrydelser, for eksempel dem, der er forbundet med udskrivning eller adgang til tastaturet mv.

Sådanne programmer blev normalt kørt gennem filen AUTOEXEC.BAT eller direkte. De opsnappede interrupts designet til at fungere med tastaturet. Så snart brugeren trykker på en foruddefineret tastekombination, aktiveres beboerprogrammet. En dialogboks for det residente program vises oven på billedet på skærmen.

Nogle gange bruges residente programmer i stedet for downloadbare drivere til at servicere ikke-standard hardware. I dette tilfælde kan det residente program indlejre sin egen handler, hvorigennem alle applikationsprogrammer kan få adgang til hardwaren.

De residente moduler i nogle databasestyringssystemer ( DBMS ) fungerer på samme måde. Applikationsprogrammet sender forespørgsler til databasen gennem et interrupt, der indstilles ved start af et sådant DBMS.

Adskillige begrænsninger er pålagt residente programmer, der gør det svært for en programmør at arbejde.

For eksempel må TSR'er ikke bruge MS-DOS-afbrydelser efter behag. Dette skyldes, at MS-DOS blev designet fra starten som et enkelt-opgave operativsystem, så MS-DOS afbrydelsesfunktioner er ikke reentrant.

Lad os forestille os en sådan situation.

Antag, at et normalt program kaldet en eller anden MS-DOS-afbrydelsesfunktion, som tager relativt lang tid at fuldføre (f.eks. skrivning til disk).

Da brugeren til enhver tid kan aktivere beboerprogrammet, med mindre der tages særlige forholdsregler, er det muligt at kalde den samme funktion op igen, hvis behandling endnu ikke er afsluttet. I dette tilfælde vil vi få et MS-DOS-funktionscallback, som er ugyldigt på grund af, at MS-DOS-funktioner ikke er reentrant.

BIOS- funktioner er heller ikke alle reentrant . Et resident program kan roligt kun kalde INT 16h interrupt (som er designet til at fungere med tastaturet). Hvis beboerprogrammet skal vise noget på skærmen, så skal du i stedet for at afbryde INT 10h skrive tegnene og deres attributter direkte til videohukommelsen.

Uden at tage særlige forholdsregler kan et resident program ikke kalde mange funktioner i oversætterbiblioteket, da sidstnævnte forårsager MS-DOS-afbrydelser. For eksempel forårsager malloc - funktionen en MS-DOS-afbrydelse for at bestemme mængden af ​​ledig hukommelse i systemet.

Et program har to muligheder for at forblive i hukommelsen - brug INT 27h interrupt eller INT 21h interrupt funktionen 31h.

For at bruge INT 27h afbrydelsen skal CS segmentregisteret pege på programmets PSP. I dette tilfælde skal forskydningen af ​​programmets sidste byte plus en byte skrives til DX-registret.

Det er let at se, at denne metode er mest velegnet til com-programmer, da det ved brug af INT 27h interrupt er umuligt at efterlade et resident program længere end 64 KB i hukommelsen.

En anden, mere bekvem måde er at kalde afbrydelsesfunktionen 31h INT 21h . AL-registret bør indeholde programafslutningskoden, DX-registret bør indeholde længden af ​​den residente del af programmet i afsnit. Der er ikke længere ovenstående begrænsning på programmets størrelse.

For at lade et program blive boende i hukommelsen, hvis størrelse overstiger 64 KB, kan du kun bruge den sidste metode. Du bør ikke lade dig rive med af store residente programmer, da den hukommelse, de optager, er nødvendig for andre programmer.

Opbygning af beboerprogrammet

Først lagres data i hukommelsen, derefter interrupt-handlere (vektorer) og til sidst initialiseringssektionen (som har et INIT-indgangspunkt, og det er på dette tidspunkt, at kontrollen overføres, når programmet starter). Hovedopgaven for initialiseringssektionen er at etablere en beboer i hukommelsen (det er kun nødvendigt, når du installerer programmet, så fjernes det fra hukommelsen). Denne sektion er placeret i de højere adresser (da vi kun kan "afskære" de højere adresser).

Funktionerne i initialiseringssektionen er som følger

  1. Interrupt-vektorer opfanges (indstiller deres handlere).
  2. Programmet slutter på en sådan måde, at kun beboerdelen forbliver i hukommelsen.
  3. Overførsel af parametre til at afbryde handlere - ISR. Værdierne af disse parametre placeres i beboerdataområdet (parameteren kan være en "hot"-tast til at kalde beboeren).
  4. Løsningen på problemet med at genstarte TSR'en (ikke at multiplicere kopier af TSR'en i hukommelsen), dvs. initialiseringssektionen skal afgøre, om der er et program i hukommelsen eller ej.
  5. Fjernelse af en beboer fra hukommelsen. For det første skal du gendanne de gamle interrupt-vektorer (fra datasektionen), og for det andet fjerne TSR-miljøet og PSP TSR.
  6. Funktion til at minimere hukommelsen optaget af beboeren.

Initialisering af beboerprogrammet

For at bruge interrupt 27h skal segmentregistret CS pege på programmets PSP, og offset af programmets sidste byte plus en byte skal skrives til DX-registret. Det er let at se, at denne måde at blive boende på er mest velegnet til programmer i COM-formatet. Du kan ikke forlade et resident program, der er længere end 64 kilobyte.

En anden, mere bekvem måde er at bruge INT 21h afbrydelsesfunktionen 31h. I AL-registret kan du angive programafslutningskoden, DX-registret skal i dette tilfælde indeholde længden af ​​den residente del af programmet i afsnit. Der er ikke længere en grænse på 64 kilobyte på programmets længde. Brug af denne funktion er den eneste måde at forlade et fast program, der er længere end 64 kilobyte.

Men du bør ikke lade dig rive med af lange TSR-programmer, da normalt den eneste måde at frigøre den hukommelse, der er optaget af et allerede unødvendigt resident program, er ved at genstarte operativsystemet.

Quick C-funktionsbiblioteket indeholder en speciel funktion til at efterlade et program i hukommelsen. Denne funktion bruger INT 21h (funktion 31h) og hedder _dos_keep(). Funktionens første parameter er udgangskoden (hvad der skrives til AL-registret), og den anden er længden af ​​den residente del af programmet i afsnit.

Løsning af genstartsproblemet

Det er nødvendigt at afgøre, om TSR allerede er startet eller ej. Der er flere muligheder for at bestemme starten af ​​TSR:

MOVAX,2ABCh INT2Fh CMP AL,0FFh; hvis lig, så er der en kopi, ellers er der ingen kopi.

Fordele: Bred brug. Ulempe: signatursættet er ret begrænset (signaturen kan ved et uheld matche). Reliabiliteten er mindre end den 2. metode.

Interaktion mellem nye og gamle interrupt-handlere (ISR'er)

Når et resident program er installeret i hukommelsen, opfanges vektorer. I dette tilfælde er følgende interaktionsskemaer mulige mellem de gamle og nye interrupt-handlere:

Returneringen er fra den gamle handler. Der er en kæde mellem interrupt-handlere. Ulempe: Det er ofte nødvendigt, at nye funktioner udføres efter gamle. Denne ordning er ikke mulig.

TSR kompleksitetsniveauer og hvordan nye ISR'er interagerer med hinanden

Afhængigt af samspillet mellem nye ISR'er skelnes der mellem forskellige niveauer af kompleksitet.

Hvis du ser på BIOS-funktionerne, mens de kører, vil du bemærke, at de ikke er reentrant, dette henviser til funktionerne ved at arbejde med disken INT 13 og skærmen INT 10. Reentrance er en egenskab, der tillader et program eller et fragment af den skal afbrydes og udføres med startet (igen). Det vil sige, at programmet kan afbryde sig selv. At. BIOS-funktioner er ikke-reentrant. Klassisk skal du skrive en ny INT 13 handler. Lad den residente funktion kaldes når der trykkes på en tast, så skal du bruge INT 9 keyboard interrupt handler, som skal tjekke flaget: disken behandles eller ej . Hvis flaget er nul, så kan vores RF-program (som fungerer med INT 13) kaldes. Beskyttelse er kun lavet mod INT 13 interrupt, da resten af ​​interrupts bruger DOS funktioner.

Det er programmer, hvor residentfunktionen bruger DOS-funktioner (f.eks. RF bruger INT 21). INT 21 er ikke genindtrædende. Det ville være muligt at løse dette problem på samme måde som med INT 13. Men denne metode virker ikke, da DOS-funktioner ikke altid har standardterminering (der er nogle udgange, der ikke kan styres). Disse funktioner inkluderer 4C og 4B. OC'en har et specielt flag kaldet DOS-aktivitetsflaget, som kaldes INDOS. Dette flag er 0, hvis INT 21 ikke udføres, og ikke 0, hvis det er det. At. i programmet er det nødvendigt at analysere INDOS. Der er en standard funktion til at få INDOS flag, dette er AH=34h af int 21 interrupt. Denne funktion resulterer i ES:BX -> inDOS. Denne funktion skal udføres 34 timer i initialiseringssektionen. Skal rette adressen på dette INDOS-flag i en statisk hukommelsesplacering og derefter bruge den i interrupt-handlere.

Når 1. gruppe udføres, er det muligt at udføre en anden gruppes funktioner, men ikke den første, og omvendt. For at løse problemet med at starte en resident funktion på tidspunktet for udførelse af 1. gruppefunktioner, bruges en speciel interrupt INT 28. Brugeren kan opsnappe INT 28 vektoren og udføre passende handlinger (fra 2. gruppe). Lad fx vores beboerfunktion kun bruge den 2. gruppe af funktioner. Hvis DOS er aktiv, kalder TSR kun INT 28, og hvis den ikke er aktiv, forårsager den kun afbrydelser fra timeren. Skærmoutput kan udføres direkte til skærmens RAM (omgå DOS og BIOS). For at arbejde med tastaturet skal du bruge BIOS-funktionerne. For at arbejde med skærm og tastatur bruges funktionerne i 2. gruppe, men skærm og tastatur betragtes som en CON-enhed, og arbejdet med det udføres som med en fil.

Se også

Noter

  1. © Alexander Frolov, Grigory Frolov. MS-DOS til programmøren . frolov-lib . Hentet 9. maj 2022. Arkiveret fra originalen 1. december 2020.