Pótló ZH - Otthoni programok védése
- Pótló ZH időpontja: 2011. május 13. (péntek), 14:00-15:00
- Helyszín: Irinyi 105-os terem.
- Otthoni programok védése: a ZH alatt a tanári (vagy sajat) gepen + a ZH után (15:00-tól), az Irinyi kabinetben kifulladásig.
Otthon elkészítendő beadandó feladat
- Feladat kiválasztása a listáról.
- Jelentkezés a feladatra a Coospace-en keresztül.
- Feladat megoldása.
- Megoldás (forráskód) feltöltése a Coospace-en keresztül.
- Feladat személyes bemutatása. Bemutatásra van lehetőség a legutolsó gyakorlati foglalkozáson a ZH után, ill. a pótló ZH után.
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ímEgy 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]
Ö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 cx ;dxax=0000 0410h azaz 1040d
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 ) * bxadd ax, cx mul bxbx * dx + ax
mov cx, ax ;ax mentése mov ax, dx ;csak ax-ben tudunk szorozni mul bx ;szorzás bx-el add ax, cx eredmény ax-benax * ax + bx * bx
mul ax ;ax*ax mov cx, ax ;ax mentése mov ax, bx ;bx-et attesszük ax-be mul ax ; add ax, cx ;eredmény ax-ben
Osztás
mov ax, 0007h mov cx, 0003h div cl ; ax= 0102h
Feladat
Legyen a 8 bites előjeles (pl. -2), b 16 bites előjeles (-3), és c 8 bites előjeltelen (130d)
szám. Számoljuk ki a + b + c kifejezést!
mov al, -2d ;al=0feh cbw ;ax=0fffeh, előjeles kiterjesztés mov bx, -3d ;bx=0fffdh; add ax, bx ;ax=0fffbh, azaz -5 mov cl, 130d ;cl=82h xor ch, ch ;ch=0, zero kiterjesztés add ax, cx ;ax=007dh, azaz 125d
Feladat
Legyen a és b 8 bites előjeltelen (p a=3, b=4), c pedig 16 bites előjeles (-3).
Számoljuk ki az (a*b + c) / b kifejezést!
mov al, 3 mov cl, 4 mul cl mov bx, -3 ;bx=0fffdh add ax, bx div cl ;ax=0102h
Bitmanipulációk
Bitek törlése, beállítása, invertálása. Példa: vegyük az 10011011b = 9Bh
számot, és töröljük a felső 4 bitjét, állítsuk be a 3. és 4. bitjét majd negáljuk
az első bitjét.
bitek törlése: AND művelet; a maszk ott 0, ahol a biteket törölni szeretnénk.
bitek beállítása: OR művelet; a maszk ott 1, ahol a biteket magasra szeretnénk állítani.
bitek negálása: XOR művelet; a maszk ott 1, ahol a biteket negálni szeretnénk.
bitek törlése: AND művelet; a maszk ott 0, ahol a biteket törölni szeretnénk.
bitek beállítása: OR művelet; a maszk ott 1, ahol a biteket magasra szeretnénk állítani.
bitek negálása: XOR művelet; a maszk ott 1, ahol a biteket negálni szeretnénk.
mov al, 9Bh and al, 0Fh ;felső 4 bit törlése or al, 0Ch ;3-4 bitek beállítása xor al, 01h ;1-es bit negálásaHázi feladat: Írjunk program részletet XOR felhasználásával, melynek hatása megegyezik "mov ax, bx"-el.
xor ax, ax xor ax, bx
Faktoriális
Írjunk program részletet ami kiszámítja n! értékét. Az alábbi prog részlet, nem kezeli
azokat az eseteket, amikor a részeredmény nem fér el ax-ben.
mov cx, 4 mov ax, 1 ;dx:ax párosban gyűjtjük mov dx, 0 ;az eredményt cimke: mul cx ;DX:AX = AX * CX dec cx ;számláló csökken cmp cx, 1 ;SR = CX - 1 jne cimke ;ugrik ha nem egyenlő nop ;dx:ax ertéke a faktoriálisÍrjuk át a programot, hogy a jne helyett a je, jcxz, ja, jb utasításokat használjuk.
Üres assembly program
Az utolsó end utasítás utáni cimkén kezdődik a program:
kod segment assume cs:kod,ds:adat,ss:verem start: mov ax,adat ;ds betöltése mov ds,ax ;ds beállítása ;ide jön maga a program mov ah,4ch ;kilépés mov al,00h ;visszatérési kód int 21h ;dos megszakítás kod ends adat segment adat ends verem segment stack db 1024 dup (1) verem ends end startVagy letölthető innen.
Turbo Debugger
Turbo Debugger használata (TASM). 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.obj
MASM
A MASM elérhető a kabinetes gépeken. A MASM használata.
Feladat
Számoljuk ki a következő kifejezés értékét!
min( a*c , a+b )
ahol, a és c 8, b 16 bites előjeltelen számok.
kod segment assume cs:kod,ds:adat,ss:verem start: mov ax,adat ;ds betoltese mov ds,ax ;ds beallitasa ;ide jon maga a program mov al, a mul c mov bx, b mov cl, a xor ch, ch add bx, cx cmp ax, bx jb vege mov ax, bx vege: mov ah,4ch ;kilepes mov al,00h ;visszateresi kod int 21h ;dos megszakitás kod ends adat segment a db 4 c db 3 b dw 9 adat endsA teljes forráskód letölthető innen.
Házi feladat
Előjeles és előjeltelen számokra...
max(a+b, a+c) mid(a,b,c) (a+b) == c ? a : b+c abs(a+b)
Sztring hossza
Számoljuk meg, hogy milyen hosszú egy sztring! Tegyük fel, hogy a
sztringet a 0 karakter zárja.
mov cx, 0 ;szamlalo mov bx, offset hahostr betolt: mov al, [bx] cmp al, 0 je vege inc bx inc cx jmp betolt vege:Az adatszegmensünk a következő:
adat segment hahostr db "Haho !", 0 adat endsA teljes forráskód letölthető innen.
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.
mov cx, len ;cx= hossz mov bx, offset sor ;bx-be kerul sor offsetje xor dx, dx ;dx=0 betolt: mov al, [bx] ;szam betöltése al-be cmp al, dl ;ha kisebb= mint az eddigi legnagyobb jbe kov ;ugorja át a következő utasítást mov dl, al ;ez lesz az aktuális legnagyobb kov: inc bx ;index növelése loop betolt mov max, dl ;max valtozóba tároljuk el dl-tAz adatszegmens pl a következő is lehet:
adat segment len dw 5 max db 0 sor db 4,5,2,7,3 adat endsA teljes forráskód letölthető innen.
Számoljunk betűket
Számoljuk meg, hogy hány darab "a" betű van egy karakterláncban!
Párhuzamosan cseréljünk minden a betűt b betűre.
mov cl, 0 ;számláló mov bx, offset text mov si, 0 kov: mov al, [bx+si] ;betöltjük a köv. betűt cmp al, 0 ;elérkeztünk a végére? je vege ;ha igen, ugrik a végére cmp al, 'a' ;kell-e számolni jne nemszamol ;ugrik, ha nem kell számolni inc cl ;noveli a számlálót mov byte ptr[bx+si], 'b' nemszamol: inc si jmp kov vege: mov n, cl ;n-be rakjuk a végeredménytA teljes forráskód letölthető innen.
Nagybetűk
Módosítsuk egy string kisbetűit, a megfelelő nagybetűkre.
mov cl, 0 ;számláló mov bx, offset text mov si, 0 betolt: mov al, [bx+si] ;betöltjük a köv. betűt cmp al, 0 ;elérkeztünk a végére? je vege ;ha igen, ugrik a végére cmp al, 'a' ;a-nal nagyobb? jb kov ;ugrik, ha nem cmp al, 'z' ;z-nel kisebb? ja kov ;ugrik ha nem add al, 'A'-'a' mov [bx+si], al kov: inc si jmp betolt vege:A teljes forráskód letölthető innen.
Házi feladat
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!
Módosítsuk a nagybetűsre konvertáló programot, hogy kisbetűkre konvertálja a
nagybetűket.
Módosítsuk a nagybetűsre konvertáló programot, hogy kisbetűket nagyra, a
nagybetűket kicsire konvertálja.
Eljárások
Í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 endpA teljes forráskód letölthető innen.
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
Rendezés
Írjunk programot, sorbarendez egy bájtokból álló 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 endpA teljes forráskód letölthető innen.
Számkiírás
Í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.
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.
Megoldás verem használatával!
;eljárás ami megfordít egy stringet verem használatával. ;a string elejét SI mutatja strvfordit proc push si, di ;regiszterek mentése mov cx, 0 ;számláló számolja a str. hosszát mov di, si ;si mentése di berak: mov al, [si] ;betöltjük a betűt cmp al, 0 ;0 jelzi a str végét je berakvege push ax ;betű be a verembe inc cx ;számláló növelése inc si ;si mutasson a köv betűre jmp berak ;ugrás vissza a ciklus elejére berakvege: cmp cx, 0 ;számláló akkor 0, ha str üres volt je strvforditvege kivesz: pop ax mov [di], al inc di loop kivesz strvforditvege: pop di, si ret strvfordit endpA teljes forráskód letölthető innen. Verem használata nélkül!
;eljárás ami megfordít egy stringet. ;a string elejét SI mutatja strfordit proc push si di ;regiszterek mentése mov di, si ;di fog mutatni a string végére keres: mov al, [di] ;de, először meg kell keresnünk a végét cmp al, 0 ;vége? je keresvege ;ha igen ugrik inc di ;di mutasson a következő betűre jmp keres ;ugrás a keresés elejére keresvege: mov ax, di sub ax, si ;ax = di - si cmp ax, 2 ;ha 0 v. 1 a hossz, akkor vege is jb vege dec di csere: mov al, [di] xchg al, [si] ;kicseréli mov [di], al ;[si]-t és [di]-t inc si dec di cmp si, di ;vége? jb csere vege: pop di si ;regiszterek visszatöltése ret strfordit endpA teljes forráskód letölthető innen.
Paraméterek a veremben!
Írjuk egy eljárást amely összead 2 számot. A paramétereket a veremben
adjuk át!
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.
;kiszámolja egy előjeltelen bájtsorozat átlagát ;1. param: sor offsetje ;2. param: sor hossza avg proc push bp ;bp mentése mov bp, sp ;verem teteje push cx si bx dx;regiszterek mentése mov cx, [bp+4] ;2. paraméter mov si, [bp+6] ;1. paraméter mov ax, 0 ;részeredmények ciklus: mov bl, [si] mov bh, 0 ;előjeltelen számok ;(cikluson kivül erdemesebb) add ax, bx inc si loop ciklus mov cx, [bp+4] mov dx, 0 div cx ;osztunk a sor hosszával pop dx bx si cx;regiszterek visszatöltése pop bp ;bp visszatöltése ret avg endpA teljes forráskód letölthető innen.
Skalárszorzat
skal proc push bp ;bp mentése mov bp, sp ;verem teteje push si di bx cx;regiszterek mentése mov si, [bp+8] ;1. paraméter mov di, [bp+6] ;2. paraméter mov cx, [bp+4] ;3. paraméter (hossz) mov bx, 0 ;részeredmények ciklus: mov al, [si] mul byte ptr [di] add bx, ax inc si inc di loop ciklus pop cx bx di si;regiszterek visszatöltése pop bp ;bp visszatöltése ret skal endpA teljes forráskód letölthető innen.
Strstr eljárás
Írjunk olyan eljárást, amely egy szringben megkeresi egy másik string első előfordulását.
A teljes forráskód letölthető innen.
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 endpA teljes forráskód letölthető innen.