/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Programmering af systemkald!!!
Fra : Preben Holm


Dato : 31-03-04 19:34

Hej alle

Jeg vil gerne have lavet et systemkald, dvs. et interrupt jo, men det
skal kaldes med nogle parametre.

Disse parametre har jeg som mange andre også gør valgt at lægge ind i
registrene, men nu er det altså også sådan, at jeg skal have
returværdier i registrene!

Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
det!


Mvh / Preben Holm

 
 
Bertel Brander (31-03-2004)
Kommentar
Fra : Bertel Brander


Dato : 31-03-04 19:29

Preben Holm wrote:
> Hej alle
>
> Jeg vil gerne have lavet et systemkald, dvs. et interrupt jo, men det
> skal kaldes med nogle parametre.
>
> Disse parametre har jeg som mange andre også gør valgt at lægge ind i
> registrene, men nu er det altså også sådan, at jeg skal have
> returværdier i registrene!
>
> Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
> tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
> det!

Hvem skal sætte parametrene op til din interrupt-funktion?
Hvem skal modtage din retur værdi?

Så vidt jeg kan se er det ikke muligt.


/b

Preben Holm (31-03-2004)
Kommentar
Fra : Preben Holm


Dato : 31-03-04 20:38

>> Jeg vil gerne have lavet et systemkald, dvs. et interrupt jo, men det
>> skal kaldes med nogle parametre.
>>
>> Disse parametre har jeg som mange andre også gør valgt at lægge ind i
>> registrene, men nu er det altså også sådan, at jeg skal have
>> returværdier i registrene!
>>
>> Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
>> tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal
>> gøre det!
>
>
> Hvem skal sætte parametrene op til din interrupt-funktion?
> Hvem skal modtage din retur værdi?
>
> Så vidt jeg kan se er det ikke muligt.

Selvfølgelig er det muligt - DOS interrupt 21h er et eksempel herpå -
spørgsmålet er bare hvordan det skal laves.

Well, vi er en gruppe på fire der skal lave et lille operativsystem til
en 186-cpu (40 MHz - wov!!), hvor vi skal schedulere nogle processer ind
og ud. Så det er disse processor der skal serviceres af dette interrupt.

Det er jo nemt at sætte registrene op så input er OK, men værre er det
med output..

Man kan jo self lægge en pointer til en klump data, men det at overskue
hvorledes, denne klump data skal håndteres er ikke helt så nem igen -
den metode har i hvert fald indtil nu kostet flere timers arbejde uden
nogen form for resultat fordi de skide pointere har drillet mere end så
rigeligt.

Anden metode ville være at modificere processens stack, men dette synes
jeg er en farlig måde at håndtere det på, hvis compileren laver nogen
former for register-optimering!



Mvh / Preben Holm

Bertel Brander (31-03-2004)
Kommentar
Fra : Bertel Brander


Dato : 31-03-04 20:02

Preben Holm wrote:
>
>
> Selvfølgelig er det muligt - DOS interrupt 21h er et eksempel herpå -
> spørgsmålet er bare hvordan det skal laves.

Så er det et SW interrupt og ikke et "rigtigt" interrupt.

>
> Well, vi er en gruppe på fire der skal lave et lille operativsystem til
> en 186-cpu (40 MHz - wov!!), hvor vi skal schedulere nogle processer ind
> og ud. Så det er disse processor der skal serviceres af dette interrupt.

Jeg kan ikke rigtigt se hvordan man kan schedulere processer vha.
interrupts på en 80186. 40 MHz er meget hurtigt for en 80186.

Hvilen kompiler bruger I? Hvilken memory model bruges? Hvilket interrupt
bruger I? Jeg kan måske se om jeg kan lave et eksempel senere.

/b

Preben Holm (01-04-2004)
Kommentar
Fra : Preben Holm


Dato : 01-04-04 21:41

>> Selvfølgelig er det muligt - DOS interrupt 21h er et eksempel herpå -
>> spørgsmålet er bare hvordan det skal laves.
>
> Så er det et SW interrupt og ikke et "rigtigt" interrupt.

Ja parameteroverførsel er jo ikke rigtig muligt ellers!
Hvorvidt det er et rigtigt interrupt tror jeg ikke jeg vil komme ind på!


>> Well, vi er en gruppe på fire der skal lave et lille operativsystem
>> til en 186-cpu (40 MHz - wov!!), hvor vi skal schedulere nogle
>> processer ind og ud. Så det er disse processor der skal serviceres af
>> dette interrupt.
>
>
> Jeg kan ikke rigtigt se hvordan man kan schedulere processer vha.
> interrupts på en 80186. 40 MHz er meget hurtigt for en 80186.

Ja, 40MHz er måske meget for den, men anyway, den har tre timere, hvoraf
Timer0 og 1 kan prescales af Timer2. Dem bruger vi til schedulering.
Desuden er der jo mulighed for frivillig schedulering.
Nu er det ikke lige scheduleringen der skal sende parametre rundt, men
f.eks. hvis vi nu skal lave et messagepassing system, så man altså skal
kunne modtage f.eks. en pointer til en bestemt "struct" som indeholder
data til den givne proces!

For interesserede kan I læse oplæg til projektet på:
http://old.iot.dk/mv/prc/ProjektOpl%E6g2004Alt2.pdf

> Hvilen kompiler bruger I? Hvilken memory model bruges? Hvilket interrupt
> bruger I? Jeg kan måske se om jeg kan lave et eksempel senere.

Vi bruger Borland's C++ 1.01, men programmerer i alm. C.

Jesper Louis Anderse~ (01-04-2004)
Kommentar
Fra : Jesper Louis Anderse~


Dato : 01-04-04 00:28

Bertel Brander <bertel@post4.tele.dk> wrote:
>
> S? vidt jeg kan se er det ikke muligt.
>

Og noget helt andet: Hvilken platform drejer det sig egentlig om?

--
j.

Ukendt (31-03-2004)
Kommentar
Fra : Ukendt


Dato : 31-03-04 22:16

Hej Preben.

> Jeg vil gerne have lavet et systemkald, dvs. et interrupt jo, men det
> skal kaldes med nogle parametre.
>
> Disse parametre har jeg som mange andre også gør valgt at lægge ind i
> registrene, men nu er det altså også sådan, at jeg skal have
> returværdier i registrene!
>
> Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
> tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
> det!

Du kan jo vælge at skrive en rutine i assembler og linke den ind således at
kaldeinterfacet kommer til at stemme både overfor dit OS og din compiler.

Mange compilere har mulighed for at bruge inline assembler eller med
specielle keywords at ændre på hvordan registre håndteres i en rutine.
Det kommer selvfølgeligt an på hvilken compiler du bruger.

Gamle versioner af Turbo C++ kan så vidt jeg kan huske hjælpe en meget på
dette område og kan også generere kode der er optimeret til 186. Det er blot
så længe siden jeg har brugt sådan en at jeg ikke kan huske det specifikke
og bøgerne er nok røget på dumpen for længe siden.

Hvad bruger i af værktøjer/udviklingsplatform ?

Med venlig hilsen
Jesper Wolf Jespersen



Ole Nielsby (31-03-2004)
Kommentar
Fra : Ole Nielsby


Dato : 31-03-04 22:42

Preben Holm <64bitNOSPAM@mailme.dk> skrev:

> Hej alle
>
> Jeg vil gerne have lavet et systemkald, dvs. et interrupt jo, men det
> skal kaldes med nogle parametre.
>
> Disse parametre har jeg som mange andre også gør valgt at lægge ind i
> registrene, men nu er det altså også sådan, at jeg skal have
> returværdier i registrene!
>
> Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
> tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
> det!

Du er nok nødt til at skrive assembler-wrappere omkring de interrupts
du skal bruge.

Start f.eks. med at lave en generisk interrupt.funktion der tager
indholdet af alle relevante registre samt en struct-pointer til output
som parametre.- Hvordan assemblerroutinen helt nøjagtig skal se
ud, afhænger af hvilken kaldekonvention c-compileren anvendes,
samt hvilke registre du har brug for. Vær opmærksom på at
kaldekonventionerne typisk forudsætter at nogle af registrene
bevares/restaureres (for win32-systemkald-konventionen drejer
det sig om registrene ebx, esi, edi og ebp; jeg vil gætte på at 16 bit
c-compileren understøtter en lignende konvention med bx, si, di og
bp. Det giver måske en lidt kompleks kaldesekvens hvor du først
skal stakke de registre der skal bevares, derefter udfylde registrene
fra længere oppe istakken, derefter udføre interruptet, derefter
gemme de registre der kan indeholde returværdier i den hertil
overførte struct, derefter restaurere de registre der skulle bevares
og returnere.

Skriv derefter - i C - specifikke wrappere for de interrupts du
skal bruge.

Skid på at koden i disse wrappere er klodset og tung.

Når du har fået det til at virke, så udskift wrapperne én efter
én med "lean & mean" assemblerkode.

ON/Fjern sneglen fra min svaradresse



Niels Dybdahl (01-04-2004)
Kommentar
Fra : Niels Dybdahl


Dato : 01-04-04 09:07

> Jeg vil gerne have lavet et systemkald, dvs. et interrupt jo, men det
> skal kaldes med nogle parametre.

Mange ældre C-compilere (16 bit til MS-DOS) har funktionskald til at kalde
software interrupts, hvor man får alle registre serveret i strukturer, både
indgående og udgående værdier. De kan ofte også lave C-funktioner som kan
bruges som interrupthandlere direkte.

Niels Dybdahl



Preben Holm (01-04-2004)
Kommentar
Fra : Preben Holm


Dato : 01-04-04 21:29

> Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
> tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
> det!

Ok, her er en tænkt løsning som jeg ikke ved om vil fungere:

struct regs {
   unsigned short ax,bx,cx,dx,si,di,flag;
}



struct callSys(struct regs* inreg, struct regs* outreg) {
   struct regs temp;
   temp.ax = _AX;
   temp.bx = _BX;
   temp.cx = _CX;
   temp.dx = _DX;
   temp.si = _SI;
   temp.di = _DI;
   temp.flag = _flag; //_flag <- findes det???


   _AX = inreg.ax;
   _BX = inreg.bx;
   _CX = inreg.cx;
   _DX = inreg.dx;
   _SI = inreg.si;
   _DI = inreg.di;
   _flag = inreg.flag;


   asm {
      int   80h;
   }


   outreg.ax = _AX;
   outreg.bx = _BX;
   outreg.cx = _CX;
   outreg.dx = _DX;
   outreg.si = _SI;
   outreg.di = _DI;
   outreg.flag = _flag; //_flag <- findes det???


   _AX = temp.ax;
   _BX = temp.bx;
   _CX = temp.cx;
   _DX = temp.dx;
   _SI = temp.si;
   _DI = temp.di;
   _flag = temp.flag;
}


dvs. hvis ov. defineres som funktion tilgængelig for processor kan vi
altså uden problemer kalde et systemkald og altså uden at ødelægge nogle
registre, hvis disse skulle være registeroptimeret.


I operativsystemet har jeg så tænkt lidt på flg.

der er defineret en tabel over forskelligt mulige systemkald, som er
funktioner der altså bliver kaldt fra systemkaldet installeret på
interrupt 80h.

Dvs. hvis disse funktioner nu får en lignende liste af registre:

int80-interrupt-procedure
   sysCallTable[_AH]();
;----



et systemkald:

sysCallMKMSG(struct regs * reg) {
   unsigned short ax,bx,cx,dx,si,di,flag;

   ax = _AX;
   bx = _BX;
   bx = _BX;
   bx = _BX;
   bx = _BX;
   bx = _BX;
}

Preben Holm (01-04-2004)
Kommentar
Fra : Preben Holm


Dato : 01-04-04 21:39

> Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
> tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
> det!

Ok, her er en tænkt løsning som jeg ikke ved om vil fungere:

struct regs {
   unsigned short ax,bx,cx,dx,si,di,flag;
}



struct callSys(struct regs* inreg, struct regs* outreg) {
   struct regs temp;
   temp.ax = _AX;
   temp.bx = _BX;
   temp.cx = _CX;
   temp.dx = _DX;
   temp.si = _SI;
   temp.di = _DI;
   temp.flag = _flag; //_flag <- findes det???


   _AX = inreg.ax;
   _BX = inreg.bx;
   _CX = inreg.cx;
   _DX = inreg.dx;
   _SI = inreg.si;
   _DI = inreg.di;
   _flag = inreg.flag;


   asm {
      int   80h;
   }


   outreg.ax = _AX;
   outreg.bx = _BX;
   outreg.cx = _CX;
   outreg.dx = _DX;
   outreg.si = _SI;
   outreg.di = _DI;
   outreg.flag = _flag;


   _AX = temp.ax;
   _BX = temp.bx;
   _CX = temp.cx;
   _DX = temp.dx;
   _SI = temp.si;
   _DI = temp.di;
   _flag = temp.flag;
}


dvs. hvis ov. defineres som funktion tilgængelig for processor kan vi
altså uden problemer kalde et systemkald og altså uden at ødelægge nogle
registre, hvis disse skulle være registeroptimeret.


I operativsystemet har jeg så tænkt lidt på flg.

der er defineret en tabel over forskelligt mulige systemkald, som er
funktioner der altså bliver kaldt fra systemkaldet installeret på
interrupt 80h.

Dvs. hvis disse funktioner nu får en lignende liste af registre:

int80-interrupt-procedure
   sysCallTable[_AH]();

   asm {
      mov   [BP+offsetAX],ax;
      mov   [BP+offsetBX],bx;
      ...
   }
;----



et systemkald:

sysCallMKMSG(struct regs * reg) {
   unsigned short ax,bx,cx,dx,si,di,flag;
   struct msg * retur;

   ax = _AX;
   bx = _BX;
   cx = _CX;
   dx = _DX;
   si = _SI;
   di = _DI;
   flag = _flag;

   retur = MK_FP(OS_SEGMENT_ADR, &messages[0]);
   retur->kdjfkdf = noget;
   osv.

   _AX = FP_SEG(retur);
   _BX = FP_OFF(retur);
   ...
}


//messages er en OS-variabel - giver det problemer? DS er jo stadig i
processen! messages er defineret som extern!



Vil ovenstående virke eller er det helt gak, gak at lave det på den måde...

Fortæl gerne din lange mening om tingene og foreslag til evt.
forbedringer, eventuelle problemer osv.


Vi bruger som sagt Borland Turbo C++ 1.01, men det er skrevet i ren C.

Kører small memory model!


På forhånd mange tak!!!

Mvh / Preben Holm

Niels Dybdahl (02-04-2004)
Kommentar
Fra : Niels Dybdahl


Dato : 02-04-04 08:50

> > Og da C automatisk push/pop'er alle registre, kan jeg jo ikke lagre
> > tingene i disse alligevel, men spørgsmålet er så hvorledes jeg skal gøre
> > det!
>
> Ok, her er en tænkt løsning som jeg ikke ved om vil fungere:
> ...
> Vi bruger som sagt Borland Turbo C++ 1.01, men det er skrevet i ren C.

Er du sikker på at den ikke allerede har sådanne funktioner ?
Jeg mindes at de hed noget i retning af "intr" eller "int86" eller lignende.

Niels Dybdahl



Preben Holm (02-04-2004)
Kommentar
Fra : Preben Holm


Dato : 02-04-04 11:58

>Er du sikker på at den ikke allerede
>har sådanne funktioner ?
>Jeg mindes at de hed noget i retning
>af "intr" eller "int86" eller lignende.

Jo, det er der da, men dem omprogrammerer vi gerne for
fleksibilitet og for at undgå unødig linkning.

Plads er meget tiltrængt og vi kan ikke bare inkludere dos.h, hvis
vi ikke ønsker at bruge alt i biblioteket - og jo, det er ikke
altid optimeret så godt som det kunne ønskes. Vores eksekverbare
er indtil videre på 1,2kB og skal helst holdes langt dernedad!
Vi har indtil nu schedulering og påbegyndende interproces
kommunikation oppe at køre, så udaf de 64 kB flash vi har til
rådighed er der ikke meget at tage af, når der også skal være
plads til TCP/IP implementering, webserver o.lign user-processer!


Byrial Jensen (02-04-2004)
Kommentar
Fra : Byrial Jensen


Dato : 02-04-04 20:56

Preben Holm wrote:
> Og da C automatisk push/pop'er alle registre,

Det gør C ikke. C kender intet til registre, men det er muligt at der
findes implementationer af C til bestemte platforme som gør det.


Preben Holm (03-04-2004)
Kommentar
Fra : Preben Holm


Dato : 03-04-04 11:45

>> Og da C automatisk push/pop'er alle registre,
>
>
> Det gør C ikke. C kender intet til registre, men det er muligt at der
> findes implementationer af C til bestemte platforme som gør det.

Nej ok, selve sproget C gør det ikke, men det gør compilere til x86 (og
andre) platforme - ellers kan der hurtigt gå noget galt i hvert fald!

Selvfølgelig sker det ikke hvis du arbejder på en RISC med bank-shifting
o.lign. teknologier, men ellers er det nødvendigt!



Mvh / Preben

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408921
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste