Professional Documents
Culture Documents
hu
Bevezetés
Ahhoz, hogy megértsük mit jelent az assembly nyelvű programozás, vissza kell
kanyarodnunk a legelsô számítógépekhez. Ezen gépek processzorai a bináris
számrendszer két számjegyének a 0 - nak és az 1 - nek megfelelô
feszültségszinteket voltak képesek értelmezni, és az így kapott gépi kódú
?
utasítást végrehajtani. Bármennyit is fejlôdött a számítástechnika azóta, a mai
processzorok többsége is csak a digitális jeleket képesek értelmezni.
Ezért a fejlôdés során minden gépi kódnak egy rövid - többnyire 3 vagy 4
betűs - szimbólumsorozatot feleltettek meg. Ezeket a gépi kódú utasításokat
reprezentáló karaktersorozatokat mnemonikoknak nevezzük. Ezekután a
processzor programozása úgy történt, hogy - egy szövegszerkesztô segítségé-
vel - a gépi kódok helyett a nekik megfelelô mnemonikokat írtuk le. Ez a gépi
nyelvű programozás máskeppen szólva az assembly nyelvű programozás.
Ezzel kapcsolatban három lényeges dolgot kell megállapítanunk. Az elsô az
az, hogy az assembly nyelv továbra is lefedi az illetô processzornak az utasítás
készletét.
Forrás: http://www.doksi.hu
Bevezetés
A második az az, hogy - mivel a processzor továbbra is csak a gépi kódot
képes értelmezni - kell egy szoftver eszköz, amely az assembly kódot a vele
egyenértékű gépi kóddá alakítja. Ezt az eszközt assemblernek hívják.
Késôbb szót ejtünk arról, hogy konkrétan melyik lesz az az assembler amit
használni fogunk és arról is, hogy hogyan történik az adat illetve a kód terület
elkülönítése.
Bodlaki Tamás
Távoktatási jegyzet
10
Forrás: http://www.doksi.hu
Impresszumoldal
3
Forrás: http://www.doksi.hu
Elôszó
Elôszó
Az elsô kérdés amire választ keresünk az az, hogy miért hasznos az assembly
nyelvű ( gépi nyelvű ) programozás alapjaival megismerkednünk, amikor olyan
hatékony magasszintű programnyelvek állnak a rendelkezésünkre, mint a
PASCAL vagy a C ill. a C++ nyelv.
A válasz tehát úgy hangzik, hogy ott ahol nagyon kényesek a sebesség ill.
idôzítési viszonyok, ott továbbra is létjogosultsága van a gépi nyelvű
programozásnak.
10
Forrás: http://www.doksi.hu
Minden fejezet elején egy rövid összefoglaló található, amely tömören közli,
hogy mit fog tartalmazni a fejezet. Ezt az összefoglaló részt a bekeretezett ∑
jelzi. Ezután következik a fejezet anyaga. A példaprogramok ezzel a
betűtípussal készültek, és keret veszi körül ôket.
Jelen elôszót egy bevezetés követi, amely definiálja a gépi kód, gépi nyelv
fogalmakat, ill. elhelyezi az assembly nyelvet a programozási nyelvek között.
5
Forrás: http://www.doksi.hu
Elôszó
10
Forrás: http://www.doksi.hu
∑
A fejezetben olyan mélységig lesz szó a processzor memória kezelésérôl,
amely a programozáshoz elengedhetetlenül szükséges. Azt nézzük meg, hogy
hogyan lehet 16 bites regiszterekkel 20 bites címet elôállítani. A fejezet
második része a processzor regisztereit tárgyalja, megemlítve a processzor
működésében illetve programozásában betöltött szerepüket. Szó lesz még az
assembly nyelvű programfejlesztés során alkalmazott software eszközökrôl.
Legyen például a szegmenscím 0040h, az offset 0002h. Ekkor a cím így irható
fel : 0040:0002. Ebben az esetben a szegmenscímet 16-tal szorozva 0400h
értéket kapunk. Ehhez hozzáadva a 0002h értéket 0402h fizikai cím adódik. A
h betű a hexa számrendszert jelöli. Ugyanez a fizikai cím áll elô a 0030:0102
alakból ami azt jelenti, hogy a szegmensek átlapolhatják egymást. Ezt a
jelenséget egy programon belül a szegmensregiszterek használatával védhetjük
ki.
Forrás: http://www.doksi.hu
12345h = 1000:2345
AH AX AL
BH BX BL
CH CX CL
DH DX DL
SI
DI
BP
SP
IP
F
CS
DS
ES
SS
Az AX regiszter :
12
Forrás: http://www.doksi.hu
A BX regiszter :
A CX regiszter :
A ciklus számláló szerepét tölti be, úgynevezett LOOP ciklus esetén. A két
elôzô regiszterhez hasonlóan felezhetô. Emellett általános célú regiszter is.
A DX regiszter :
Amellett, hogy általános célú regiszter, kitüntetett szerepe van a verem (stack)
címzésénél. Ilyenkor az SS regiszterhez képest címzi a stack-et. A stack
aktuális elemének az offset címét tartalmazza.
13
Forrás: http://www.doksi.hu
Az F ( Flag ) regiszter :
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
X X X X O D I T S Z X A X P X C
1. X : Kihasználatlan.
3. X : Kihasználatlan.
5. X : Kihasználatlan.
14
Forrás: http://www.doksi.hu
12. X : Kihasználatlan.
13. X : Kihasználatlan.
14. X : Kihasználatlan.
15. X : Kihasználatlan.
15
Forrás: http://www.doksi.hu
SP 92
elem3
94
elem2
96
elem1
98
elem0 100
Ez a stack például ami az ábrán látható 100 byte méretű. Elôszôr az elem0-t,
majd az elem1-et, elem2-ôt és végül az elem3-at írtuk bele. Ekkor az SP
regiszter értéke 92 lesz. A legelsô olvasás elem3-at fogja kiolvasni, így az SP
új értéke 94 lesz. A stack többek között nélkülözhetetlen a késôb tárgyalandó
szubrutin hívás megvalósításánál.
16
Forrás: http://www.doksi.hu
Korábban volt róla szó, hogy szükségünk lesz egy olyan eszközre, amely az
assembly nyelvű programunkat gépi kóddá fordítja le. Ennek a programnak
általában assembler a neve. A jegyzetben szereplô összes programot a
BORLAND C++ 3.1 programrendszer assemblerével fordítottam le. Ennek a
programnak a neve : TASM .EXE (Turbo Assembler). A TASM programnév
nélkül elindítva kiírja a képernyôre a rövid helpjét ami tartalmazza a
kapcsolóit. Mi fôleg a /zi kapcsolókat fogjuk használni a nyomkövetés
használatához. A TASM alapértelmezés szerint .ASM kiterjesztésű állományt
vár bemenetként.
Szükségünk lesz egy olyan programra is ami a gépi kódú programból (.OBJ)
futattható állományt szerkeszt (.EXE). Jelen rendszerben ez a TL I NK .EXE
(Turbo Linker) nevű program. Leggyakrabban a /v kapcsolóját fogjuk
használni, lehetôvé téve a hibakeresést.
17
Forrás: http://www.doksi.hu
18
Forrás: http://www.doksi.hu
Σ
Ebben a fejezetben elôször is különbséget teszünk utasítás és direktíva között,
majd egy egyszerű assembly programocska kapcsán megismerkedünk az
assembly program felépítésével és az egyszerűsített direktívákkal. Szó lesz az
alkalmazható memóriamodellekrôl, az adatdefinícióról, illetve az alapvetô
DOS szolgáltatások hívásáról, valamint az általunk használt alapvetô adat-
típusok definiálásáról.
1. sz. példaprogram :
;
; Egyszerű assembly példaprogram
;
.MODEL small
.STACK 100h
.DATA
;
uzenet db 'Hajrá Ferencváros',13,10,'$'
;
.CODE
mov ax, @data ; A DS regiszter feltöltése
mov ds,ax ; Az adatszegmens kezdôcímével
;
mov ah,9 ; Az üzenet kiiratása
mov dx,OFFSET uzenet
int 21h
;
mov ah,4ch ; Visszatérés a DOS-hoz
int 21h
END
Forrás: http://www.doksi.hu
A .M ODEL small kifejezés tehát azt jelenti, hogy mi a small modellt fogjuk
használni. Ez a jegyzetben található összes mintapéldára igaz.
A .STACK 100h jelenti azt, hogy a programunk által használt stack méretét
100h azaz 256 byte-ban határozzuk meg. A stack-et változók tárolására,
paraméterátadásra ill. szubrutinhívásra használja - többek között - a program.
19
Forrás: http://www.doksi.hu
!
kódszegmens) szétválasztása. A .DATA direktíva jelenti az adatterület
kezdetét. Ezután a direktíva után definiálhatjuk adatainkat. Hiába egyezik
meg valamely adat a processzor valamelyik utasításának kódjával, akkor
sem kerül végrehajtásra, mert az adatszegmensben foglal helyet. A fordító
mindent adatnak értelmez, egészen a .CODE direktíváig. Amit ezután írunk az
vagy direktíva, vagy címke, vagy utasítás de semmiképpen sem adat.
20
Forrás: http://www.doksi.hu
!
A DOS-hoz való visszatérést mindig el kell végezni. Ennek elhagyása
ki-számíthatatlan hibajelenségeket eredményez !
A már megismert 9. illetve 4ch sorszámú DOS szolgáltatásokon kívül még két
szolgáltatást fogunk gyakran használni. Ezek az 1. illetve a 2. sorszámú DOS
szolgáltatások.
21
Forrás: http://www.doksi.hu
.DATA
karakter db ; karakter nevű 1 byte-os változó
index dw ; index nevű 2 byte-os változó
...
22
Forrás: http://www.doksi.hu
Például :
A dup operátor láthatóan arra alkalmas, hogy az elôtte álló számú adott típusú
adategységnek ( byte vagy word ) a zárójelek közötti kezdôértéket adja. Ha a
kezdôérték közömbös számunkra, akkor a ‘ ?’ karaktert használjuk.
Attól, hogy a matr ix nevű változó 3 sorban illetve 3 oszlopban lett iniciali-
zálva, attól még ugyanúgy sorfolytonosan tárolódnak az elemei, mintha azt
írtuk volna, hogy : matr ix dw 1,2,3,4,5,6,7,8,9. !
Azt, hogy vektorként vagy mátrixként fogjuk kezelni, azt majd az indexelés
módja fogja eldönteni !
23
Forrás: http://www.doksi.hu
04. Hogyan adhatjuk meg egy programon belül az általunk használni kívánt
stack terület méretét ?
07. Általában hogyan tudunk elérni egy DOS szolgáltatást, konkrétan mi-
lyen DOS szolgáltatásokat ismer ?
12. Készítsen egy olyan programot amely kiír egy üzenetet a képernyôre,
majd egy soremelést ír ki, utána pedig még egy üzenetet ír ki a
képernyôre !
24
Forrás: http://www.doksi.hu
3. Ar itmetikai utasítások
Σ
fejezetben látott példa programnál bonyolultabb programokat is tudjunk írni.
Eôször a MOV értékadó utasítással, majd a fôbb aritmetikai utasításokkal is-
merkedünk meg. Ezt követôen konverziós illetve egyéb utasítások tárgyalása
következik.
[<címke>] <utasítás | dir ektíva > [<oper andusok>] [<; megj egyzés>]
Mint látható, az utasítás formátum négy részbôl áll, ebbôl egy kötelezô, három
pedig opcionális. A részek leírása a következô :
Példa :
mov cx,10
Forrás: http://www.doksi.hu
3.2 A M OV utasítás
-
-
A kódszegmens regiszternek ( CS ) értéket adni.
Szegmensregiszterbôl szegmensregiszterbe írni.
!
- Konstans értéket szegmensregiszterbe írni.
- Különbözô típusú operandusokat használni.
Ezeken kívül nem fordulhat elô az az eset, hogy mindkét operandus memória
változó !
25
Forrás: http://www.doksi.hu
3. Aritmetikai utasítások
Az add utasítás a két operandusának összeadására szolgál. Hasonlóan a mov
utasításhoz itt is <op1> a cél- és <op2> a forrás operandus. Megfelel az
<op1> = <op1> + <op2> műveletnek. A két operandus típusa meg kell
egyezzen, valamint itt is érvényes az a megkötés, hogy nem lehet egyszerre
mindkét operandus memóriaváltozó. Konstans érték csak a forrás operandus
lehet. Az utasítás a következô flageket érinti :
- ZF = 1 ha az összeadás eredménye 0.
- SF = 1 ha az eredmény negatív.
Ezek után nézzük meg, hogy mikor kell használnunk az adc utasítást ! Abban
az esetben ha 32 bites mennyiségeket akarunk összeadni elôfordulhat, hogy az
alsó 16 bit összeadásakor átvitel keletkezik. Ekkor a CF értéke 1 lesz. Világos,
hogy a felsô 16 bit összeadásánál ezt a bitet is figyelembe kell venni, tehát a
sima add utasítást nem használhatjuk. Ilyenkor az adc használatára kerül sor !
Az adc utasítás az <op1> = <op1> + <op2> + [CF] műveletnek felel meg. Az
utasítás ugyanazokat a flageket érinti mint az add.
26
Forrás: http://www.doksi.hu
3.5 A CM P utasítás
27
Forrás: http://www.doksi.hu
3. Aritmetikai utasítások
int 21h
cmp al,13 ; <ENTER> - t billentyűztünk ?
3.6 Az I NC utasítás
28
Forrás: http://www.doksi.hu
3.10 A M UL és I M UL utasítások
29
Forrás: http://www.doksi.hu
3. Aritmetikai utasítások
Az imul utasítás két elôjeles mennyiséget szoroz össze. A műveleti szélesség
itt is kétféle lehet, mint a mul-nál, az operandusok elhelyezkedése is
tökéletesen megegyezik az elôzôekben leírtakkal.
3.11 A DI V és I DI V utasítások
30
Forrás: http://www.doksi.hu
Bár nem utasítás, de elég gyakran kell majd használnunk. Az offset operátor az
utána álló memória változó kezdôcímét állítja elô. A kezdôcím alatt a
szegmens kezdethez ( ds regiszter tartalma) képesti offset címet kell érteni.
31
Forrás: http://www.doksi.hu
3. Aritmetikai utasítások
05. Mi az azonosság illetve a különbség a SUB és a CMP utasítás
működését tekintve ?
09. Végezze el a következô szorzásokat : 30* 20, 300* 200, 3000* 2000,
30000* 20000 !
10. Végezze el a következô szorzásokat : -30* 20, -300* 200, -3000* 2000,
-30000* 20000 !
32
Forrás: http://www.doksi.hu
4. L ogikai utasítások
Σ
Ebben a fejezetben a logikai utasításokat mutatom be. Feltételezem, hogy a
tárgyalandó logikai utasítások igazságtáblájával tisztában van az olvasó !
Példa :
4.2 Az OR utasítás
bites minta 3. 4. ill. 5. számú bitjének az értékét kell megállapítanunk. Mivel
három bitrôl van szó, ez az érték elvileg lehet 111, 110, 101, 011, 100, 010,
001 és 000. Nyilván mindegyik érték különbözô információt hordoz.
2. sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
;
minta db 00101010b
info db 28h ; 00101000b ( erre vadászunk ! )
;
.CODE
mov ax, @data
mov ds,ax
;
mov ax,0
mov al,[minta] ; A gyakorlatban valamilyen
; periféria küldi.
and al,00111000b ; Itt történt meg a maszkolás !
cmp al,[info]
;
; Az összehasonlítás eredményétôl függô
; program sorok
;
mov ah,4ch
int 21h
END
4.2 Az OR utasítás
Szintaxis : OR <op1>,<op2>
33
Forrás: http://www.doksi.hu
4. Logikai utasítások
34
Forrás: http://www.doksi.hu
35
Forrás: http://www.doksi.hu
4. Logikai utasítások
36
Forrás: http://www.doksi.hu
Ahhoz, hogy egy feltétel szerint el tudjunk ágazni két vagy több irányba - azaz
szelekciót tudjunk végrehajtani - , meg kell ismerkednünk a feltételnélküli és
feltételes ugró utasításokkal. Ebben a fejezetben a feltételnélküli és feltételes
ugróutasításokat tárgyaljuk.
! ( -127 ill. +128 byte ), ebben az esetben a j mp utasítás relatív cimzést használ.
Ez azt jelenti, hogy az ugrás távolsága elôjelesen hozzáadódik az IP regiszter
tartalmához, ezáltal megvalósul a vezérlésátadás.
Abban az esetben ha az ugrás helye távolabb van mint amit egy elôjeles byte-
on ábrázolni tudunk, abszolút cimzéssel hajtódik végre a j mp. Ez pedig azt
jelenti, hogy a cimkéhez tartozó offset cím kerül az IP regiszterbe, azaz símán
felülíródik az IP regiszter tartalma. A címkéhez tartozó offset cím a
szimbólumtábla alapján érhetô el.
37
Forrás: http://www.doksi.hu
38
Forrás: http://www.doksi.hu
39
Forrás: http://www.doksi.hu
3. sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
c1 db ?
c2 db ?
nagy12 db ' 1 > 2 ','$'
kis12 db ' 1 < 2 ','$'
egy12 db ' 1 = 2 ','$'
sorem db 0dh,0ah,'$'
.CODE
mov ax,@data
mov ds,ax
mov ah,1
int 21h
mov [c1],al ; Elsô karakter C1-ben
int 21h
mov [c2],al ; Második karakter C2-ben
;
cmp [c1],al ; Elsô összehasonlítva másodikkal
je egyen ; Ha egyenlôk, akkor ugrás EGYEN-re
jb k1_2 ; Ha elsô < második, akkor ugrás
; K1_2-re
40
Forrás: http://www.doksi.hu
05. Irjon programot amely három karaktert olvas be. Elsô lépésben döntse
el, hogy a három karakter közül melyik a legnagyobb. Második
lépésben rakja ABC sorrendbe a három karaktert, és így irassa ki ôket a
képernyôre !
41
Forrás: http://www.doksi.hu
08. Irjon programot, amely beolvas egy kétjegyű számnak megfelelô két
karaktert, és átalakítja számmá ! Például az ‘ 1’ ‘ 2’ -bôl 12-ôt csinál !
11. Irjon programot amely egy négyjegyű szám számjegyeit olvassa be,
majd elvégzi a számmá alakítást ! Ezután bontsa le megint
számjegyekre, és fordított sorrendben írja ki a számjegyeket a kép-
ernyôre.
42
Forrás: http://www.doksi.hu
Σ
A feltételnélküli és feltételes ugró utasítások ismertetése után a ciklusszervezô
utasításokkal ismerkedünk meg. A ciklusszervezô utasítások a harmadik
alapvetô programstruktúra - az iteráció - megvalósítására szolgálnak.
Segítségükkel tehát egy programrészlet végrehajtását többször is megismétel-
hetjük. Ebben a fejezetben mutatom be a Turbo Debugger ( TD.EXE )
használatát is.
A loop utasítás a dec cx, j nz cikl utasításokat valósitja meg ebben az esetben :
!
utasítás egy elôjeles byte-on ábrázolja az ugrás hosszúságát, tehát -127 byte-
nál többet nem lehet visszafelé ugratni ! Ennél hosszabb ciklusok tehát nem
Forrás: http://www.doksi.hu
mov cx,20
mov ah,1
;
beo_cikl: int 21h ; karakter az al-ben
mov [kar],al ; karakter a kar nevű változóban
cmp al,13 ; összehasonlítás az ENTER kódjával
loopne beo_cikl ; ha cx tartalma pozitív és nem e-
; gyenlô 13-mal, ( cx > 0 és ZF = 0 )
; akkor folytatás a beo_cikl címkén.
... ; a program folytatása
43
Forrás: http://www.doksi.hu
6. Ciklusszervezô utasítások
Létezik még egy feltételes ugró utasítás aminek az ismertetése mégis ide
kivánkozik. Ez a j cxz utasítás. Szintaktikája a következô : jcxz <cimke>.
Abban az esetben ha a cikluba való belépés elôtt cx tartalma nulla és ezt az
utasítást leírjuk, akkor a cimkére adódik a vezérlés. A j cxz segítségével tehát
átugorhatunk egy olyan ciklust, amelynek ciklusváltozója - azaz a cx regiszter
- nulla.
44
Forrás: http://www.doksi.hu
4. sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
szam DW 0
.CODE
mov ax,@data
mov ds,ax ; DS regiszter inicializálása
;
;
xor ax,ax ; AX regiszter nullázása
mov ah,1
int 21h ; Egy karakter bekérése
;
xor ah,ah ; AH regiszter nullázása
sub al,48 ; Numerikus értékké alakítás
;
xchg ah,al ; Az integer (AX) megfordítása
;
mov [szam],ax
45
Forrás: http://www.doksi.hu
6. Ciklusszervezô utasítások
Mielôtt elindítanánk a programunkat, jelöljük ki megfigyelésre a szam
változót illetve az ax, al, ah regisztereket. Ezt úgy tehetjük meg, hogy a
programunkban a kurzort - az egér, vagy a billentyűzet segítségével - ráállítjuk
a kívánt változó vagy regiszter nevére és lenyomjuk a <CTRL> <W>
billentyűkombinációt. Ezen művelet hatására a képernyô alján rendre
megjelennek a kijelölt regiszterek illetve a szam változó nevei, valamint az
éppen aktuális értékük.
- Utolsó elôtti lépésként kiírjuk ezt azt értéket a szam változóba, majd
visszadjuk a vezérlést a DOS-nak.
! az IP regiszter inicializálását !
Lehetôség van arra is, hogy a programnak egy részét egy lépésben, míg a
fennmaradó részt lépésenként futtassuk. Állítsuk a szövegkurzort a mov
[szam],ax utasításra és nyomjuk le az <F4> billentyűt. Ennek hatására egy
lépésben történik meg a karakter bekérése, a 48 kivonása az al regiszterbôl
valamint az ah és al megcserélése, majd a program végrehajtása megáll az
általunk kijelölt utasításon és innét lépésenként hajthatjuk végre. Ez a
46
Forrás: http://www.doksi.hu
5. sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
;
szj dw 0
;
.CODE
mov ax,@data
mov ds,ax
;
mov cx,70
xor ax,ax
mov dx,0 ; DX-ben számoljuk a számjegyeket
mov ah,1
;
beolv: int 21h
cmp al,'0'
jb nem ; Ha kisebb mint '0', akkor nem számjegy
cmp al,'9'
ja nem ; Ha nagyobb mint '9', akkor sem számjegy
;
inc dx ; Ha egyik sem tejesül akkor számjegy volt !
nem: cmp al,13 ; ENTER-re vizsgálunk
loopne beolv
;
mov [szj],dx
;
mov ah,4ch
int 21h
END
47
Forrás: http://www.doksi.hu
6. Ciklusszervezô utasítások
48
Forrás: http://www.doksi.hu
Σ
Az elôzô fejezet alapján rendelkezésre állnak a vezérlésátadó uatsítások is. Az
igazán hatékony programok elkészítését többek között azonban az gátolja,
hogy csak egyszerű változókat tudunk kezelni az eddig tanultak alapján. A
most következô fejezetben megismerkedünk az i8086-os processzor memória
címzési módjaival, amelyek a következôk : közvetlen operandusú, direkt,
indirekt, indexelt. Ezután képesek leszünk összetet adatokkal ( vektorok,
mátrixok ) dolgozni.
Látható, hogy ezzel a két címzési móddal nem tudnánk kezelni egy vektort,
ugyanis egyik móddal sem tudunk indexelni. Az az eljárás pedig, hogy a vek-
tor mindegyik elemét egyszerű változóként kezeljük, gyakorlatilag megvaló-
síthatatlan. A következô két címzési mód teszi lehetôvé az összetett adatszer-
kezetek kezelését.
.DATA
adat2 db ‘ 12345’
.
. ; további adatdefiníciók
.
.CODE
.
. ; utasítások
.
mov si,OFFSET adat2
.
. ; utasítások
.
mov ah,2
mov cx,5
kiir: mov dl,[si] ; kiiratjuk az adat2 karakter-
int 21h ; vektor öt elemét.
inc si
loop kiir
49
Forrás: http://www.doksi.hu
BX SI
50
Forrás: http://www.doksi.hu
BP DI
6. sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
51
Forrás: http://www.doksi.hu
mov cx,si
mov si,0
;
konv: ; Itt kezdôdik az átalakítás
mov al,kars[si]
cmp al,'a'
jb n_kis
cmp al,'z'
ja nkis
sub al,20h ; A kisbetű és a nagybetű ASCII
; kódja között 20h a különbség
nkis: mov nagy[si],al
inc si
loop konv
52
Forrás: http://www.doksi.hu
7. sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
;
v1 dw 1,2,3,4,5,6,7,8,9,10
v2 dw 1,2,3,4,5,6,7,8,9,10
v3 dw 10 dup(0)
;
.CODE
mov ax,@data
mov ds,ax
;
mov si,0
mov cx,10
;
ad:
mov ax,v1[si]
add ax,v2[si]
mov v3[si],ax
inc si ; Az SI indexregisztert kettôvel
inc si ; kell növelni !
loop ad
;
mov ah,4ch
int 21h
END
8 sz. példaprogram :
53
Forrás: http://www.doksi.hu
9 sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
innen db 'Lisztes berúgta elsô Bundesliga gólját !',0
ide db 80 dup(?)
hossz dw 0
.CODE
mov ax,@data
mov ds,ax
;
mov si,0
hossza: ; Másolandó string hosszának megállapítása
mov al,innen[si]
inc si ; SI-ben lesz a hossza
cmp al,0
54
Forrás: http://www.doksi.hu
10 sz. példaprogram :
.MODEL small
.STACK 100h
.DATA
;
matrix DB '1','2','3'
DB '4','5','6'
DB '7','8','9'
elemsz DW 3
sorem DB 0dh,0ah,'$'
;
55
Forrás: http://www.doksi.hu
56
Forrás: http://www.doksi.hu
04. Hogyan tudjuk “ kivédeni” azt, hogy az i8086 assembly-ben nem létezik
pointeraritmetika ?
07. Irjon programot amely bekér két egyenlô hosszú stringet. ( Maximum
40 karakter hosszút ). Állapítsa meg, hogy melyik string a nagyobb
illetve egyenlôek-e ! A megállapítást irassa is ki a stringekkel együtt !
( Az egyik string akkor nagyobb mint a másik, ha az adott pozición
nagyobb ASCII kódú karakter áll mint a másikban ).
08. Bôvítse úgy a 07. számú programot, hogy alkalmas legyen két string
viszonyának megállapítására akkor is, ha azok nem egyenlô hosszúak.
09. Irjon programot, amely összefűz két C típusú stringet olymódon, hogy
az elsôt bemásolja egy célstringbe, majd utána fűzi a másodikat. Az
eredmény irassa ki !
10. Irjon programot, amely összefűz két C típusú stringet olymódon, hogy
az elsô string egy karakterét bemásolja egy célstringbe, majd utána a
második string egy karakterét. Elôszö a két string lehet egyenlô hosszú,
majd próbálja meg különbözô hosszú stringekkel megoldani a feladatot!
Az eredményt irassa ki !
12. Képezze két 10 elemű integer vektor skaláris szorzatát. A szorzat ered-
ményét a TD-vel tekintse meg !
13. A 10. sz. példaprogram alapján indexeljen egy 5x5-ös integer mátrixot.
Az aktuális elemet írja az ax regiszterbe és a TD-vel tekintse meg !
57
Forrás: http://www.doksi.hu
∑
A fejezetben szó lesz a balra illetve jobbra történô bitléptetésrôl, illetve
rotációról egy adott byte-on, vagy szón belül. Megtárgyaljuk ezek különbözô
válfajait, úgymint aritmetikai léptetés illetve rotáció a CF-en keresztül. A
fejezetet a flagekkel kapcsolatos utasítások ismertetése zárja.
0 1 1 0 0 1 1 0 1
1 1 0 0 1 1 0 1 0
1 1 0 0 1 1 0 1 0
0 1 1 0 0 1 1 0 1
1 1 1 0 0 1 1 0 1
58
Forrás: http://www.doksi.hu
mov al,11001100b
mov cl,4
shr al,cl
0 1 1 0 0 1 1 0 1
1 0 0 1 1 0 1 1
59
Forrás: http://www.doksi.hu
mov al,11001100b
mov cl,4
;
shl al,cl
1 1 0 0 1 1 0 1 0
1 1 1 0 0 1 1 0
60
Forrás: http://www.doksi.hu
0 1 1 0 0 1 1 0 1
mov al,11001100b
mov cl,4
;
shl al,cl
CLC CF = 0
CMC CF = NOT CF
STC CF = 1
CLD DF = 0
STD DF = 1
CLI IF = 0
STI IF = 1
.MODEL small
.STACK 100h
.DATA
kod1 db 00001101b
kod2 db 00101000b
ht dw 0
61
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
be db 'Kérem a karaktert : ','$'
kar db ?
prot db 'A soros protokoll : ','$'
sorem db 0dh,0ah,'$'
.CODE
mov ax,@data
mov ds,ax
;
mov ah,9
mov dx,OFFSET be
int 21h
mov ah,1 ; A karakter beolvasása
int 21h
mov [kar],al
;
62
Forrás: http://www.doksi.hu
63
Forrás: http://www.doksi.hu
64
Forrás: http://www.doksi.hu
Σ
Ebben a fejezetben megismerkedünk a szubrutinok szervezésével és használa-
tával. A szubrutinok önálló alprogramok, amelyekre meghatározott hívási
mechanizmus segítségével adhatjuk rá a vezérlést. A hívó programba való
visszatérés is meghatározott mechanizmus szerint történik. Rokon fogalom a
C-ben a függvény fogalma.
sub_név PROC
.
.
.
utasítások
.
.
.
ret
sub_név ENDP
call sub_név
65
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
66
Forrás: http://www.doksi.hu
Ahhoz, hogy a stackbe írni illetve onnan olvasni tudjunk, két utasítást kell
megismernünk, de elôbb nézzük meg a globális változó használatát. A C
nyelven globális változó alatt a main() elôtt definiált változót értjük, ami az
egész forrásprogramra nézve látható. A mi esetünkben az adatszegmensben
definiált változó látható az egész programra nézve, tehát minden további
nélkül használhatjuk egy szubrutinban.
67
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
memóriaváltozó. Az utasítások a flageket nem érintik. A következô kis
példaprogramot érdemes TD alatt lefuttatni úgy, hogy közben a VIEW
menübôl a CPU panelt választjuk, és ott a jobb alsó sarokban figyeljük a stack
helyzetének alakulását.
.MODEL small
.STACK 100h
.DATA
adat dw 0
;
.CODE
mov ax, @data
mov ds,ax
;
mov ax,1
mov bx,2
mov [adat],3
;
push ax
push bx
push [adat]
;
mov ax,0 ; Kinullázzuk ôket, hogy ellenôrizni
mov bx,0 ; tudjuk a kiolvasás helyességét.
mov adat],0
;
pop [adat]
pop bx
pop ax
;
mov ah,4ch
int 21h
END
A fôpr ogr am :
.
.
.
push ax ; Az ax-ben lévô paraméter a stackbe kerül
call szubrut5 ; Meghívjuk a szubrutint
68
Forrás: http://www.doksi.hu
96
OFFSET R. A. 98
AX 100
A szubr utin :
szubrut5 PROC
push bp ; BP-t a stackbe mentjük
mov bp,sp ; Most BP értéke is 94
.
.
.
mov bx,[bp+4] ; Indexelt címzéssel érjük el a paraméterün-
; ket, amely most a BX-be került.
.
.
.
pop bp ; Hatására a stack teteje a BP regiszterbe író-
; dik és az SP értéke 96 lesz.
ret ; Hatására a stack tetejérôl az R. A. az IP
;regiszterbe íródik, és megtörténik a
69
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
;vezérlés visszaadása a hívóprogramra. Az
;SP értéke 98 lesz.
szubrut5 ENDP
70
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
szam DW 334
ide DB 5 DUP (20h)
vege LABEL BYTE
DB 0dh,0ah,'$'
;
.CODE
mov ax,@data
mov ds,ax
;
mov ax,[szam] ; Paraméterátadás regiszteren mov bx,OFFSET
vege - 1 ; keresztül
mov cx,5
call cnts
;
mov bx, OFFSET ide
call prst
;
mov ah,4ch
int 21h
cnts PROC
cnvlp:
sub dx,dx
div si ; Maradék a DX-ben
add dl,'0' ; Most konvertáltuk karakterré
mov [bx],dl ; Kiirjuk az aktuális címre
dec bx
71
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
and ax,ax ; Ha 0 az AX tartalma, akkor vége
jz szokoz
loop cnvlp
szokoz:
ret
cnts ENDP
prst PROC
push ax
push dx
;
mov ah,9
mov dx,bx
int 21h
;
pop dx
pop ax
ret
prst ENDP
END
9.4 K ész szubr utinok szer kesztése, saj át könyvtár ak létr ehozása.
72
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
; Adatdefiníciók
.CODE
EXTRN cnts:PROC
kezd:
;
; Utasítások
;
END kezd
PUBLIC cnts
cnts PROC
;
; Utasítások
;
cnts ENDP
73
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
2. tasm al_prg[.asm]
1. tasm f_cnts[.asm]
2. tasm f_prst[.asm]
74
Forrás: http://www.doksi.hu
szam DW 1
ide DB 5 DUP (20h)
vege LABEL BYTE ; Itt jelöljük meg az
DB 0dh,0ah,'$' ; IDE utáni byte-ot.
;
.CODE
prgstart:
mov ax,@data
mov ds,ax
;
xor ax,ax
mov ax,[szam]
mov BYTE PTR[szam],ah ; Ez a két sor a csere
mov BYTE PTR[szam+1],al
;
mov ax,[szam] ; Átadjuk a számot
75
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
; szubrutint
mov ah,4ch ; Visszaadjuk a vezér-
int 21h ; lést a DOS-nak.
;
mov si,10
cnvlp: sub dx,dx
div si
add dl,'0' ; Most konvertáltuk karakterré
mov [bx],dl
dec bx
and ax,ax
jz szokoz
loop cnvlp
szokoz:
ret
cnts ENDP
push ax
push dx
;
mov ah,9
mov dx,bx
int 21h
pop dx
pop ax
ret
prst ENDP
END prgstart
76
Forrás: http://www.doksi.hu
;
; INC_DEF.ASM : Include fileként használható assembly
; program
;
CR EQU 0dh ; Újsor
CHARIN EQU 1 ; Egy karakter bekérése
CHAROUT EQU 2 ; Egy karakter kiírása
STROUT EQU 9 ; String kiírása
RETDOS EQU 4ch ; visszatérés a DOS-hoz
77
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
mov BYTE PTR[szam],ah ; Ez a két sor a csere
mov BYTE PTR[szam+1],al
;
mov ax,[szam]
mov bx,OFFSET vege - 1
mov cx,5
call cnts
mov bx, OFFSET ide
call prst
mov ah,RETDOS ; Az INC_DEF.ASM-bôl
int 21h
END prgstart
; Megvalósitás függvénnyel
;
; Paraméterátadás : Változó címe a BX regiszterben
.MODEL small
.STACK 100h
.DATA
szam DW 1
ide DB 5 DUP (20h)
vege LABEL BYTE
DB 0dh,0ah,'$'
;
.CODE
EXTRN cnts:PROC
EXTRN prst:PROC
prgstart:
mov ax,@data
mov ds,ax
;
mov bx,OFFSET szam ; BX-ben átadjuk a megfor-
; dítani kívánt integer
; címét
call fordit ; Meghívjuk a szubrutint
mov ax,[szam]
mov bx,OFFSET vege - 1
mov cx,5
call cnts
mov bx, OFFSET ide
call prst
mov ah,4ch
int 21h
78
Forrás: http://www.doksi.hu
79
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
call prst
mov ah,4ch
int 21h
;
; Itt jön a fordit megvalósítása
;
; Megfordítandó szám címe a STACK-ben
;
fordit PROC
push bp
mov bp,sp
mov bx,[bp+4] ; BP+0 = bp értéke
; BP+2 = visszatérési cím
; BP+4 = paraméter címe
; BX-ben a szám címe van !
pop bp
ret
fordit ENDP
END
80
Forrás: http://www.doksi.hu
;
; Itt jön a fordit megvalósítása
;
;
fordit PROC
;
mov ax,[szam] ; AX-ben a szám van
;
mov BYTE PTR [szam],ah ; Ez a két sor a csere
mov BYTE PTR [szam+1],al
;
ret
;
fordit ENDP
END
A makró használatra csak egy nagyon rövid példát mutatok be jelezvén, hogy
ilyen lehetôség is rendelkezésünkre áll. A makró definíciója a következô :
81
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
.MODEL small
.STACK 100h
; Itt jön a makró definíció !
;
dosint MACRO intnum
mov ah,intnum
int 21h
ENDM
.DATA
nagy12 db '1 > 2','$'
nagy21 db '1 < 2','$'
egy12 db '1 = 2','$'
sorem db 0dh,0ah,'$'
82
Forrás: http://www.doksi.hu
02. Milyen formában kell megírni egy szubrutint, és mely utasítással kell
hivatkozni rá ?
83
Forrás: http://www.doksi.hu
9. Szubrutinok szervezése
03. Miért nem elég szubrutinhíváskor csak a vezérlésátadást megvalósítani?
06. Irjon programot, amely az 56. oldalon található 07. sz. feladatot
szubrutin alkamazásával oldja meg. A két string címét regisztereken
keresztül adja át a szubrutinnak !
07. Olja meg a 06. sz. feladatot úgy, hogy a két string címét a stacken
keresztül adja át !
08. Bôvítse úgy a 07. számú programot, hogy alkalmas legyen két string
viszonyának megállapítására akkor is, ha azok nem egyenlô hosszúak.
09. Irjon programot, amely az 56. oldalon található 09. sz. feladatot
szubrutin alkamazásával oldja meg. A két string címét elôször regisz-
tereken, majd a stacken keresztül adja át a szubrutinnak !
10. Irjon programot, amely az 56. oldalon található 10. sz. feladatot
szubrutin alkamazásával oldja meg. A két string címét elôször regisz-
tereken, majd a stacken keresztül adja át a szubrutinnak !
12. Képezze két 10 elemű integer vektor skaláris szorzatát. A szorzat ered-
ményét a most ne a TD-vel tekintse meg, hanem irassa ki a képernyôre!
A feladatot szubrutin alkalmazásával oldja meg, a paraméterátadás
módját Önre bízom !
84
Forrás: http://www.doksi.hu
∑
Ebben fejezetben elôször az i8086-os stringutasításait mutatom be, amelyek
csak a nevükben stringutasítások hiszen integer változókon is működnek. Az
utasítások közül az elsô három adatmozgató, a következô kettô pedig
összehasonlító. Ezután a stringműveleteknél használható prefixek működését
nézzük meg. A stringműveletek után példaprogramok következnek a DOS dá-
tumelôállító, illetve a BIOS színkezelô szolgáltatásaira
1. lods <cím>
2. lodsb
3. lodsw
1. stos es:<cím>
2. stosb
3. stosw
84
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
innen db 'Ezt a szöveget másoljuk !',0
SLEN EQU ($-innen) ; Az EQU az egyenlôség direktíva
ide db SLEN DUP(?)
db 0dh,0ah,'$'
;
.CODE
mov ax,@data
mov ds,ax
;
mov ax,SEG innen
mov ds,ax ; A forrás string címe a DS:SI-ben
mov si,OFFSET innen
;
mov ax,SEG ide
mov es,ax ; A cél string címe az ES:DI-ben
mov di,OFFSET ide
;
mov cx,SLEN
masol:
lods [innen]
stos es:[ide]
loop masol
;
xor ax,ax
mov ah,9
mov dx,OFFSET ide
int 21h
;
mov ah,4ch
int 21h
END
.MODEL small
.STACK 100h
.DATA
innen db 'Ezt a szöveget másoljuk !',0
SLEN EQU ($-innen)
ide db SLEN DUP(?)
85
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
;
innen db 'Ezt a szöveget másoljuk !',0
SLEN EQU ($-innen)
ide db SLEN DUP(?)
db 0dh,0ah,'$'
;
.CODE
86
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
;
innen dw 1,2,3,4,5
SLEN EQU ($-innen)/2 ; Az integer hossza miatt
ide dw SLEN DUP(?)
;
.CODE
mov ax,@data
mov ds,ax
;
87
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
innen dw 1,2,3,4,5
SLEN EQU ($-innen)/2
ide dw SLEN DUP(?)
;
.CODE
mov ax,@data
mov ds,ax
;
mov ax,SEG innen
mov ds,ax ; A forrás string címe a DS:SI-ben
mov si,OFFSET innen
;
mov ax,SEG ide
mov es,ax ; A cél string címe az ES:DI-ben
mov di,OFFSET ide
;
mov cx,SLEN
cld
masol:
lodsw
88
Forrás: http://www.doksi.hu
2. movsb
3. movsw
.MODEL small
.STACK 100h
89
Forrás: http://www.doksi.hu
xor ax,ax
mov ah,9
mov dx,OFFSET ide
int 21h
;
mov ah,4ch
int 21h
end
90
Forrás: http://www.doksi.hu
A scas utasítás az ES:DI-ben lévô címen tárolt byte vagy szó értékét hasonlítja
össze az al vagy az ax regiszter tartalmával. Az összehasonlítás kivonás
formájában történik meg, de az eredményt nem ôrzi meg a művelet, hanem
csak a flageket változtatja az eredménynek megfelelôen. Ezek a flagek a
következôk : CF, PF, AF, ZF, SF, OF. A művelet után a DI regisztert a
megfelelô módon változtatja az utasítás. Amennyiben byte-os összehasonlítást
akarunk végezni úgy a scasb alakot, amennyiben szavas összehasonlítást, úgy
a scasw alakot használjuk.
10.5 A CM PS utasítás
A cmps utasítás a DS:SI-ben lévô címen lévô byte vagy szó értékét hasonlítja
össze az ES:SI-ben tárolt címen lévô byte vagy szó tartalmával. Az érintett
flagek a következôk : CF, PF, AF, ZF, SF, OF. A művelet után az SI és a DI
regisztereket a megfelelô módon változtatja az utasítás. Amennyiben byte-os
összehasonlítást akarunk végezni úgy a cmpsb alakot, amennyiben szavas
összehasonlítást, úgy a cmpsw alakot használjuk.
91
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
innen db 'Ezt a szöveget másoljuk !',0
SLEN EQU ($-innen)
ide db SLEN DUP(?)
db 0dh,0ah,'$'
.CODE
mov ax,@data
mov ds,ax
;
mov ax,SEG innen
mov ds,ax ; A forrás string címe a DS:SI-ben
mov si,OFFSET innen
;
mov ax,SEG ide
mov es,ax ; A cél string címe az ES:DI-ben
mov di,OFFSET ide
;
mov cx,SLEN ; A forrás string hossza CX-ben
cld ; A D flaget nullázzuk, igy a növekvô
; indexek felé mozog a másolás
;
rep movsb ; A MOVSB egyik regiszterben sem he-
; lyezi el a byte-ot, igy a hosszát ; ismernünk
kell !
;
xor ax,ax
mov ah,9
mov dx,OFFSET ide
int 21h
;
92
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
innen dw 1,2,3,4,5
SLEN EQU ($-innen)/2
ide dw 5 DUP(0)
.CODE
mov ax,@data
mov ds,ax
;
mov ax,SEG innen
mov ds,ax ; A forrás string címe a DS:SI-ben
mov si,OFFSET innen
;
mov ax,SEG ide
mov es,ax ; A cél string címe az ES:DI-ben
mov di,OFFSET ide
;
mov cx,SLEN ; A forrás string hossza CX-ben
cld
;
rep movs es:[ide],[innen]
;
xor ax,ax
mov bx,0
mov cx,SLEN
mutat: ; A másolás ellenôrzése TD alatt
mov ax,ide[bx]
inc bx
inc bx
loop mutat
;
mov ah,4ch
int 21h
END
93
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
innen dw 1,2,3,4,5
SLEN EQU ($-innen)/2
ide dw 5 DUP(0)
.CODE
mov ax,@data
mov ds,ax
;
mov ax,SEG innen
mov ds,ax
mov si,OFFSET innen
;
mov ax,SEG ide
mov es,ax
mov di,OFFSET ide
;
mov cx,SLEN
cld
;
rep movsw
;
xor ax,ax
mov bx,0
mov cx,SLEN
;
mutat:
mov ax,ide[bx]
inc bx
inc bx
loop mutat
;
mov ah,4ch
int 21h
END
94
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
;
innen db 'Ebben a szövegbenkeressük az elsôszóközt!'
SLEN EQU ($-innen)
;
.CODE
mov ax,@data
mov ds,ax
;
mov ax,SEG innen
mov es,ax ; A string címe az ES:DI-ben
mov di,OFFSET innen
;
mov cx,SLEN ; A string hossza CX-ben
cld
mov al,20h ; A szóköz kódja
repne scasb ; Keresés 'nem egyenlô' - ig !
;
jne vege
dec di ; Itt volt az elsô szóköz !
;
vege:
mov ah,4ch
int 21h
END
.MODEL small
.STACK 100h
.DATA
;
minta db 'Ezaz'
ml EQU $ - minta
innen db '111122223333Ezaz4444'
SLEN EQU ($-innen)/ml
;
95
Forrás: http://www.doksi.hu
cld
;
mov dx,SLEN
mov bx,0
;
kov:
lea si,innen[bx] ; A tábla aktuális offszetje
; az SI-ben
lea di,minta ; A minta offszetje DI-ben
mov cx,ml ; A minta mérete CX-ben
repe cmpsb ; Keresés amíg a tábla elem =
; = minta elem !
;
je megvan
add bx,ml ; Ha nincs találat, akkor arrébb
; megyünk a minta hosszával
dec dx
jnz kov
mov si,ml
;
megvan:
sub si,ml ; Itt volt az egyezés !
;
mov ah,4ch
int 21h
END
96
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
;
ev DW ?
honap DB ?
nap DB ?
hnap DB ?
sev DB 4 DUP (20h)
sevv LABEL BYTE
DB '$'
snap DB 2 DUP (20h)
snv LABEL BYTE
DB '$'
spa DB ' '
;
holen DB 12
;
hok DB 'Január ','$'
DB 'Február ','$'
DB 'Március ','$'
DB 'Április ','$'
DB 'Május ','$'
DB 'Június ','$'
DB 'Július ','$'
DB 'Augusztus ','$'
DB 'Szeptember ','$'
DB 'Október ','$'
DB 'November ','$'
DB 'December ','$'
;
97
Forrás: http://www.doksi.hu
;
mov ah,2ah
int 21h ; Meghivtuk a dátum függvényt
;
mov [ev],cx ; Kimentjük a dátum alkotó részeit
mov [honap],dh
mov [nap],dl
mov [hnap],al
;
mov ax,[ev] ; Az évszám átalakítása kezdôdik !
mov bx,OFFSET sevv - 1
mov cx,4
call cnts
;
xor ax,ax ; A nap átalakítása kezdôdik !
mov al,[nap]
mov bx,OFFSET snv - 1
mov cx,2
call cnts
;
mov bx, OFFSET sev ; Az évszám kiírása
call prst
mov ah,2 ; Egy szóközt írunk ki utána
mov dl,[spa]
int 21h
;
xor ax,ax ; A hónap nevének szöveges kiírása
mov al,[honap] ; kezdôdik
dec al
mul holen
mov bx,OFFSET hok
add ax,bx
98
Forrás: http://www.doksi.hu
;
cnts PROC
mov si,10
cnvlp:
sub dx,dx
div si
add dl,'0'
mov [bx],dl
dec bx
and ax,ax
jz szokoz
loop cnvlp
szokoz:
ret
cnts ENDP
;
;
prst PROC
push ax
push dx
mov ah,9
mov dx,bx
int 21h
pop dx
pop ax
ret
prst ENDP
99
Forrás: http://www.doksi.hu
.MODEL small
.STACK 100h
.DATA
.CODE
mov ax,@data
mov ds,ax
;
kiir:
mov bl,dl ; Karakter attribútum
int 10h
push ax
mov ah,1 ; Várakozás billentyű lenyomásra
int 21h
pop ax
inc dx
cmp dx,255
jnz kiir
;
mov ah,4ch
int 21h
END
100
Forrás: http://www.doksi.hu
101
Forrás: http://www.doksi.hu
Σ
A kapcsolattartást a két nyelv között többek közt az indokolja, hogy manapság
- hála a C nyelv elterjedésének - egyre ritkább a nagyméretű, tisztán assembly
nyelven írt program. A fejlesztés általában úgy történik, hogy csak a nagy se-
bességigényű programrészeket “ hegyezik ki” assembly betétekkel, a többit
leginkább C - esetleg Pascal - nyelven írják meg. Ez a fejezet konkrétan az
inline kapcsolatot és a modul szerű kapcsolatot mutatja be.
Példa: .
.
.
int i;
.
.
.
i=0;
asm dec WORD PTR i;
i++;
Ha valaki egy kicsit is jártas az inline assembly használatában az azonnal rá-
jön, hogy i értéke 0 marad az utasítások végén, de azért nézzük meg részlete-
sebben az asm kulcsszóval kezdôdô sort.
asm [<címke>] < utasítás | dir ektíva > < oper andus ... > < ; | új sor >
. .
. .
. .
jó nem j ó
101
Forrás: http://www.doksi.hu
A fordítás menete tehát a következô : .C -> .ASM -> .OBJ -> .EXE.
Amennyiben azt szeretnôk látni, hogy a C forrásprogramunknak milyen
assembly program felel meg, úgy használjuk a BCC -S kapcsolóját.
#include <stdio.h>
#include <conio.h>
#include <string.h>
#pragma inline
void main()
{
void sm(char * , char * , int );
char st1[] = { "Ezt másoljuk !" } ;
char st2[] = { "xxxxxxxxxxxxxx" } ;
int l;
l = strlen(st1);
sm( st1,st2,l );
printf("\nSTRING1 = %s\n",st1) ;
printf("\nSTRING2 = %s\n",st2) ;
102
Forrás: http://www.doksi.hu
masol:
asm {
mov al,[si]
mov [di],al
inc si
inc di
loop masol
}
}
#include <stdio.h>
#include <conio.h>
#include <string.h>
#pragma inline
void main()
{
void sm(char * , char * , int );
char st1[25] = { "Ezt másoljuk !" } ;
char st2[] = { " " };
int l;
103
Forrás: http://www.doksi.hu
l = strlen(st1);
sm( st1,st2,l );
printf("\nSTRING1 = %s\n",st1) ;
printf("\nSTRING2 = %s\n",st2) ;
getch() ;
}
masol:
asm {
mov al,[si]
mov [di],al
inc si
inc di
loop masol
}
}
104
Forrás: http://www.doksi.hu
Példa : ...
EXTERN szubr2( int, int, int );
int a, b, c;
...
szubr2( a, b, c ); // Assembly nyelvű szubrutin
...
OFFSET R. A.
a
b
c
105
Forrás: http://www.doksi.hu
extern “ C” {
extern szubr3( int, int * , int);
}
106
Forrás: http://www.doksi.hu
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
l = strlen(st1);
sm( st1,st2,l );
printf("\nSTRING1 = %s\n",st1) ;
printf("\nSTRING2 = %s\n",st2) ;
getch() ;
}
;
; String másolás szubrutinként megvalósítva
;
.MODEL small
.STACK 100h
.DATA
;
.CODE
PUBLIC _sm
_sm PROC
;
push bp
mov bp,sp
;
mov si,[bp+4] ; A forrás string OFFSET-je SI-ben
107
Forrás: http://www.doksi.hu
#include <stdio.h>
#include <conio.h>
// Stringhossz meghatározás
void main()
{
extern int sh(char * );
char st1[25] = { "Mennyi lehet a hossza ?" } ;
int l;
l = sh(st1);
sh( st1 );
printf("\nSTRING1 = %s\n",st1) ;
printf("\nHOSSZ = %d\n",l) ;
getch() ;
}
108
Forrás: http://www.doksi.hu
;
; String hossza szubrutinként megvalósítva
;
.MODEL small
.STACK 100h
;.DATA
;
.CODE
PUBLIC _sh
_sh PROC
;
push bp
mov bp,sp
;
mov cx,0 ; Itt számoljuk a hosszat
mov si,[bp+4] ; A forrás string OFFSET-je SI-ben
;
hossz:
mov al,[si]
cmp al,0
je vege
inc si
inc cx
jmp hossz
;
vege:
pop bp
mov ax,cx
ret
_sh ENDP
END
109
Forrás: http://www.doksi.hu
#include <stdio.h>
#include <conio.h>
// Integer forditás
extern "C" {
extern void fordit(int * );
}
void main()
{
int i;
;
; Integer megforditását végzô assembly szubrutin
;
.MODEL small
.STACK 100h
.CODE
PUBLIC _fordit
fordit PROC
;
push bp ; A bázispointer elmentése a stackba
mov bp,sp
;
mov bx,[bp+4] ; A szám cime a BX - ben !
;
mov ax,[bx] ; Maga a szám az AX-ben !
mov BYTE PTR [bx],ah ; Ez a ket sor a csere
mov BYTE PTR [bx+1],al
;
pop bp
ret
fordit ENDP
END
110
Forrás: http://www.doksi.hu
05. Irjon programot amely összefűz két C típusú stringet. A két stringet C-
ben olvassuk be, magát az összefűzést pedig assemblyben végezzük el.
Oldja meg a feladatot elôször inline assemblyben, majd a modul
kapcsolat segítségével !
06. Irjon programot, amely egy 5x5-ös mátrixot helyben tükröz a fô-
átlójára ! A mátrixot C-ben lehet inicializálni, a tükrözést assemblyben
kell elvégezni. Oldja meg a feladatot elôször inline assemblyben, majd
a modul kapcsolat segítségével !
08. Irjon programot amely eldönti egy 5x5-ös mátrixról, hogy szim-
metrikus-e ! Egy mátrix akkor szimmetrikus, ha aij = aj i minden i,j-re.
A mátrixot C-ben lehet inicializálni, a vizsgálatot assemblyben
kell elvégezni. Oldja meg a feladatot elôször inline assemblyben, majd
a modul kapcsolat segítségével !
111
Forrás: http://www.doksi.hu
112
Forrás: http://www.doksi.hu
∑
Ebben fejezetben azokat a lényeges különbségeket mutatom be amelyek a
tanult i8086-os utasítások és ugyanezen utasítások fejlettebb processzorokon
történô megvalósításai között állnak fenn. Szó lesz továbbá a skálázott cím-
zésrôl is. A programok 386-os üzemmódban készültek ( az TASM assembler
ezen verziójának idejében még nem terjedt el a Pentium ) de az utasítások
ugyanígy szerepelnek a Pentium utasításkészletében is !
EAX
31 15 0
AH AL
AX
ESI
31 15 0
SI
Forrás: http://www.doksi.hu
A kérdés többek között azért sem közömbös, mert például az EBP regiszter
bázisregiszterként a stackszegmenst, indexregiszterként az adatszegmenst
címzi !
.MODEL small
.386 ; 16 bites szegmensek használata
.STACK 100h
.DATA
112
Forrás: http://www.doksi.hu
mov ax,matrix[ebx][edi* 2]
mov bx,OFFSET selemv - 1
113
Forrás: http://www.doksi.hu
...
mov al,[byte]
cbw ; AX-be konvertáljuk elôjelesen
mov dx,ax
...
...
mov sx dx,[byte]
114
Forrás: http://www.doksi.hu
.MODEL small
.386 ; 16 bites szegmensek
.STACK 100h
.DATA
;
szorzo1 dw 2
szorzo2 dw 3
szorzat dw 0
;
.CODE
115
Forrás: http://www.doksi.hu
116
Forrás: http://www.doksi.hu
Logikai utasítások
DIV op AL = AX/op Határozatlan
IDIV op AL = AX/op (elôjeles) Határozatlan
XCHG op1, op2 op1 <--> op2 -
L ogikai utasítások
Ugr ó utasítások
117
Forrás: http://www.doksi.hu
JC cimke ugrás, ha CF = 1 -
JS cimke ugrás, ha SF = 1 -
JO cimke ugrás, ha OF = 1 -
JZ cimke ugrás, ha ZF = 1 -
JP cimke ugrás, ha PF = 1 -
JPE cimke ugrás, ha PF = 1 -
JPO cimke ugrás, ha PF = 0 -
JNC cimke ugrás, ha CF = 0 -
JNS cimke ugrás, ha SF = 0 -
JNO cimke ugrás, ha OF = 0 -
JNZ cimke ugrás, ha ZF = 0 -
JNP cimke ugrás, ha PF = 0 -
JNPE cimke ugrás, ha PF = 0 -
118
Forrás: http://www.doksi.hu
CLC CF = 0 C=0
CMC CF = NOT CF C
STC CF = 1 C=1
CLD DF = 0 D=0
STD DF = 1 D=1
CLI IF = 0 I=0
STI IF = 1 I=1
119
Forrás: http://www.doksi.hu
Irodalomjegyzék
Szubr utin szer vezô uatsítások
Str ingműveletek
I r odalomj egyzék
120
Forrás: http://www.doksi.hu
Stringműveletek
1. Dr. Gidófalvi Zoltán : Az IBM PC programozása assembly
nyelven.
Novotrade 1988
121
Forrás: http://www.doksi.hu
TARTAL OM JEGYZÉK
Elôszó ........................................................................................................................7
Bevezetés ....................................................................................................................... 8
3
Forrás: http://www.doksi.hu
4
Forrás: http://www.doksi.hu
5
Forrás: http://www.doksi.hu
35. Ugyanaz mint 34. , de a paraméterekre stack címzéssel hivatkozunk ................. 103
36. Stringmásolás megoldása C és assembly modul kapcsolat segítségével ............. 106
37. C típusú string hosszának meghatározása modul kapcsolat segítségével ............ 107
38. Integer alsó és felsô byte-jának megfordítása .CPP kiterjesztésû programból .... 109
39. 3x3-as mátrix indexelése skálázott címzéssel ...................................................... 112
40. Szorzás változatok az IMUL utasítás új alakjaival .............................................. 115