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