Architektúrák gyakorlat

1. Gyakorlat

Számrendszerek
Tanenbaum A Függelék. Számok konvertálása 2-es, 10-es, 16-os számrendszerek között. Pl:
77d = 100 1101b = 4Dh
185d = 1011 1001b = 0B9h
BEDh = 1011 1110 1101b = 3053d 

19,625d = 1 0011,101b
114,25d = 111 0010,01b
Hány különböző szám fejezhető ki n darab bináris számjegyen?
Helyik a legnagyobb?
Ha r az alap?
Műveletek
Negatív számok: 1-es, 2-es komplemens.
Összeadás, kivonás 2-es, 16-os számrendszerben.

2. Gyakorlat

Lebegőpontos számábrázolás
Tanenbaum B függelék.
114.25 ==> 0100 0010 1110 0100 1000 0000 0000 0000b
       = 42E4 8000h
1,5 ==> 3FC0 0000h
Memóriakezelés
Rodek 4.1-4.4 fejezet, Tanenbaum 5.4. Szegmens, offset, címzési módok.

3. Gyakorlat - Assembly

Flag-ek
O  Overflow - előjeles túlcsord
D  Direction - string műveletek iránya
I  Interrupt
T  Trap
S  Sign - előjel bit
Z  Zero - 1, ha az eredmény 0
A  Aux. Carry - átvitel a 3. és a 4. bit között
P  Parity - 1, ha az 1-esek száma az alsó 8 biten páros
C  Carry - átvitel előjel nélküli műveleteknél
Címzés
Kódba épített adat
Direkt (közvetlen) címzés: [offs16]
Bázis: [BX] vagy [BP]
Index: [SI] vagy [DI]
Bázis+relatív: [BX+rel] vagy [BP+rel]
Index+relatív: [SI+rel] vagy [DI+rel]
Bázis+index: [bázis+index]
Bázis+index+relatív: [bázis+index+rel]
Alapértelmezések
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]
Helyes címzések
[12h*34h+56h] (közvetlen címzés)
ES:[09D3h]
CS:[SI-500d]
SS:[BX+DI+1999d]
DS:[BP+SI]
Hibás címzések
[AX] (az AX regiszter nem használható)
[CX+1234h] (a CX regiszter sem használható címzésre)
[123456789ABCh] (túl nagy az érték)
[SI+DI] (két indexreg nem használható egyszerre)
[SP+BP] (az SP regiszter nem használható)
IP:[0000h] (IP nem használható így)
[IP] (az IP regiszter nem érhet el)
Összeadas, szorzás, címzések...
Rodek 10. fejezet.
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
mov       ax, 5h         ;ax=0005h, ip=köv.ut.
add       al, 0001h      ;ax=0006h, p=1, ip=köv.ut.
mov       ax, 5h
add       al, [0001h]    ;ax=0025h, ip=köv.ut.
mov       ax, 5h
mov       bx, 6h
add       ax, bx         ;ax=000Bh, ip=köv.ut.
mov       ax, 5h
mov       bx, 6h
add       ax, [bx]       ;ax=FEF5h, s=p=1, ip=köv.ut.
mov       ax, 0102h
mov       cx, 0003h
mul       cl             ;ax=0006b, p=1, ip=köv.ut.
mov       ax, 0102h
mov       cx, 0003h
mul       cx             ;dx:ax=00000306b, p=1
mov       ax, 0102h
mov       si, 0003h      ;ds:0003= 9Fh
mul       mul byte ptr [si] ;ax=013Eb, c=o=1
mov       ax, 0602h
mov       si, 0003h      ;ds:0003= 9F 00h
mul       mul word ptr [si] ;dx:ax=0003 BB3Eb, c=o=1
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.
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ása
Í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 dx:ax-ben, ill. ha ax kezdetben 0.
;kód szegmens
kod  segment para public 'CODE'
     assume cs:kod, ds:adat, ss:verem, es:nothing
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ő
                        ;dx:ax ertéke a faktoriális
kod  ends

;az adatszegmens
adat segment para public 'DATA'
adat ends

;verem szegmens
verem segment para stack
verem ends
     end

4. Gyakorlat

Skalárszorzat
Írjunk olyan programot, amely kiszámítja két vektor skalárszorzatát.
;kód szegmens
kod  segment para public 'CODE'
     assume cs:kod, ds:adat, ss:verem, es:nothing
     mov       ax, adat
     mov       ds, ax

     mov       dx, 0         ;részösszeg
     xor       ax, ax
     mov       al, offset v1
     mov       si, ax
     mov       al, offset v2
     mov       di, ax
     mov       cl, [len]
ciklus:
     mov       al, [si]      ;első vektor
     mul       byte ptr [di] ;szorozva a másodikkal
     add       dx, ax        ;hozzáadjuk a részösszeghez
     inc       si            ;vektor köv. eleme
     inc       di
     dec       cx
     cmp       cx, 0
     jne       ciklus
kod  ends

;az adatszegmens
adat segment para public 'DATA'
v1   db 1,2,3,4
v2   db 2,4,3,1
len  db 4
adat ends

;verem szegmens
verem segment para stack
     dw 100 dup(?)
verem ends
     end
Turbo Debugger
Turbo Debugger 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.obj

5. Gyakorlat

Üres assembly program
Az op. rendszer úgy hívja meg a főprogramokat, hogy a CS és IP a program végén levő END utasításban megadott címke szegmens és offset címét tartalmazza. A visszatérés szegmens címe DS-ben van, offsetje pedig mindig 0;
A forrás letölthető: ures.asm.
;kód szegmens
kod     segment   para public 'code'
        assume    cs:kod,ds:adat,ss:verem,es:nothing

start:  push    ds        ;visszatérés segmensének mentése
        xor     ax, ax    ;offset mindig 0
        push    ax        ;visszatérés offsetjének mentése

        mov     ax, adat  ;mert nincsen 'mov ds, adat'
        mov     ds, ax

        ;főprogram kezdődik
        ;főprogram vége

vege:   retf              ;visszatérés a hívó programhoz
kod     ends

;adat szegmens
adat    segment   para public 'data'
adat    ends

;verem szegmens
verem   segment   para stack
        dw      64 dup (0) ;helyfoglalás
verem   ends

end     start
Maximum keresés
Keressük meg a 'szoveg'-ben tárolt, 0-val végződő string legnagyobb elemét. Az eredményt a 'max' nevű változóban tároljuk.
A teljes forrás letölthető: 001max.asm.
        mov     bx,offset szoveg
ciklus: mov     al,[bx]
        cmp     al,0
        je      vege
        cmp     al,max
        jbe     kov
        mov     max,al
kov:    inc     bx
        jmp	    ciklus
Házi feladat
Módosítsuk a maximum kereső programot minimum kereső programra! Azaz Keressük meg a legkissebb elemet.

Egészítsük ki a maximum kereső programot, hogy a legnagyobb betű első előfordulási helyét a "pos" változóban tároljuk!

6. Gyakorlat

Számoljunk betűket
Számoljuk meg, hogy hány darab "a" betű van egy karakterláncban!

A teljes forrás letölthető: 002betu.asm.
        ;főprogram kezdete
        mov     al, 0     ;al-ben lesz az akt. betű
        mov     cl, 0     ;számláló
        mov     si, offset text
kov:    mov     al, [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, source ;kell-e számolni
        jne     nemszamol ;ha nem kell
        inc     cl        ;noveli a számlálót
nemszamol:
        inc     si
        jmp     kov

vege:   mov     n, cl     ;n-be rakjuk a végeredményt
Cserebere
Cseréljük ki egy 0-val záródó karakterlánc minden "a"-betűjét "b" betűre!

A teljes forrás letölthető: 003csere.asm.
        ;főprogram kezdete
        mov     ax, 0
        mov     bl, dest
        mov     si, offset text
kov:    mov     al, [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, source ;kell-e cserélni
        jne     nincscsere ;ha nem kell ugrik
        mov     [si], bl  ;csere
nincscsere:
        inc     si
        jmp     kov
Házi feladat
Módosítsuk a "Betű számoló" programot, hogy több betűt is meg tudjon számolni.

Módosítsuk a betűszámoló programot, hogy 3 tömböt kezeljen: az egyik az input sztring, mint korábban, a másik, hogy melyik betűkre vagyunk kíváncsiak, ill. a harmadik tömb azt mondja meg, hogy a második tömb betűi hányszor fordulnak elő. A 2. és a 3. tömb elemszáma megegyezik. (Nehéz)

Módosítsuk a "Cserebere" programot, hogy több betűt is ki tudjon cserélni!

Módosítsuk a "Cserebere" programot, hogy 3 tömbot kezeljen: az első maga az input sztring, a második hogy melyik betűt kell kicserélni, a harmadikban pedig hogy melyik betűre. A 2. és a 3. tömb elemszáma megegyezik.

7. Gyakorlat

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 endp
Házi feladat
Írjunk olyan programot, amely kiír 0-val záródó karakterláncokat a képernyőre a fenti eljárások felhasználásával! Megoldás letölthető: 004haho.asm.

8. Gyakorlat

Fordítsuk meg a szöveget
Írjunk egy olyan eljárást, ami egy sztringet megfordít! Azaz a karakterei fordított sorrendben lesznek az eljárás meghívása után.

A teljes forrás letölthető: 005ford.asm.
;eljárás ami megfordít egy stringet.
;a string elejét SI mutatja
strfordit proc
        push    si        ;regiszterek mentése
        push    di

        mov     di, si    ;di fog mutatni a string végére
keresciklus:
        mov     al, [di]  ;de, először meg kell 
        cmp     al, 0     ;keresnünk a végét
        je      keresvege ;ha igen ugrik
        inc     di        ;di mutasson a következő betűre
        jmp     keresciklus ;ugrás a keresés elejére
keresvege:

        mov ax, di
        sub ax, si
        cmp ax, 2
        jbe forditvege
        dec di

csereciklus:
        mov     al, [si]
        mov     ah, [di]
        mov     [si], ah
        mov     [di], al
        inc     si
        dec     di
        cmp     si, di
        jb      csereciklus
forditvege:
        pop     di       ;regiszterek visszatöltése
        pop     si
        ret
strfordit endp
Házi feladat
Írjunk olyan eljárást, amely megfordít egy sztringet a verem segítségével. A stringet teljes egészében bepakolja a verembe, majd kiolvassa onnan. Megoldás letölthető: 006vford.asm.

Írjunk olyan eljárást, ami egy sztring szavait egyenként fordítja meg. A szavak egymástól szóközzel vannak elválasztva.

Írjunk olyan eljárást, amely egy bájtokból/word-ök álló vektor (tömb) elemeinek összegét, átlagát (egészosztás), szórását számolja ki.

9. Gyakorlat

Paraméterek veremben történő átadása
Írjunk olyan eljárást, amely kiszámítja két vektor skalárszorzatát. Az eljárás a két vektor offset-címét és hosszukat a veremben várja.

Teljes program forrása letölthető: 007param.asm.
        xor     dx, dx    ;részeredmények
        mov     cx, [bp+4]
        cmp     cx, 0     ;jcxz skalvege is eleg lenne
        je      skalvege  ;ez a két utasítás helyett
        mov     si, [bp+6]
        mov     di, [bp+8]
        xor     bx, bx    ;tömbindex

ism:    mov     al, [si + bx]
        mul     byte ptr [di + bx]
        add     dx, ax
        inc     bx
        loop    ism       ;dec cx; cmp cx, 0; jne ism

        mov     ax, dx    ;végeredmény ax-be
Házi feladat

10. Gyakorlat

strstr
Írjunk olyan eljárást, amely egy szringben megkeresi egy másik string első előfordulását.

Teljes program forrása letölthető: 008str.asm.
Házi feladat
Írjunk olyan eljárást, amely megkeresi egy sztringben egy másik string utolsó előfordulását.

Írjunk olyan eljárást amely megszámolja, hogy egy sztringben hányszor fordul elő egy másik string.

ZH típusfeladatok