Feladatok

(A feladatok neve mellett a kapható maximális félév végi jegy áll.)

 

1. Feladat (AntiPos) (max:3) betelt

Írd meg az alábbi Pascal programhoz tarozó külsô assembly függvényt. Az AntiPos függvény tegye az ellenkezôjét annak, amit a Pos, vagyis egy sztringben ne az elsô, hanem az utolsó elôfordulását keresse meg egy másik sztringnek. Ha nem fordul benne elô, akkor akkor adjon vissza 0-t, ha pedig igen, akkor a jobbról elsô elôfordulás pozícióját adja vissza! (Lásd: megjegyzés a programban)

 

Program Feladat1;
Var sz1,sz2:String;
b:Byte;
Function AntiPos(Substr:String; S:String):Byte; external; {$l antipos.obj}
BEGIN
Write('Kerem a nagy sztringet:');
ReadLn(sz1);
Write('Kerem a kis sztringet:');
ReadLn(sz2);
b:=AntiPos(sz2,sz1);
Case b of
0:Writeln('Nem fordul benne elo');
else Writeln('Jobbrol az elso elofordulas pozicioja:',b);
End;
{Pl: AntiPos('cde','abcedfcdeg')=7}
END.

 

2. Feladat (Convert) (max:3) betelt

Írd meg az alábbi Pascal programhoz tarozó külsô assembly függvényt. A Convert függvény a neki átadott sztring paramétert alakítja át a Command paraméter értéke szerint. A Command paraméter értelmezését lásd a programban.

 

Program Feladat2;
Var S:String;
Function Convert(S:String; Command:Byte):String; external; {$l convert.obj}
BEGIN
ReadLn(S);
Writeln('Csupa nagy betuvel :',Convert(S,0));
Writeln('Csupa kis betuvel :',Convert(S,1));
Writeln('Csak a kezdobetuk nagyok:',Convert(S,2));
Writeln('A kezdobetuk nagyok :',Convert(S,3));
  {Pl: Ha a felhasznalo altal megadott sztring: 'AssemblY programozas'
akkor a prg rendre az alabbi outputot adja:
'Csupa nagy betuvel: ASSEMBLY PROGRAMOZAS'
'Csupa kis betuvel: assembly programozas'
'Csak a kezdobetuk nagyok:Assembly Programozas'
'A kezdobetuk nagyok: AssemblY Programozas'
Minden egyeb (3-nal nagyobb) Command parameter a sztringet valtozatlan formaban adja vissza}
END.

 

3. Feladat (Igazit) (max:3)

Írd meg az alábbi Pascal programhoz tarozó külsô assembly függvényt. A JobbraIgazit és BalraIgazit függvények ugyanabban az ASM fileban vannak definiálva. Mindekettô a megkapott sztringet Width méretû sztringgé alakítja. Szükség esetén az S-hez szóközöket ad hozzá a megfelelô oldalról, vagy levág belôle valahány karaktert szintén a megfelelô oldalról. (Lásd: megjegyzés a programban)

 

Program Feladat3;
Var s:String;
Function JobbraIgazit(S:String; Width:Byte):String; external; {$L igazit.obj}
Function BalraIgazit (S:String; Width:Byte):String; external;
BEGIN
WriteLn('Kerem az input sztringet');
ReadLn(s);
Writeln('1234567890123456789012345678901234567890');
WriteLn('Jobbra igazitva 40 karakterre:',JobbraIgazit(S,40),'Idaig tart');
WriteLn('Balra igazitva 40 karakterre :',BalraIgazit(S,40),'Idaig tart');
WriteLn('Jobbra igazitva 6 karakterre:',JobbraIgazit(S,6),'Idaig tart');
WriteLn('Balra igazitva 6 karakterre :',BalraIgazit(S,6),'Idaig tart');

{A prg. a 'regiszter' inputra az alabbi outputot adja:
Jobbra igazitva 40 karakterre: regiszterIdaig tart
Balra igazitva 40 karakterre :regiszter Idaig tart
Jobbra igazitva 6 karakterre:iszterIdaig tart
Balra igazitva 6 karakterre :regiszIdaig tart
}
END.

 

4. Feladat (Fibonacci) (max:2) betelt

Írd meg az alábbi Pascal programhoz tarozó külsô assembly függvényt. A Fibonacci függvény mintájára egy olyan assemly függvényt (FibonacciAsm) kell írni, amelyiket Pascalból hívjuk, és ô rekurzívan hívja saját magát. Feltehetô, hogy a függvény 25-nél kisebb paramétert kap, vagyis a Fibonacci sorozat nem fut ki a Word tartományból. A FibonacciAsm(n:Word) függvény a Fibonacci-sorozat n-dik elemét adja vissza. (A Fibonacci-sorozat 0-dik eleme 0, elsô eleme 1, minden újabb elem a két korábbi elem összege) (Lásd: megjegyzés a programban)

 

Program FibonacciSorozat;
{Ez a program csak a fuggvenyhivast es a rekurziot illusztralja,
nem a leghatekonyabb Fibonacci-sorozatot szamito algoritmus}
Var n:word;
{----------------------------------------------}
Function Fibonacci(w:word):word;{ezt a fuggvenyt irjuk at kulso assemblyre}
Begin
If w<2 then Fibonacci:=w
else Fibonacci:=Fibonacci(w-1)+Fibonacci(w-2);
End;
{----------------------------------------------}
Function FibonacciAsm(w:word):word; external; {$L Fibon.obj}
{----------------------------------------------}
BEGIN
For n:=0 to 24 Do {25-re mar kifutnank a WORD tartomanybol}
Write(FibonacciAsm(n):8);
END.

 

5. Feladat (Faktoriális) (max:2) betelt

Írd meg az alábbi Pascal programhoz tarozó külsô assembly függvényt. A Faktorial függvény mintájára egy olyan assemly függvényt (FaktorialAsm) kell írni, amelyiket Pascalból hívjuk, és ô rekurzívan hívja saját magát. Feltehetô, hogy a függvény 17-nél kisebb paramétert kap, vagyis a Faktorialis sorozat nem fut ki a LongInt tartományból. A FaktorialAsm(n:LongInt) függvény az n! értéket adja vissza. (Definíció szerint 0!=1!=1) (Lásd: megjegyzés a programban)

 

Program Faktorialis;
{Ez a program csak a fuggvenyhivast es a rekurziot illusztralja,
nem a leghatekonyabb faktorialis-szamito algoritmus}
Var n:LongInt;
{----------------------------------------------}
Function Faktorial(w:LongInt):LongInt;{ezt a fuggvenyt irjuk at kulso assemblyre}
Begin
If w<2 then Faktorial:=1
else Faktorial:=w*Faktorial(w-1);
End;
{----------------------------------------------}
Function FaktorialAsm(w:LongInt):LongInt; external; {$L Fakt.obj}
{----------------------------------------------}
BEGIN
For n:=0 to 12 Do {13-ra mar kifutnank a LongInt tartomanybol}
Write(FaktorialAsm(n):16);
END.

 

6. Feladat (Unix-match) (max:4)

Írd meg az alábbi Pascal programhoz tarozó külsô assembly (Match) függvényt. A program azt csinálja, hogy az aktuális alkönyvtár minden file-ját beolvassa, és amelyekl neve illeszkedik a megadott S sztringhez a Unix-filozófia szerint, azoknak a nevét kiírja.

A Unix-értelemben vett filenév-illeszkedés annyiban tér el a DOS-tól, hogy a filenév nem oszlik névtörzs és kiterjesztés részekre, hanem egyetlen összefüggô karaktersorozat, amelynek a pont egy közönséges eleme, és többször is elôfordulhat. Ezen kívül eltérés az, hogy a file-név akár 255 karakter hosszú is lehet. A filenév-illeszkedés vizsgálatához használható a ? és a * karakter a DOS-hoz hasonló értelemben. Eltérés az, hogy a * karakter utáni jeleket is figyelembe veszi a Unix.

Tehát pl: a '*a*' azokat a file-okat jelöli, amelyek nevében legalább egy 'a' karakter szerepel (pont is lehet benne), míg a DOS ezalatt a jelölés alatt minden filenevet ért.

 

Program feladat6;
Uses Dos;
Var TS:SearchRec;
S:String;
{-----------------------------------------}
Function Match(S1,S2:String):Boolean; external; {$l match.obj}
{
Begin
Match:=Random(2)=1; {nem ezt kell megirni! :) }
End;
}
{-----------------------------------------}
BEGIN
Randomize;
Write('Kerem az illeszkedesi sztringet');
ReadLn(S);
Writeln('------------');
FindFirst('*.*',AnyFile,TS);
While DosError=0 Do
Begin
If Match(S,TS.Name) Then WriteLn(TS.Name);
FindNext(TS);
End;
{Az aktuaslis alkonyvtar minden file-jan vegigmegyunk, es megnezzuk,
hogy illeszkedik-e a megadott S sztringhez a Unix-filozofia szerint
}
END.

 

7. Feladat (Gyorsrendezõ) (max:4)

Írd meg az alábbi programban használható GyorsRendez külsô assembly eljárást, amely gyorsrendez egy tömböt. Az eljárás paraméterként kapja annak a tömbnek a címét, amely tömb a rendezendô elemekre mutató pointereket tartalmazza. Rendezni csak a pointereket szabad a tömbön belül, tömbön kívüli adatokat (tehát a pointerek által mutatott értékeket) módosítani nem szabad. Ezen kívül a tömb maximális indexét kell még átvenni paraméterként. A pointerek tömbje 0..MaxIndex tartományban van indexelve. Utolsó paraméterként azt a FAR típusú függvényt kell átadni (függvény típusú paraméter), amelyik két (címükkel adott) elem sorendjét válaszolja meg. (0: a rendezés szempontjából azonosak, -1: P1 által mutatott adat elôbb szerepeljen a rendezett tömbben, mint a P2 által mutatott adat (vagyis P1 a kisebb), +1: P1 nagyobb)

A GyorsRendez eljárás semmi információt nem kap a mutatott elemek típusáról, az összehasonlítást a Compare paraméterként megadott függvény hasonlítja össze, a GyorsRendez csak a pointerek sorrendjét változtatja meg.

Program feladat7;
Type CompFunction=Function(P1,P2:Pointer):Shortint;
     TRekord=Record
               Adat1:Word;
               Adat2:String;
             End;
Const MaxIndex=100;
Var Tomb:Array[0..MaxIndex] Of Pointer;
    i:integer;
    s:String;
{-----------------------------------------}
Procedure GyorsRendez(TombCim:Pointer;
                      MaxIndex:Word;
                      Compare:CompFunction); external; {$l gyorsrnd.obj}
{-----------------------------------------}
{$F+}  {csak far tipusu fuggveny lehet fuggveny tipusu parameter}
Function Hasonlit(P1,P2:Pointer):Shortint;{(P1,P2:Pointer):Shortint;}
Begin
  If TRekord(P1^).Adat1<TRekord(P2^).Adat1
     Then Hasonlit:=-1  {-1:P1 kisebb}
     Else If TRekord(P1^).Adat1=TRekord(P2^).Adat1
          Then Hasonlit:=0  {0:egyenlok}
          Else Hasonlit:=1  {1:P1 nagyobb}
End;
{$F-}
{-----------------------------------------}
BEGIN
  For i:=0 To MaxIndex Do
    Begin
      GetMem(Tomb[i],SizeOf(TRekord));
      TRekord(Tomb[i]^).Adat1:=Random(65535);
      Str(TRekord(Tomb[i]^).Adat1,s);
      TRekord(Tomb[i]^).Adat2:='A szam erteke:'+s;
    End;
  {Minden tombelemet feltoltunk: Helyet foglalunk neki
                                 Adat1: veletlen szeru ertek}
                                {Adat2: ugyanez a szam sztringkent}
  GyorsRendez(@Tomb,MaxIndex,Hasonlit);  {lerendezzuk a tombot}
  For i:=0 To MaxIndex Do
    WriteLn(TRekord(Tomb[i]^).Adat1,' ',TRekord(Tomb[i]^).Adat2);  {kiirjuk az eredmenyt}
END.

8. Feladat (Képlopó) (max:5) Nem választható

Írj olyan rezidens COM programot (neve: KEPLOPO.COM), amely a PrintScreen gomb lenyomását figyelei, ekkor lementi az aktuális képernyô tartalmát TXT vagy PCX file-ba attól függôen, hogy karakteres vagy grafikus képernyô van-e bekapcsolva. A lementendô file nevét a COM indításakor parancssori paraméterként lehessen átadni. Grafikus esetben csak a 320*200-as üzemmódra kell mûködnie a programnak.

Pl.: KEPLOPO.COM CAPTURE
parancs hatására CAPTURE.TXT illetve CAPTURE.PCX keletkezzen.

Megjegyzés: A PCX formátum az egyik legegyszerûbb PC-s képformátum, dokumentációja sok helyen (interneten) elérhetô.

 

9. Feladat (Scroll) (max:5) nem választható!

Írj olyan rezidens COM-ot (neve: SCROLL.COM), amely a képernyô tetején ki-scrollozódó sorokat megjegyzi, és ALT+CursorUP illetve ALT+PageUp (és ugyanez lefelé) billentyûkombinációra a korábban megjegyzett sorokat fokozatosan visszahozza úgy, mint ahogyan az X-terminál ablakában a kigördülô sorok a görgetôsávval visszahozhatók. A kigördülô sorok tárolásához szükséges puffer a COM file szegmensében legyen, vagyis mérete nem nagyobb egy szegmensnél.

 

10. Feladat (PwdLopó) (max:5) betelt

Írj olyan rezidnes COM-ot (neve: PWDLOPO.COM), amely két paramétert vár: egy számot (tizes számrendszerben, max. 65535), és egy sztringet (a szám paraméter után egy szóköz kötelezõ, az az utáni karaktertõl kezdve a paraméter-sor végéig tart a sztring). Ha a felhasználó a sztring-et begépeli, akkor onnantól kezdve n darab billentyûleütést egy file-ba mentsen a COM. Így a program alkalmas lenne login_name figyelésére, majd utána lementené az elsõ pár billentyûvel begépelt jelszót (ezért a neve PWDLOPO).

Például: PWDLOPO.COM 50 h123456

Ez az elsô alkalomtól kezdve, amikor valaki rendre a h, 1, 2, 3, 4, 5, 6 billentyûket nyomta le, attól kezdve 50 billentyûleütést kiír egy file-ba.

 

11. Feladat (StringComapre) (max:3) betelt

Írj olyan, az alábbi PASCAL fõprogramhoz illesztett külsõ MASM függvényt, amely két változó módú, String típusú paraméterrõl eldönti, hogy a magyar (!) ABC szerint melyik van elõbb, és eszerint visszaad egy -1,0,1 közötti Shortint típusú eredményt, amely rendre azt mondja meg, hogy az elsõ String paraméter kisebb, egyenlõ vagy nagyobb, mint a második (a magyar ABC szabályai szerint).

Megjegyzés: A kettõs betûket (cs, ty, stb.) nem kell figylemebe venni, de az ékezeteseket igen (DOS szerint, nem Windows szerint!). Ezen kívül ügyelni kell arra is, hogy a kis és nagy betûk közül a nagyobbak vannak elôbbre.

Például:
  A<Á<...<a<á
  a<á<b
  co<cs<cu

  
Program Feladat11;
Var S1,S2:String;
{-----------------------------------------}
Function StringCompare(Var S1,S2:String):Shortint; external; {$l strcomp.obj}
{-----------------------------------------}
BEGIN
Write('Kerem az 1. sztringet:');
ReadLn(S1);
Write('Kerem az 2. sztringet:');
ReadLn(S2);
Case StringCompare(S1,S2) of
-1:WriteLn('Az elso kisebb');
0:WriteLn('Egyenlok');
1:WriteLn('A masodik kisebb');
End;
END.

 

12. Feladat (Gyökvonás) (max:2-3, megvalósítástól függ) betelt

Írj az alábbi Pascal programhoz kapcsolható külsõ assembly (MASM) függvényt, amely egy Word típusú paramétert kap, és visszaadja a négyzetgyökének egészrészét. Több féle elfogadható algoritmus is létezik.

Program Feladat12;
{---------------------------}
Function Gyok(L:Word):Byte; external; {$L gyok.obj}
{----------------------------}
BEGIN
Write('Kerek egy pozitiv egesz szamot:');
ReadLn(N);
WriteLn('A negyzetgyokenek egeszresze:',Gyok(N));
END.
  

13. Feladat (KisHeap) (max:5)

A Pascal a heap-et úgy kezeli, hogy az elemeire mutató pointerek mind far pointerek, vagyis 4 byte-osak. C-ben van lehetõség 2 byte-os (near) pointereket is használni. Ez egyrészt kevesebb memóriát igényel a pointerek tárolásához, másrészt gyorsabb is, emiatt gyakran érdemesebb (lenne) használni, mint a far pointereket.
Írj olyan unit-ot, ami lefoglal egy (64K-nál kisebb) területet az adatszegmensbõl, és abban megvalósítja a foglalás, felszabadítás és referencia-mûveleteket. A referencia ez esetben hagyományos far pointerré alakítást jelent.

Unit KisHeap;
Interface
Function Malloc(Size:Word):Word; {Size: mekkora terulet kell, eredmeny:cime (0:hiba)}
Procedure Free(Address: Word);
Function ConvertToFarPointer(Address: Word):Pointer;
{-------------------------------------------------------}
Implementation
Function Malloc(Size:Word):Word; external; {$L kisheap.obj}
Procedure Free(Address: Word); external;
Function ConvertToFarPointer(Address: Word):Pointer; external;
Const HeapSize=20000; {ekkora teruletet hasznalunk heap-nek}
Var Puffer:Array[1..HeapSize] Of Byte;
BEGIN
END.

 

14. Feladat (NagyHeap) (max:5)

A Pascal a DOS 640K RAM-jából használ fel annyit heap-nek, amennyi a program memóriába töltése után marad. Ez 200-500KB attól függõen, hogy mennyi rezidens programot töltöttünk a memóriába, illetve az IDE alól futtatjuk-e a programot. Mivel gyakran több memóriára van szükség, file-ba kell dolgozni, ami lassú és kényelmetlen.
Írj olyan unit-ot, ami lefoglal a winchesteren egy adott nagyságú file-t, és abban megvalósítja a heap-inicializálás, foglalás, felszabadítás és referencia-mûveleteket. Mutatóként pointer helyett LongInt-et használj, a hivatkozott területet virtuális memóriaként lapozd be a RAM-ba. Használj minél jobb cache-elési technikát!

Unit NagyHeap;
Interface
Function HeapInit(Size:Longint):Boolean; {Eredmeny: FALSE, ha nem sikerult}
Function Malloc(Size:Word):LongInt; {Size: lefoglalando terulet, eredmeny: cime. 0:hiba}
Procedure Free(Address: LongInt);
Function ConvertToFarPointer(Address: LongInt):Pointer;
{-------------------------------------------------------}
Implementation
Function HeapInit(Size:Longint):Boolean; external; {$L nagyheap.obj}
Function Malloc(Size:Word):Longint; external;
Procedure Free(Address: LongInt): Boolean; external;
Function ConvertToFarPointer(Address: LongInt):Pointer; external;
BEGIN
END.

 

 

15. Feladat (3D Engine) (max:5)

Írj tiszta assembly-ben egy 3D engine-t (3 dimenziós megjelenítõ rendszer). Alakítsd ki a szükséges adatstruktúrákat, írd meg a megjelenítõ rutin(ok)at és futtasd a kötprogramot egy teszt-adatbázison. (Minimális követelmény a wire-frame, azaz dróthálós megjelenítés!) Az engine-hez interaktív kezelõfelületet is kell írni (ezt már nem kell assemblyben), legalább forgatni és mozgatni lehessen a megjelenítendõ objektumot. A megjelenítendõ objektum adatait textfile-ból olvassa be a program. Az objektumleíró file specifikációját is mellékeld a kötprg-hoz!

 

16. Feladat (Fixpontos I.) (max:4)

Fixpontos számábrázolás esetén egy számot leíró byte-sorozat rögzített darabszámú bitje írja le az egész, és rögzített darab bit a törtrészt. Például 8 bites fixpontos ábrázolásnál lehet 1:5:2 arányú, vagyis 1 bit elõjel tárolásra, 5 bit egészrész tárolásra, és 2 bit törtrész tárolásra van fenntartva, de lehet 0:6:2 arányú, vagyis elõjeltelen 6 bites egészek mellé 2 bitnyi törtrészt tudunk tárolni. Ekkor a tárolható számok: 0.0, 0.25, 0.50, 0.75, 1.00, 1.25, ..., 63.00, 63.25, 63.50, 63,75 (a 2 bit törtrészen negyedeket tudunk megkülönböztetni). Elõjeles esetben kettes komplemens alakban tárolandók a számok. A legmagasabb helyiértéken tárolandó az elõjel-bit, közepes helyeken az egészrész, legalacsonyabb helyiértékeken a törtrész. Tehát például a memóriában lévõ E2FCh érték (FCh E2h sorrendben van a memóriában) 1:11:4 arányú ábrázolás esetén:

F    C    E    2
1111 1100 1110 0010

legmagasabb helyiérték az E jegybõl származó 1-es (bold),
egészrész a középsõ 11 bit: 110 0010 1111 (italic), és
törtrész a legalacsonyabb helyiértékû 4 bit a C jegybõl: 1100 (underline).

Írj olyan unit-ot, amely 16 byte-os számokkal dolgozva megvalósítja az 1:63:64 arányú fixpontos számábrázolás negálás, + és - mûveleteit. A számokat LongInt típusú egészekkel lehet inicializálni, és LongInt-ben lehet visszakapni az eredményt is. Így LongInt egész számokból kiindulva nagy pontosságú fixpontos aritmetikát használva lehet számolni, és a végeredmény is LongInt lesz, tehát csak a számolás idejére pontos a számábrázolás. A számok adattömbjeire a rájuk mutató pointerekkel hivatkozzon a Pascal.

Unit FixPont1;
Interface
Procedure LongintToFix(L:Longint; FixP:Pointer);
Function FixToLongint(FixP:Pointer; Var L:Longint):Boolean; {FALSE, ha nem fer longint-be}
Function FixAdd(FixP1,FixP2:Pointer; Var Result:Pointer): Boolean; {FALSE, ha nem fer el}
Function FixSub(FixP1,FixP2:Pointer; Var Result:Pointer): Boolean; {FALSE, ha nem fer el}
Function FixNeg(FixP1:Pointer; Var Result:Pointer): Boolean; {FALSE, ha nem fer el} {-----------------------------------------------------------------------} Implementation Procedure LongintToFix(L:Longint; FixP:Pointer); external; {$L FixPont1.obj} Function FixToLongint(FixP:Pointer; Var L:Longint):Boolean; external; Function FixAdd(FixP1,FixP2:Pointer; Var Result:Pointer):Boolean; external; Function FixSub(FixP1,FixP2:Pointer; Var Result:Pointer): Boolean; external; Function FixNeg(FixP1:Pointer; Var Result:Pointer): Boolean; external; BEGIN END.

 

17. Feladat (Fixpontos II.) (max:5)

A 16-os feladat kiegészítve a szorzás és osztás mûveleteivel. Az eljárások fejléce:

Function FixMul(FixP1,FixP2:Pointer; Var Result:Pointer): Boolean; {FALSE, ha nem fer el}
Function FixDiv(FixP1,FixP2:Pointer; Var Result:Pointer): Boolean; {FALSE, ha nem fer el, vagy 0-val oszt}

 

18. Feladat (Buborékrendezõ) (max:3)

Írd meg az alábbi programban használható BuborekRendez külsô assembly eljárást, amely rendez egy tömböt. Az eljárás paraméterként kapja annak a tömbnek a címét, amely tömb a rendezendô elemekre mutató pointereket tartalmazza. Rendezni csak a pointereket szabad a tömbön belül, tömbön kívüli adatokat (tehát a pointerek által mutatott értékeket) módosítani nem szabad. Ezen kívül a tömb maximális indexét kell még átvenni paraméterként. A pointerek tömbje 0..MaxIndex tartományban van indexelve. Utolsó paraméterként azt a FAR típusú függvényt kell átadni (függvény típusú paraméter), amelyik két (címükkel adott) elem sorrendjét válaszolja meg. (0: a rendezés szempontjából azonosak, -1: P1 által mutatott adat elôbb szerepeljen a rendezett tömbben, mint a P2 által mutatott adat (vagyis P1 a kisebb), +1: P1 nagyobb)

A BuborekRendez eljárás semmi információt nem kap a mutatott elemek típusáról, az összehasonlítást a Compare paraméterként megadott függvény hasonlítja össze, a BuborekRendez csak a pointerek sorrendjét változtatja meg.

Program Feladat18;
Type CompFunction=Function(P1,P2:Pointer):Shortint;
     TRekord=Record
               Adat1:Word;
               Adat2:String;
             End;
Const MaxIndex=100;
Var Tomb:Array[0..MaxIndex] Of Pointer;
    i:integer;
    s:String;
{-----------------------------------------}
Procedure BuborekRendez(TombCim:Pointer;
                        MaxIndex:Word;
                        Compare:CompFunction); external; {$l bubrnd.obj}
{-----------------------------------------}
{$F+}  {csak far tipusu fuggveny lehet fuggveny tipusu parameter}
Function Hasonlit(P1,P2:Pointer):Shortint;{(P1,P2:Pointer):Shortint;}
Begin
  If TRekord(P1^).Adat1<TRekord(P2^).Adat1
     Then Hasonlit:=-1  {-1:P1 kisebb}
     Else If TRekord(P1^).Adat1=TRekord(P2^).Adat1
          Then Hasonlit:=0  {0:egyenlok}
          Else Hasonlit:=1  {1:P1 nagyobb}
End;
{$F-}
{-----------------------------------------}
BEGIN
  For i:=0 To MaxIndex Do
    Begin
      GetMem(Tomb[i],SizeOf(TRekord));
      TRekord(Tomb[i]^).Adat1:=Random(65535);
      Str(TRekord(Tomb[i]^).Adat1,s);
      TRekord(Tomb[i]^).Adat2:='A szam erteke:'+s;
    End;
  {Minden tombelemet feltoltunk: Helyet foglalunk neki
                                 Adat1: veletlen szeru ertek}
                                {Adat2: ugyanez a szam sztringkent}
  BuborekRendez(@Tomb,MaxIndex,Hasonlit);  {lerendezzuk a tombot}
  For i:=0 To MaxIndex Do
    WriteLn(TRekord(Tomb[i]^).Adat1,' ',TRekord(Tomb[i]^).Adat2);
  {kiirjuk az eredmenyt}
END.

 

19. Feladat (10-es maradék) (max:3)

Írj olyan önálló assembly programot (COM-ot) REMAIND.COM néven, amely a parancssorból beolvasott 8-as számrendszer beli számról megmondja, hogy mennyi a 10-zel vett maradéka. Az input szám lehet, hogy nagyobb, mint a LongWord méret! (Kis ügyeskedéssel ki lehet cselezni:)) Az eredményt írja ki a képernyõre, és adja vissza hibakódként is.
Például:REMAIND.COM 235
az input szám értéke:2*64+3*8+5=157, ennek a 10-zel vett maradéka 7, ezt kell kiírni és visszaadni.

Példa nagy számra:REMAIND.COM 100000000002
az input szám értéke: 1*8^11+2=8589934594, ennek a 10-zel vett maradéka 4.

 

20. Feladat (StackCalculator) (max:3)

Írj olyan önálló assembly programot (COM)-ot, amely parancssorból olvas be egy postfix jelölésû mûveletsort, kiszámítja az eredményt, és kiírja a képernyõre.
A postfix jelölésnél elõször az argumentumok vannak felsorolva, és utánuk jön a mûveleti jel. (Prefix jelölés:+,2,3; infix jelölés: 2,+,3; postfix jelölés: 2,3,+.) A postfix jelölésû mûveletsort gyorsan ki lehet értékelni úgy, hogy ha számot olvasunk be, akkor azt verembe gyûjtjük, mûveleti jel esetén pedig a megfelelõ mennyiségû számot leszedjük a verem tetejérõl, és a mûvelet eredményét visszatesszük a verem tetejére.
Feltehetjük, hogy az input string szabályos. Minden számjegy egyetlen számot jelent.
Például a (1+3)*(5+2) hagyományos infix jelölés postfix formában így néz ki: 13+52+*. Látható, hogy így nincs szükség zárójelekre. A feldolgozás során a 1 majd a 3 bekerül a verembe, az elsõ + jel alkalmával a helyükre az 4 kerül (1+3=4). Utána az 5 és a 2 is a verembe kerül, így a verem tartalma: 4,5,2. A második + jel miatt az 5 és a 2 kikerül a verembõl, helyükre a 7 kerül (5+2=7). Ekkor a verem tartalma: 4,7. Az utolsó feldolgozandó jel a *, a verembõl kikerül a 4 és a 7, helyükre a 28 kerül. Mivel vége az input stringnek, a verem tetején lévõ szám az eremény (28).

 

21. Feladat (TurtleGraphics) (max:5)

Írj olyan önálló assembly programot (TURTLE.COM)-ot, amely parancssorból olvas be egy filenevet, amely file egy turtle graphics program neve, és ezt a programot végrehajtja, majd billentyûleütés után kilép. A turtle graphics program egy ASCII szöveges file, minden sora egy-egy önálló parancs, amelyek egy teknôsbékát irányítanak. A teknôsbéka amerre megy, nyomot hagy, feltéve, hogy a tolla leér a papírra. Hat lehetséges parancs van: U, D, Lxxx, Rxxx, Fxxx, Bxxx. Az U és a D parancsok a tollat emelik fel, illetve teszik le. Az Lxxx és a Rxxx parancs hatására a teknôs balra illetve jobbra fordul xxx fokos szöggel. Az Fxxx parancs hatására xxx pixelt lép abba az irányba, amerre néz, illetve Bxxx esetén tolat. Ha a toll közben lent volt, akkor rajzol is, különben csak mozog. A parancsok xxx argumentuma nemnegatív egész szám, kisebb, mint 65536, fokot illetve pixelt jelent.
A teknôs akkor is hagy nyomot, ha nem mozdul el, csak leteszi a tollat majd felemeli. A rajzolás során kimehet a képernyôrôl, utána vissza is jöhet, a képernyôre rajzolni csak akkor kell, ha a teknôs tényleg arra jár. A kiinduló állapot: a képernyô közepe, a teknôs felfelé néz, és a tolla lent van. A program használjon 640*480-as felbontású grafikát.
Az alábbi példaprogram szabályos hatszöget rajzol:
F40
L60
U
F40
L 60
D
F 40
L 60
U
F40
L60
D
F40
L 60
U
F 40
L60

A forrásprogram tartalmazhat soronként akárhány szóközt, ezeket figyelmen kívül kell hagyni. Ettôl eltekintve a forrásprogramról feltehetô, hogy szintaktikailag helyes. A program hívása pl.: TURTLE.COM HATSZOG.TUR.

Tanácsok: A lebegôpontos számítások megkerülhetôk úgy, hogy a program magában tartalmazza a 0-90 fok közötti szögek szinuszának 16384-szeresét. Segítségével minden egész szög sziusza és koszinusza is kikereshetô a táblázatból. Így a hossz*sin(30) helyett hossz*Tabla[30]/16384 alakban lehet számolni. Ez egy kicsit pontatlanabb, mint ha végig lebegôpontos számokat használnánk, de lényegesen egyszerûbb, és gyorsabb is, ráadásul a teljes táblázat csak 91 word-öt tartalmaz (0...90), vagyis csak 182 byte adatot igényel. Egyenesrajzoló algoritmusról harmadéveseknél is lehet érdeklôdni (ôk tanulták már grafikából), de az interneten is van bô leírás róla.

 

22. Feladat (Hatvány) (max:2)

Írj az alábbi Pascal programhoz illesztett MASM szintaxisú assembly függvényt, amely a kapott paraméterekre kiszámolja a hatványukat. Az alap és a kitevő is lehet 0 vagy nagyobb. Természetesen ezekre is helyes eredményt kell adnia a programnak.

Program Feladat22;
Var x,y:Word;
    eredmeny: Longint;
Function Hatvany(Alap, Kitevo: Word):Longint;  external; {$l hatvany.obj}
BEGIN
  Write('Kerem az alapot:');
  ReadLn(x);
  Write('Kerem az kitevot:');
  ReadLn(y);
  eredmeny:=Hatvany(x,y);
  Writeln('Az eredmény: ', eredmeny);
END.

 


Utoljára módosítva: 2002. okt. 17. 17.13
e-mail:csongor@halmai.hu