Gyakorlati számonkérések időpontjai
Kis ZH-k: 5. hét (február 28.), 8. hét (március 21.), 11. hét (április 11.), 12. hét (április 18.)
Nagy ZH: Április 29. 08:00 óra. Helyszín: TIK kongresszusi terem.
- A dolgozatírás ideje 60 perc.
- A dolgozatíráshoz segédeszköz (könyv, jegyzet, számítógép, mobil telefon, ...) nem vehető igénybe.
- Fényképes igazolvány kötelező.
- A teremnek csak az 1. emeleti ajtói lesznek nyitva. Akiknek a vezetékneve A - L betűvel kezdődik, a jobb oldali ajtónál gyülekezzen, a többiek a bal oldalinál.
1. Gyakorlat
Számrendszerek
Számok konvertálása 2-es, 10-es, 16-os számrendszerek között.
Pl:
Helyik a legnagyobb?
Ha r az alap?
77d = 100 1101b = 4Dh 185d = 1011 1001b = 0B9h BEDh = 1011 1110 1101b = 3053d 19,625d = 1 0011,101b 114,25d = 111 0010,01bHány különböző szám fejezhető ki n darab bináris számjegyen?
Helyik a legnagyobb?
Ha r az alap?
Műveletek
Összeadás, kivonás 2-es, 16-os számrendszerben.
Negatív számok: 1-es, 2-es komplemens.
Negatív számok: 1-es, 2-es komplemens.
Memóriakezelés
Szegmens: offszet címzés: Lineáris cím = segm * 16 + offs.
Mondjunk olyan logikai címeket, melyek az 12345h lineáris címre mutatnak! Mi a helyzet a 0ffffh:0010h címmel?
Mi a különbség a lineáris cím és a fizikai cím között?
segm:1272h ===> *16 ===> 12720h
offs:1a3bh + 1a3bh
-------
1415bh lineáris cím
Egy lineáris címnek hány logikai (szegmens:offszet) címe van? Mondjunk olyan logikai címeket, melyek az 12345h lineáris címre mutatnak! Mi a helyzet a 0ffffh:0010h címmel?
Mi a különbség a lineáris cím és a fizikai cím között?
Címzés
Kódba épített adat Címzés: [BX v. BP] + [SI v. DI] + [rel8 v. rel16]Alapértelmezett szegmens: DS, vagy BP használata esetén SS. Szegmens felülbírálással CS, DS, ES, SS elérhető. Alternatív jelölésmódok: [BX][SI], vagy 04h[BX]
Címzések
Melyik címzés helyes és melyik nem?
[12h+56h] ES:[09D3h] [123456789ABCh] [SI+DI] [IP] [SI-500d] [AX] SS:[BX+DI+1999d] [CX+1234h] [SP+BP] DS:[BP+SI] IP:[0000h]
2. gyakorlat
Turbo Debugger
Csomagold ki a tasm.zip állományt egy tetszőleges könyvtárba.
A td.exe-t kell elindítani.
MASM
A MASM elérhető a kabinetes gépeken. A MASM használata.
Összeadas
Tegyük fel hogy a következő példákban az adatszegmensünk így néz ki:
ds:0000 CD 20 FF 9F 00 9A F0 FE
ds:0000 CD 20 FF 9F 00 9A F0 FE
mov al, [0] ;al=CD mov ax, [0] ;ax=20CD Bájtsorrend!!
mov ax, 5h ;ax=0005h add al, 0001h ;ax=0006h
mov ax, 5h add al, [0001h] ;ax=0025h
mov ax, 5h mov bx, 6h add ax, bx ;ax=000Bh
mov ax, 5h mov bx, 6h add ax, [bx] ;ax=FEF5hAdjunk össze egy 8 bites előjeles számot és egy 16 bites előjeltelen számot! Például a -10d-t és a 2525d-t.
mov al, -10d ;al=0f6h mov bx, 2525d ;bx=09ddh cbw ;ax=0fff6h add ax, bx ;ax=09d3h
Szorzás
mov ax, 0102h mov cx, 0003h mul cl ;ax=0006h
mov ax, 0102h mov cx, 0003h mul cx ;dxax=0000 0306h
mov ax, 0202h mov si, 0003h ;ds:0003= 9fh mul byte ptr [si] ;ax=013eh
mov ax, 0602h mov si, 0003h ;ds:0003= 9f 00h mul word ptr [si] ;0602h*009fh = 0003 bb3ehElőjeles szorzás:
mov al, -2d ;al=0feh mov cl, 3d ;cl=03h imul cl ;ax=fffahSzorozzunk össze egy 8 bites előjeles, ill. egy 16 bites előjeles számot! Például a -2d-t és a -520d-t.
mov al, -2d ;al=0feh cbw ;ax=0fffeh mov cx, -520d ;cx=0fdf8h imul cl ;dxax=0000 0410h azaz 1024d
3. gyakorlat
Feladat
Írjunk egy programrészletet, amely kiszámolja az alábbi kifejezés értékét!
Feltesszük, hogy minden regiszter előjeltelen számot tartalmaz és minden
művelet eredménye elfér 16 biten. Az eredményt tároljuk ax-ben.
(cx + ax ) * bx
bx * dx + ax
ax * ax + bx * bx
bx * dx + ax
ax * ax + bx * bx
Gyakorlás
Legyen a 8 bites előjeles (pl. -2), b 16 bites előjeles (-3), és c 8 bites előjeltelen (130d)
szám. Adjuk össze őket!
Osztás
mov ax, 0007h mov cx, 0003h div cl ; ax= 0102hOsszuk el a 1234h-t 00h-val! Mi fog történni?
Osszuk el a 1234h-t 03h-val!
Feladat
Legyen a és b 8 bites előjeltelen, c pedig 16 bites előjeles.
Számoljuk ki a (a*b + c) / b kifejezést!
4. gyakorlat
Feltételes ugrások
Számoljuk ki a következő kifejezés értékét! Az eredményt helyezzük AX regiszterbe!
AX := min( a*c , a+b )
AX := max(a+b, a+c)
AX := mid(a,b,c)
AX := (a+b) == c ? a : b+c
AX := abs(a+b)
AX := min( a*c , a+b )
adat segment a db 4 ;elojeltelen c db 3 ;elojeltelen b dw 9 ;elojeltelen adat endsOldjuk meg a feladatot előjeles számokra is! További kifejezések:
AX := max(a+b, a+c)
AX := mid(a,b,c)
AX := (a+b) == c ? a : b+c
AX := abs(a+b)
5. gyakorlat
Üres assembly program
Az üres assembly program nem tartalmaz mást, mint azokat a kötelező utasításokat,
amelyek a program elindulásához és befejeződéséhez kellenek.
Sztring hossza
Számoljuk meg, hogy milyen hosszú egy sztring! Tegyük fel, hogy a sztringet a 0 karakter zárja.
Az adatszegmensünk a következő:
adat segment hahostr db "Haho !", 0 adat endsA teljes forráskód letölthető innen.
Turbo Debugger
Turbo Debugger (TASM) használata. Ahhoz hogy a Debuggerben a forrásprogramunkat
is lássuk, a következőképpen kell a fordítást és a linkelést végezni (%1 a
forrásfile neve kiterjesztés nélkül)
tasm /zd %1.asm tlink /v %1.objDebuggolás: td.exe
MASM
A MASM elérhető a kabinetes gépeken. A MASM használata. A fordítás menete MASM használatával:
masm %1.asm,,,, link %1.obj,,,,Debuggolás: debug
Feladatok
Oldjuk meg az alábbi feladatokat a sztring hossza program átírásával!
- Számoljuk meg, hogy hány darab "a" betű van egy karakterláncban!
- Cseréljünk le egy string minden "a" betűjét "b" betűre.
- Titkosítás: Cseréljünk ki minden betűt (A-Z, és a-z) az "x" betűre, az egyéb karaktereket hagyjuk meg.
- Cseréljünk le egy string minden kisbetűjét nagybetűre (UPPER CASE). Mit kell módosítani a programon, hogy a nagybetűkből legyenek kisbetűk? (lower case)
- Invetáljuk a kis és nagy betűket egy karaktersorozatban. (iNVERT cASE)
- A szavak első betűjét állítsuk nagybetűsre, a többi részét pedig kisbetűsre. A szavakat szóközök választják el. (Proper Case)
Szöveg kiírása
Írjunk eljárást, amely kiírja az AL-ben található karaktert a képernyőre.
;eljárás ami kiír egyetlen betűt. a betű kódját al-ben
;várja
betukiir proc ;al ben a kiirandó betű
mov ah, 14 ;BIOS rutin paramétere
int 10h ;10h megszakítás hívása
ret ;visszatérés
betukiir endp
Írjunk eljárást, ami kiír egy 0-val záródó karakterláncot a képernyőre!
;eljárás ami kiír egy 0-val záródó karakterláncot
;a string elejét si mutatja
strkiir proc
kov: mov al, [si] ;következő betű
cmp al, 0 ;0 jelzi a str végét
je strvege ;ha elértünk a végére ugrunk
call betukiir ;egy betű kiirása
inc si ;mutató a következő betűre
jmp kov ;ugrás
strvege:
ret ;eljárás vége
strkiir endp
A teljes forráskód letölthető innen.
6. gyakorlat
Szám kiírása
Írjunk ki egy előjeltelen 16 bites számot decimális alakban
a képernyőre!
Algoritmus: a számot osztjuk tízzel. A maradékot kiírjuk, a
hányadost pedig tovább osztjuk.
;eljárás, ami kiír egy számot decimális alakban ;a számot ax regiszterben várja szamkiir proc mov bx, 10d ;számrendszer alapja mov cx, 0 ;verembe tett számok számlálója k1: cmp ax, 0 ;addig osztunk amíg nulla nem lesz je v1 ;ha nulla ugrik mov dx, 0 ;a kov ut. dx:ax-et osztja! div bx ;osztás bx push dx ;maradek a verembe inc cx jmp k1 v1: jcxz cxnulla ;ugrik, ha nem tettünk semmit a verembe k2: pop ax ;kiveszünk egy értéket a veremből add al, '0' ;hozzáadjuk a '0' ASCII kódját call betukiir ;kiírjuk a számot (mint betűt) loop k2 ;jöhet a következő jmp v2 cxnulla: mov al, '0' ;ha ax-ben 0 volt, call betukiir ;írjunk ki egy 0-t v2: ret szamkiir endpA teljes forráskód letölthető innen. Feladatok:
- Írjuk át a programot, hogy 8 bites számokat írjon ki a képernyőre.
- Írjuk át a programot, hogy más számrendszerben is ki tudjon írni számokat.
- Írjuk át a programot, hogy előjeles számot is ki tudjon írni.
Maximum
Keressük meg egy bájtokból álló számsorozat legnagyobb
elemét! A számsorozat hosszát a len változó tartalmazza.
Az eredményt taroljuk a max változóban.
Az adatszegmens pl a következő is lehet:
adat segment
len dw 5
max db 0
sor db 4,5,2,7,3
adat ends
Feladatok:
- Módosítsuk a maximum kereső programot hogy szavakból (dupla bájt) álló számsorozatra is működjön.
- Módosítsuk a maximum kereső programot minimum kereső programra! Azaz keressük meg a sorozat legkisebb elemét. Figyeljünk a megfelelő kezdőértékekre!
- Egészítsük ki a maximum kereső programot, hogy a legnagyobb szám első/utolsó előfordulási helyét a "pos" változóban tároljuk!
7. gyakorlat
String beolvasás billentyűzetről
Irjunk egy eljárást, ami a billentyűzetről beolvas egy sztringet egy bufferbe.
; eljárás ami beolvas egy stringet az SI altal mutatott bufferbe
strolvas proc
push si ;si mentése
olv:
mov ah, 1h ;bios eljárás sorszáma
int 21h ;bios interrupt
cmp al, 0dh ;enter kódja
je olvasvege
mov [si], al ;betű tárolása a memóriában
inc si ;a következő betű egyel magasabb mem. címre kerüljön
jmp olv ;vissza az olvasás elejére
olvasvege:
mov byte ptr [si], 0 ;a string veget 0-val lezárjuk
mov ax, 0e0ah ;újsor karakter kiírása
int 10h
pop si
ret
strolvas endp
String fordítás
Fordítsunk meg egy stringet! Írjunk eljárást, amely egy string tartalmát
megfordítja. Az eljárás SI regiszterben várja a string elejét. Kiindulási forrás: strford.asm.
- Oldjuk meg a feladatot a verem használata nélkül!
- Használjuk a vermet a megoldáshoz!
- Használjuk a sztingkezelő utasításokat
8. gyakorlat
Paraméterek a veremben!
Írjuk egy eljárást amely összead 2 számot. A paramétereket a veremben
adjuk át!
... mov ax, 2d push ax mov ax, 4d push ax call osszead add sp, 4 ...
osszead proc push bp ;bp mentése mov bp, sp ;verem teteje push bx ;bx mentése mov bx, [bp+4] ;2. paraméter mov ax, [bp+6] ;1. paraméter add ax, bx ;összeadás pop bx ;bx visszatöltése pop bp ;bp visszatöltése ret osszead endpA teljes forráskód letölthető innen.
Átlag
Írjunk egy eljárást, amely kiszámolja egy sorozat átlagát! Az eljárásnak 2 paramétere
legyen (melyeket a veremben kap): az első a sorozat offsetje, a második a sorozat
hossza.
Kiindulási forrás a gyakorlati munkához: atlag.asm
Skalárszorzat
Írjunk eljárást, ami 2 n hosszúságú vektor skalárszorzatát határozza meg! A paramétereket a vermen keresztül kapja!
A teljes forráskód letölthető innen.
9. gyakorlat
Rendezés
Írjunk programot, sorbarendez egy bájtokból álló előjeltelen számsorozatot.
Működési elv: a sorozat minden egyes elemére végrehajtjuk a következőket:
végigmegyünk a rákövetkező elemeken, és ha kisebbet találunk mint az
aktuális, akkor megcseréljük őket.
;eljárás bx-ben várja a bájtsorozat elejét
;ha talál az első elemnél kisebb elemet, akkor
;megcseréli őket
min proc
mov dl, [bx] ;dl-ben az elso szám
mov si, bx ;si mutasson az elejére
k1: mov al, [si] ;akt szám betöltése
cmp al, 0 ;nulla?
je v1 ;ha igen: vége
cmp al, dl ;akt. szám és az eddigi legkisebb
jae k2 ;ha az akt. nagyobb ugorjunk
mov dl, al ;jegyezzük meg mert kisebb
xchg al, [bx] ;csere
mov [si], al ;csere
k2: inc si ;köv betű
jmp k1 ;
v1: ret ;visszatérés
min endp
;eljárás, mely rendez egy bájtsorozatot
rendez proc
k3: mov al, [bx] ;akt szám betölt
cmp al, 0 ;nulla?
je v2 ;ha igen: vége
call min ;tegyük az elejére a legkisebbet
inc bx ;köv betű
jmp k3
v2: ret ;eljárás vége
rendez endp
A teljes forráskód letölthető innen.
Feladatok: Írjuk át a programot úgy hogy, ...
- számoljuk, hogy hány csere történik, majd irassuk ki a cserék számát képernyőre!
- kiírja az eredeti és a rendezett sorozatot is a képernyőre!
- előjeles számokat kezeljen! Írjuk meg a szamkiir eljaras előjeles változatát is!
- 16 bites számokat kezeljen!
- csökkenő sorrendbe rendezze a számokat!
ASCII to Integer
Írjuk meg az atoi() függvényt előjeltelen számokra.
A teljes forráskód letölthető innen.
mov si, [bp+4] ;parameter atvetele mov cx, 10 ;számrendszer alapja mov ax, 0 ;ax-ben lesznek a részeredmények mov bh, 0 ;bl-ben lesz az aktuális számjegy, bh-ban meg nulla kovszamjegy: mov bl, [si] ;betöltünk egy betűt cmp bl, 0 ;vége-e a sztringnek? je vege sub bl, '0' ;levonja az első számjegy ASCII kódját, megkapjuk az értékét mul cx ;eddigi részeredmény x 10 add ax, bx ;hozzáadjuk az aktuális számjegyet inc si ;lépés a köv betűre jmp kovszamjegy vege:Feladatok: Írjuk át a programot úgy hogy, ...
- hexadecimális/bináris számokra működjön!
- előjeles számokat kezeljen!
- lebegőpontos számokat is kezeljen!
Gyakorló feladatok ZH-ra
Stringek
String esetén a kezdőcím SI regiszterben van megadva, ill. a végét a 0 jelzi. Az
eredményt (feltéve hogy van) AX-ben kell tárolni.
- Határozd meg az első "a" betű pozícióját (az első betű a nulladik, a második az első, stb...)! Ha nincs "a" betű a stringben legyen -1 a visszatérési érték!
- Számold meg hány betű van egy stringben a szóközök és írásjelek nélkül!
- Számold meg hány szó van egy sztringben. (dupla szóközök esetén a szavak száma nem változik!)
- Konvertáld a stringet csupa nagy-, ill. kisbetűsre! (To uppercase / to lower case)
- Egy string összes nagybetűjét váltsd kicsire, a kicsiket pedig nagyra! (Invert case)
- Minden szó kezdőbetűjét állítsd nagybetűsre! (Capitalize)
- Határozd meg hány kisbetű ( nagybetű, szám-karakter, írásjel ) van a szövegben!
- Határozd meg melyik betű hányszor fordul elő. (Pl. DI egy 256 elemű táblázat elejét mutatja)(hisztogram)
- Határozd meg, hogy a DI által mutattot string betűi hányszor fordulnak elő összesen!
- Határozd meg, hogy a DI által mutattot string hányszor fordul elő!
- Határozd meg a DI által mutatott string első/utolsó előfordulasának pozícióját! (strstr)
- Határozd meg a szóismétlések számát! (na, ez már durva...)
Számsorozatok, tömbök
Számsorozat kezdőcíme SI-ben, a hossza CX-ben van megadva. Az
eredményt (feltéve hogy van) AX-ben kell tárolni. A sorozat lehet előjeles/előjeltelen, 8/16 bites.
- Határozd meg hány darab szám esik 100 és 200 közé!
- Határozd meg a legnagyobb/legkisebb számot!
- Határozd meg a legnagyobb/legkisebb szám (első/utolsó előfordulásának) pozícióját!
- Határozd meg a legnagyobb/legkisebb szám előfordulásainak számát!
- Számolj átlagot/szórást.
- Határozd meg hányszor szerepel két egyforma szám egymás mellett!
- Határozd meg hányszor szerepel két egyforma abszolult értékű szám egymás mellett!
- Határozd meg hányszor szerepel n darab egyforma szám egymás mellett!
- Határozd meg hány n-el osztható szám van a sorozatban!
- Határozd meg hány négyzetszám van a sorozatban!
- Határozd meg hány előjelváltás történik a sorozatban!
- Határozd meg, hogy a számsorozat növekvő/csökkenő sorrendben van e! AX legyen 1, ha igen, különben 0.
- Határozd meg, hogy a számsorozat számtani sorozatot alkot e. AX legyen 1, ha igen, különben 0.
- Határozd meg, hogy a számsorozat mértani sorozatot alkot e. AX legyen 1, ha igen, különben 0.
- Határozd meg, hogy a számsorozat Fobonacci-sorozatot alkot e. AX legyen 1, ha igen, különben 0.
- Határozd meg, a leghosszabb növekvő/csökkenő részsorozat hosszát. AX legyen 1, ha igen, különben 0.
n-el osztható számok
Számoljuk meg hány n-el osztható szám van egy sorozatban!
;eljárás amelyik meghatározza, h. hány n-el osztható
;szám van sorozatban. Az eredményt ax-be teszi.
;1. param: 16 bites előjeltelen sorozat eleje
;2. param: hossz
;3. param: n
ndiv proc
push bp ;bp mentése
mov bp, sp ;bp = si
push si bx cx dx;regiszterek mentése
mov si, [bp+8];sorozat eleje
mov cx, [bp+6];hossz
mov bx, 0 ;számolja az n-el osztható elemeket
kezd:
mov ax, [si] ;ax-be a sor következő eleme
mov dx, 0 ;a köv. div dx:ax-et osztja!
div word ptr [bp+4] ;osztunk n-el
cmp dx, 0
jne nemoszthato
inc bx ;számláló növel
nemoszthato:
add si, 2 ;kov elem
loop kezd
mov ax, bx ;eredmény ax-be
pop dx cx bx si;regiszterek visszatöltése
pop bp
ret
ndiv endp
A teljes forráskód letölthető innen.
English