1 / 25

11. přednáška 17. 4. 2008 - výstupy na monitor (16 bitové prostředí)

11. přednáška 17. 4. 2008 - výstupy na monitor (16 bitové prostředí) - kombinace jazyka C a assembleru ovládání přerušení Obsah přednášky se týká šestnáctibitového prostředí Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/. Výstupy na monitor. Textový režim

thora
Download Presentation

11. přednáška 17. 4. 2008 - výstupy na monitor (16 bitové prostředí)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 11. přednáška • 17. 4. 2008 • - výstupy na monitor(16 bitové prostředí) • - kombinace jazyka C a assembleru • ovládání přerušení • Obsah přednášky se týká šestnáctibitového prostředí • Studijní materiály najdete na adrese: • http://www.uai.fme.vutbr.cz/~vdumek/

  2. Výstupy na monitor Textový režim - printf() - nelze ovládat atributy znaků, polohu kurzoru, ovládání pouze v omezené míře pomocí ESC-sekvencí. Používají se funkce, které mají prototypy v conio.h. Adresování pozice kurzoru je v rámci obrazovky [1,1] až [80,25], pokud se jedná o výstup do okna (window), má levý horní roh opět souřadnice [1,1]. Specifikace okna: void window(int x1, int y1, int x2, int y2) Po spuštění programu (nastavení textového režimu) je jako okno definována celá obrazovka: window(1, 1, 80, 25) Nastavení polohy kurzoru: void gotoxy(int x, int y); - souřadnice jsou relativní vzhledem k oknu Výmaz okna (barvou pozadí): void clrscr(void)

  3. Výstupy na monitor K nastavení barev popředí a pozadí se používají funkce: void textcolor(int barva) 0 - 15 void textbackground(int barva) 0 - 7, (8 - 15 stejné barvy jako 0 - 7, znak bliká) void textattr(int atribut) popředí i pozadí najednou,atribut = popredi+(16 *pozadi) K výstupu textu se zohledněním okna, pozice a atributu: cprintf(const char *form[, arg, ...])

  4. Výstupy na monitor Pro uschování a obnovení obrazovky, nebo její části: int gettext(int x1, int y1, int x2, int y2, void *buffer) souřadnice jsou vždy absolutní (bez ohledu na poslední volání window), buffer je směrník na dynamicky alokovanou paměť (počet znaků * 2), návratová hodnota 0 - neúspěch, 1 - úspěch int puttext(int x1, int y1, int x2, int y2, void *buffer) K nastavení různých režimů adapteru lze použít volání přerušení 10H, je možný i přímý zápis do VRAM.

  5. Výstupy na monitor Grafický režim - pro práci v grafickém režimu je k dispozici rozsáhlý repertoár funkcí, využívá se modulů BGI, které jsou závislé na typu adaptéru, k detekci adaptéru lze využít konstantu DETECT. Prototypy grafických funkcí jsou umístěny v hlavičkovém souboru graphics.h (všechny funkce jsou volané jako far, všechny směrníky jsou také far, je proto výhodné pracovat s některým z velkých paměťových modelů. 

  6. Výstupy na monitor Nastavení a uzavření grafického režimu void far initgraph(int far *driver, int far *mode, char far *cesta); Pokud je driver zjištěn pomocí DETECT, nastaví se automaticky i mód a to na nejkvalitnější zobrazení, jakého je adapter schopen, parametr cesta udává umístění BGI modulu. void far closegraph(void);

  7. Výstupy na monitor Souřadný systém na obrazovce: [0,0] až int far getmaxx(void), int far getmaxy(void) Grafické okno se nazývá viewport: void far setviewport(int x1, int y1, int x2, int y2, int clip) Nenulová hodnota clip udává, že všechny výstupní operace budou ořezávány na hranicích nastavené oblasti. Pro přebarvení okna barvou pozadí: void far clearviewport(void)

  8. Výstupy na monitor Nastavení barvy popředí a pozadí: void far setcolor(int barva) void far setbkcolor(int barva) Pro barvy platí stejné symbolické označení, jako pro textový režim (conio.h). Pro výstup textu v grafickém režimu: void far outtextxy(int x, int y, char far *text) Souřadnice x, y jsou v pixelech. Mimo bodů udávajících znak nejsou žádné jiné body ošetřovány, takže přemazání je potřeba řešit ve vlastní režii, u znaku mezera se udaná pozice přeskočí. Úschova a obnovení části obrazovky v grafickém režimu:

  9. Výstupy na monitor void far getimage(int x1, int y1, int x2, int y2, void far *buffer) void far putimage(int x1, int y1, void far *buffer, int operace) buffer- musí ukazovat na oblast paměti dostatečně velkou pro uložení definované části obrazovky, operace určuje způsob vkopírování obrazce na obrazovku (je možné provádět bitové logické operace s body vkládanými a stávajícími: Symbolické vyjádřeníVýznam COPY_PUTprosté kopírování XOR_PUTexclusive or - výhradní součet OR_PUTlogický součet AND_PUTlogický součin NOT_PUTnegace původního obrazu Velikost potřebné paměti pro uložení okna je závislá nejen na velikosti okna, ale i na použitém adapteru (dochází k zaokrouhlování na celé osmice bodů), takže se doporučuje používat funkce: unsigned far imagesize(int x1, int y1, int x2, int y2);

  10. Výstupy na monitor Pro kreslení vyplňovaných obrazců je nutné nastavit způsob a barvu vyplnění: void far setfillstyle(int vypln, int barva); Hodnoty pro parametr vypln: NázevHodnotaPopis EMPTY_FILL0barvou pozadí SOLID_FILL1barva popředí LINE_FILL2---------------- LTSLASH_FILL3//////// WIDE_DOT_FILL10......... USER_FILL12Uživatelsky definováno

  11. Výstupy na monitor Vykreslení pravoúhlého čtyřúhelníku, vyplněného a vybarveného podle nastavení daného posledním voláním setfilestyle(). V grafickém režimu není na obrazovce kurzor, je však definována pozice tzv. grafického ukazatelu (current position - cp). K nastavení se používá: void far moveto(int x, int y) - absolutní posuv void far moverel(int x, int y) - relativní posuv (např. propoužití outtext, která nemá udány souřadnice) void far lineto(int x, int y) - přímka z cp do udaného bodu void far linerel( int dx, int dy) - parametry udávají relativní pozici vůči cp void far line(int x1, int y1, int x2, int y2)

  12. Kombinace jazyka C a assembleru - mixed language programming, nejčastější kombinace vyššího programovacího jazyka a assembleru, efektivita vyššího programovacího jazyka spolu s rychlostí (přímé dosažení technického vybavení) assembleru - ve většině případů stačí výrazové schopnosti jazyka C (systémové programování) - tři možnosti kombinace jazyků: * hlavní program v assembleru, funkce v jazyku C volány pomocí instrukce CALL * hlavní program vytvořen v jazyku C, volají se funkce vytvořené v assembleru * celý program je v jazyku C, některé sekvence jsou v assembleru - parametry se ukládají do zásobníku v opačném pořadí, než jsou uvedeny v seznamu parametrů při volání, parametr v zásobníku obsazuje vždy sudý počet bytů char 2 B (významný je nižší byte) float 4 B int 2 B near pointer 2 B long 4 B far pointer 4 B (první segment, druhý offset)

  13. Kombinace jazyka C a assembleru - podprogram nechává parametry v zásobníku, zásobník uvolňuje volající modul po návratu z podprogramu (funkce), návratová hodnota se ukládá do registrů - pro funkce v assembleru se uvádí prototyp s třídou extern extern int ASMFCE(int, char near *) extern "C" int ASMFCE(int, char near *) - pro C++ 16 bitů (int, near pointer) ax 8 bitů (char) al 32 bitů (long, far pointer) dx (vyšší slovo, segment) ax (nižší slovo, offset) float, double TOS - koprocesor Deklarace procedury PUBLIC _ASMFCE _ASMFCE PROC FAR … (kód procedury) _ASMFCE ENDP - pro vstupní body v assembleru se používají direktivy PROC, ENDP, jméno musí být deklarováno jako PUBLIC, v kódu C se funkce uvádí velkými písmeny, kompilátor C generuje na začátku každé funkce znak _, nelze mít jednu verzi funkce pro všechny modely

  14. Kombinace jazyka C a assembleru Moduly v assembleru by měly zachovávat konvence podle paměťového modelu hlavního programu. <code> SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:<code>, DS:<dseg> … (kód programu) <code> ENDS <dseg> GROUP _DATA, _BSS <data> SEGMENT WORD PUBLIC 'DATA' … (inicializovaná data) <data> ENDS _BSS SEGMENT WORD PUBLIC 'DSS' … (neinicializovaná data) _BSS ENDS END <data>, <code> a <dseg> jsou jména závislá na použitém paměťovém modelu.

  15. Kombinace jazyka C a assembleru Model <code> <data> <dseg> TINY, SMALL _TEXT _DATA DGROUP COMPACT _TEXT _DATA DGROUP MEDIUM filename_TEXT _DATA DGROUP LARGE filename_TEXT _DATA DGROUP HUGE filename_TEXT filename_DATA filename znamená, že odpovídající jméno je modifikováno jménem zdrojového souboru (XYZ.ASM=> XYZ_TEXT). - podprogram nesmí změnit obsah registru BP, SI, DI (třída uložení register) - parametry jsou v zásobníku, za nimi je uložena návratová adresa, pro near volání 1 byte, pro far volání 2 byty, relativní uložení parametrů je proto závislé na paměťovém modelu - hodnota BP se ukládá do zásobníku, potom se používá pro přístup k parametrům, BP se používá místo SP proto, že v podprogramu můžeme pracovat se zásobníkem, čímž se mění hodnota vrcholu zásobníku a tím i relativní poloha parametrů vzhledem k tomuto vrcholu

  16. uschovaný bp návratová adresa začátek parametrů Kombinace jazyka C a assembleru - klasická úvodní sekvence push bp ;uložení hodnoty bp do zásobníku mov bp, sp ;v bp ukazatel na vrchol zásobníku - pro vyšší přehlednost se definují symbolická jména pro jednotlivé parametry, jsou zde zohledněny i datové typy parametrů ss : [bp] ss : [bp + 2] ss : [bp + 4] ss : [bp + 6] - deklarovaná funkce pro model LARGE, uložená v souboru FCE1.ASM void extern ASMFCE1(int x, char y, struct ppp *z);

  17. FCE1_TEXT SEGMENT BYTE PUBLIC ASSUME CS:FCE1_TEXT PUBLIC _ASMFCE1 x EQU WORD PTR [BP+6] y EQU BYTE PTR [BP+8] z EQU DWORD PTR [BP+10] _ASMFCE1 PROC FAR ; push bp ;ulozeni puvodni hodnoty bp mov bp, sp ;do bp hodnota pro ;spravny vyber parametru … mov ax, x ;parametr x do ax mov bl, y ;parametr y do bl lds si, z ;ds:si je adresa struktury ppp mov bx, ds:[si];prvni slovo struktury do bx … pop bp ;obnoveni hodnoty bp ret ;navrat do volajiciho modulu _ASMFCE1 ENDP ;konec funkce FCE1_TEXT ENDS ;konec segmentu funkce END ;konec modulu FCE1.ASM

  18. Kombinace jazyka C a assembleru - překladače assembleru poskytují direktivy pro přehlednější zápis programů v assembleru .MODEL;TINY, SMALL, MEDIUM, COMPACT, … .CODE ;kód programu .DATA ;inicializovaná data .DATA? ;neinicializovaná data - segment zahájený některou z direktiv končí definicí jiného segmentu nebo koncem modulu - pro typy parametrů: BYTE 1 B WORD 2 B DWORD 4 B QWORD 8 B TBYTE 10 B - formát deklarace: jmproc PROC jazyk paměťjmpar1:typ1, jmpar2:typ2, … jmproc jméno programu jazyk určení programovacího jazyka, ze kterého voláme paměť NEAR nebo FAR jmpar jméno parametru typ typ parametru

  19. Zápis předchozího příkladu s použitím direktiv .MODEL LARGE PUBLIC C _ASMFCE1 ASMFCE1PROC C FAR x : WORD, y : BYTE, z : DWORD ; … mov ax, x ;parametr x do ax mov bl, y ;parametr y do bl lds si, z ;ds:si je adresa struktury ppp mov bx, ds:[si];prvni slovo struktury do bx … ret ;navrat do volajiciho modulu ASMFCE1 ENDP ;konec funkce END ;konec modulu FCE1.ASM

  20. Kombinace jazyka C a assembleru - metoda inline assembly - zařazení kódu v assembleru přímo do zdrojového modulu v jazyce C, pro případ kdy rozsah assembleru je malý a nevyplácí se použít běžný mechanismus asm jméno_instrukce operandy; - místo znaku ; lze použít <CR>, jeden řádek může obsahovat i více příkazů asm, příkaz asm nesmí přesahovat rozsah jedné řádky int minim(int a, int b) { asm { mov ax, a cmp ax, b jle konec mov ax, b } konec: printf("v reg. ax je hodnota: %d\n", _AX); asm ADC ax, 10 return _AX; } #include <stdio.h> int minim(int, int); void main(void) { int p=5, r=2, q; q=minim(p, r); printf("modif. hodnota je: %d\n", q); } v reg. ax je hodnota: 2 modif. hodnota je: 38

  21. Generování SW přerušení - možnost volat vektory přerušení, nejpoužívanější jsou 10H (video BIOS), 16H (ovládání klávesnice), 21H (vyžádání funkce operačního systému), 33H (komunikace s ovladačem myši) - knihovní funkce pro naplnění registrů procesoru a generování přerušení požadovaného typu int int86(int typ, union REGS *inregs, union REGS *outregs) int intdos(union REGS *inregs, union REGS *outregs) void intr(int intno, struct REGPACK *reg) - uvedené funkce plní vstupní parametry do odpovídajících registrů a generují přerušení daného typu, po návratu jsou naplněny výstupní parametry, používají se strukturované datové typy, jejichž jednotlivé složky představují registry procesoru (jsou to běžné proměnné, uložení hodnot do registru provádí knihovní funkce před generováním přerušení) #include <dos.h> struct REGPACK r; r.r_ax = 0x001; intr(0x10, &r);

  22. Ovládání přerušení - rezervace prvních 1024 bytů paměti pro vektory přerušení (256) - mnoho vektorů přerušení není obsazeno, což dává možnost defi- novat si vlastní obslužné rutiny - funkce pro ošetření přerušení je typu void s modifikátorem inrerrupt, její parametry jsou typu unsigned void interrupt obsluha(bp, di, si, ds, es, dx, cx, bx, ax, ip, cs, flags, …) - všechny registry se předávají jako parametry, takže je lze libo- volně používat a modifikovat. Obslužná rutina může mít i dal- ší parametry. - funkce typu interrupt automaticky uloží (vedle SI, DI, a BP) i AX až DX, ES a DS - jsou k dispozici dvě funkce pro práci s obsluhami přerušení

  23. Ovládání přerušení void interrupt(*getvect(int cis_prer))() - přečte se hodnota vekto- ru přerušení, určeného parametrem cis_prer a interpretuje se jako vzdálený ukazatel na funkci přerušení. Návratová hodnota jsou 4 slabiky, které jsou uloženy ve vektoru přerušení cis_prer void setvect(int cis_prer, void interrupt(*rut)()) - funkce nastaví hodnotu vektoru přerušení cis_prer na novou hodnotu, jež je vzdáleným ukazatelem obsahujícím adresu nové funkce pro ob- sluhu přerušení rut. Návratová hodnota není žádná. Adresu rut lze předávat jako parametr funkce setvect pouze tehdy, pokud byla definována jako interrupt. /* instalace obsluhy preruseni 10H zvukovym signalem */ #include <dos.h> #include <conio.h> void instaluj(void interrupt(*vzdaladr)(), int cislo); void testzvuk(unsigned char bpocet, int icislo); void interrupt zvuk(unsigned ax);

  24. void main() void interrupt zvuk(unsigned ax) { { char znak; int i, j; char origin, bity; instaluj(zvuk, 10); unsigned char bpocet = ax >> 8; setvect(10, zvuk); /* sejme aktualni stav ridiciho portu */ do { bity = origin = inport(0x61); testzvuk(3, 10); for(i=0; i<=bpocet; i++) znak=getch(); { } while (znak != 3); /* na chvili vypne bzucak */ } outport(0x61, bity & 0xFC); for(j=0; j<=100; j++) ; /* prazdny prikaz */ void testzvuk(unsigned char /* na chvili se zapne */ bpocet, int icislo) outport(0x61, bity | 2); { for(j=0; j<=100; j++) ; /* prazdny prikaz */ _AH = bpocet; } geninterrupt(icislo); /* nastavi se puvodni stav ridiciho portu */ } outport(0x61, origin); } - v dalším příkladu je instalace obsluhy přerušení 5H, která je vy- hrazena pro hard - copy obrazovky

  25. #include <dos.h> #include <conio.h> void interrupt (*stara)(); void interrupt zvuk(void); void main() { char znak; stara = getvect(5); /* ulozeni stareho vektoru */ setvect(5, zvuk); /* instalace noveho */ do { znak = getch(); } while (znak != 3); setvect(5, stara); } void interrupt zvuk(void) { putch(7); }

More Related