assembly programozás

45
10 Tartalomjegyzék 1. Zárthelyi feladatok 11 2. Minta-vizsgafeladatok és megoldásuk 15 3. Önálló gyakorló feladatsor 21 Bevezet 21 Az MS-DOS felület elindítása 21 1. Gépi kód 23 2. Assembly program írása a Debug programmal 24 3. További programírás a Debuggal: a „Hello” szó kiíratása 27 4. Programírás Borland Turbo Assemblerrel 29 4. Törzsanyag 37 Prezentáció 37 I. Ismétlés 37 II. Az Assembly elemei 40 III. Assembly programozás 53 Kiegészítések a Prezentációhoz 65 A 0-65535-ig elszámoló program forráskódja 67 Az IBM PC XT/AT Input-Output portjai 68 A FLAGS (állapotregiszter) felépítése 68 Memóriacímzés valós és védett (80286+) módban 69 Lapozás (80386+) 69 A Norton Guide program az INT 27-et ismerteti 69 Számítógép konkrét hardver adatainak megtekintése 70 5. A gyakorlatokon kitzött feladatok 72 6. Assembly - összefoglaló 73 7. Assembly programozás a mai modern operációs rendszerek alatt 75 8. Az Intel 8086/8088 és 80286 proc. teljes utas.készlete – valós (real) mód 79 9. Az IBM PC XT/AT megszakításvektorai 82

Upload: veresnorbi

Post on 23-Jul-2015

218 views

Category:

Documents


6 download

DESCRIPTION

Példaprogramok, zh.-kérdések, információk a gyakorlatokról és a vizsgákról

TRANSCRIPT

Page 1: Assembly programozás

10

Tartalomjegyzék 1. Zárthelyi feladatok 11 2. Minta-vizsgafeladatok és megoldásuk 15 3. Önálló gyakorló feladatsor 21

Bevezet� 21 Az MS-DOS felület elindítása 21 1. Gépi kód 23 2. Assembly program írása a Debug programmal 24 3. További programírás a Debuggal: a „Hello” szó kiíratása 27 4. Programírás Borland Turbo Assemblerrel 29

4. Törzsanyag 37

Prezentáció 37

I. Ismétlés 37 II. Az Assembly elemei 40 III. Assembly programozás 53

Kiegészítések a Prezentációhoz 65 A 0-65535-ig elszámoló program forráskódja 67 Az IBM PC XT/AT Input-Output portjai 68 A FLAGS (állapotregiszter) felépítése 68 Memóriacímzés valós és védett (80286+) módban 69 Lapozás (80386+) 69 A Norton Guide program az INT 27-et ismerteti 69 Számítógép konkrét hardver adatainak megtekintése 70

5. A gyakorlatokon kit�zött feladatok 72 6. Assembly - összefoglaló 73 7. Assembly programozás a mai modern operációs rendszerek alatt 75 8. Az Intel 8086/8088 és 80286 proc. teljes utas.készlete – valós (real) mód 79 9. Az IBM PC XT/AT megszakításvektorai 82

Page 2: Assembly programozás

11

1. Zárthelyi feladatok Az alábbiakban közreadjuk a zárthelyin el�forduló összes kérdést. A kérdések az Intel 80x86-os processzorcsalád valós módjára vonatkoznak, IBM PC kompatíbilis számítógé-pen, MS-DOS rendszerben (ablakban). A kérdések megválaszolhatók ezen Tantárgyi útmutató (f�leg a Prezentációs rész) gondos tanulmányozása és néhol cseppnyi gondolkodás után. A kérdések sorrendje általában kö-veti az útmutató felépítését.

1. Hogyan képezhet� egy pozitív, illetve negatív szám egyes komplemens alakja? 2. Hogyan képezhet� egy pozitív, illetve negatív szám kettes komplemens alakja? (A negatív esetében ismertessen két különböz� képzési módszert!) 3. Írja le az N szám (-9�N�+9) egyes komplemens alakját, 8 biten! A feladatot fejben végezze el, legfeljebb fél perc alatt! A számot a tanár adja meg. 4. Írja le az N szám (-9�N�+9) kettes komplemens alakját, 8 biten! A feladatot fejben végezze el, legfeljebb fél perc alatt! A számot a tanár adja meg. 5. Mennyi egy szám és kettes komplemensének összege az ábrázolási tartományon belül? 6. Hogyan (milyen alakban) tárolják az Intel mikroprocesszorok az egész számokat? 7. Mi a kettes komplemens használatának el�nye? Mutassa be konkrét példával! 8. Hogyan állapítható meg ránézésre egy kettes komplemens alakban tárolt (bináris) szám el�jele? Mondjon konkrét példát! 9. Melyik Assembly utasítás állítja el� egy szám egyes/kettes komplemensét? 10. Mit jelent a BCD kódú számábrázolás: minek a rövidítése, hogyan tárolódik a szám, milyen fajtái vannak (2 féle, 3-3 megnevezéssel), mire használ-

ható? 11. Írja le az N számot (0�N�99) a kétféle BCD kódolással, ezen belül bináris és hexadecimális módon, fejben, fél perc alatt! A számot a tanár adja

meg. 12. Milyen matematikai halmazhoz tartozó számokat ábrázolhatunk egyes komplemens / kettes komplemens / BCD / lebeg�pontos alakban? 13. Mi a lebeg�pontos szám felírásának elve? Írja le a matematikai képletet, nevezze meg az egyes összetev�ket (mindkét elnevezéssel)! 14. Hányféle lebeg�pontos számábrázolást használhatunk? Sorolja fel! 15. Hány részb�l áll egy lebeg�pontos szám? Sorolja fel az egyes részeket és magyarázza el, mit tartalmaznak! 16. Ismertesse a rövid valós tárolási módját: az egyes részeket hány biten tároljuk, összesen hány bájtot foglal el egy szám, a tároláskor mit módosí-

tunk és hogyan? 17. Mi az az „1”-es bit, amit nem tárolunk a lebeg�pontos számban? Miért nem kell tárolni? Magyarázza el részletesen! 18. Vezesse le a -3,75 szám rövid valós formában történ� ábrázolását lépésr�l lépésre, részletesen! 19. Létezik-e +0 és -0 a lebeg�pontos számábrázolásban? Miért? 20. Ha a lebeg�pontos szám egyik, illetve másik részének nagyobb tárolási helyet biztosítunk (pl. x helyett 2x bitnyi helyet), a szám mely min�ségi tu-

lajdonsága változik meg az egyik, illetve a másik esetben? 21. Hány tizedesjegy a rövid valós pontossága? 22. Mire használható a paritásvédelem? 23. Hányféle paritásvédelmi lehet�ség van? Nevezze meg ezeket, mondjon konkrét számpéldát! 24. Melyik paritásvédelmet használják inkább és miért? 25. Mennyi a 0 szám paritásbitje az egyes paritásvédelmi fajtáknál? 26. Mire használják fel a paritásvédelmet? Mondjon két konkrét példát! 27. Melyik memóriát védik paritásvédelemmel? Ezen belül melyik típussal? Mindig védik? 28. Milyen memóriavédelmet használnak a ROM, illetve a RAM memóriánál? 29. Mondjon egy-egy konkrét példát els� / második / harmadik / negyedik generációs nyelvre! Melyiket érti meg közvetlenül (azonnal) a mikroprocesz-

szor? 30. Mi a gépi kód, mire használható, mit tartalmaz? 31. Hogyan néz ki egy gépi kódú program papírra leírva? 32. Hol található a mikroprogram? Mely típusra jellemz�? 33. Könny�-e megérteni a gépi kódot? A választ indokolja meg! 34. Milyen hosszú (hány bájtos) az „A” bet�t kiíró gépi kódú program MS-DOS rendszerben? Milyen lépésekb�l áll? 35. Mi a „mnemonik”, mi az el�nye, hol használják? Mondjon konkrét példát is! 36. Mi a kapcsolat az Assembly és a gépi kód között? Mondjon konkrét példát! 37. Szoros-e a kapcsolat az Assembly és a gépi kód között? 38. Alacsony szint�-e az Assembly? Ez mit jelent? 39. Hardverfügg�-e az Assembly? Ez mit jelent? 40. Hasonlítsa össze forrásfájlméret, futtatható fájlméret és gyorsaság szempontjából az Assemblyt más programnyelvekkel! 41. Magyarázza meg a következ� fogalmakat: Assembly, assembler, disassembler! 42. Hol használják manapság az Assemblyt (legalább két példával)? 43. Hány regisztert (hány bitest) használunk a szegmens-offset memóriacímzésnél? 44. Mi a „szegmens” másik neve, mi az „offset” másik neve? Melyik mit mutat? 45. Hogyan számítható át egy szegmens-offset cím fizikai címre? Mondjon egy konkrét számpéldát is! 46. Mi a hidegindítás kezd�címe? Adja meg a fizikai címet és kétféle módon szegmens-offset alakban is! 47. Mekkora egy szegmens mérete (valós módban)? Miért? 48. Mit jelent a „normalizált érték” a szegmens-offset memóriacímzésnél? Mondjon egy konkrét számpéldát is! 49. Miért címezhet� meg egy memóriacím többféle módon szegmens-offset alakban? Magyarázza meg, mutasson konkrét példát is! 50. A memória mely része címezhet� csak egyféleképpen szegmens-offset címzéssel? Miért? Mutasson konkrét példát is! 51. Mit jelent a paragrafus a szegmens-offset címzésnél? Mekkora távolságra vannak egymástól? Magyarázza meg részletesen! 52. Mi a HMA, mi a különlegessége, hol található, mire használható? Magyarázza meg részletesen! 53. Mekkora memória címezhet� meg valós módban, bájtra pontosan? 54. Mit jelent az „Unreal mode”, hol használják, milyen kétféle más elnevezése van? 55. Sorolja fel az Intel CPU általános regisztereit! Melyiknek mi a teljes neve, hogyan jelöljük? 56. Hogyan jelöljük az akkumulátor regisztert? 57. Milyen számtartomány ábrázolható 1 bájton, ha a szám el�jel nélküli, illetve el�jeles? A határokat tízes és tizenhatos számrendszerben adja meg! 58. Milyen számtartomány ábrázolható 2 bájton, ha a szám el�jel nélküli, illetve el�jeles? A határokat tízes és tizenhatos számrendszerben adja meg! 59. Mi az AH és AL, mekkora a méretük? Hogyan függ össze AX-AH-AL? 60. Mit jelent AH és AL-nél a H illetve L bet�? 61. Miért jó a hexadecimális számrendszer használata a decimálishoz képest? Az AX-AH-AL regiszterhármas esetében mutassa be konkrét számpél-

dával! 62. Az AH és AL értékeit ismerjük, tízes számrendszerben megadott számok. Írja le, hogyan számolhatjuk ki AX értékét! 63. Hány bitesek az általános regiszterek Intel 8086/8088-nál, illetve 80386-tól kezdve? 64. Sorolja fel az indexregisztereket: hogy mondjuk angolul és magyarul, hogyan jelöljük, mekkora a méretük, mire használhatók? 65. Sorolja fel a veremregisztereket: rövidítés+teljes név, mire használhatók? 66. Hány szegmensregiszter van (valós módban)? Sorolja fel �ket: hogyan jelöljük, mi a teljes nevük, melyik mire használható?

Page 3: Assembly programozás

12

67. Mire jó az utasításmutató regiszter, hogyan jelöljük? 68. Mi a következ� végrehajtandó utasítás címe? 69. Hogyan nevezik másképp a Flag regisztert? Mondjon legalább kétféle másik elnevezést! 70. Mi található a Flag regiszterben? 71. Használható-e a Flag regiszter adattárolásra? Miért? 72. Mekkora egy flag mérete? Milyen értékeket vehet fel? 73. Mi állítja a flageket? 74. Ismertessen öt jelz�bitet részletesen (megnevezés, hogyan m�ködik)! 75. A flageknél milyen érték jelenti a „normál” eredményt és mi a „különlegeset”? 76. Mondjon konkrét aritmetikai és logikai m�velet példát a zérus jelz�bit m�ködésére! Mi lesz (a zérus jelz�bit) értéke az egyes esetekben? 77. Mire használható a megszakítás jelz�bit? 78. Beállítható-e (módosítható-e) szoftveresen az, hogy onnantól kezdve egy Assembly utasítás mely regiszter(ek)re vonatkozzon? 79. Megszüntethet�-e véglegesen egy regiszter szoftveresen? 80. Melyik angol szóból származik a MOV utasítás, mit jelent magyarul? 81. Mondjon konkrét példát a MOV utasításnál értékadásra, regisztercímzésre, memória m�veletre! Mindegyik példában szerepeljen az akkumulátor

regiszter! 82. Hány paramétert igényel a MOV utasítás, melyek ezek? 83. Mit jelent a MOV AX,200 utasítás? Magyarázza el! 84. A MOV AX,200 utasításnál mennyi lesz AH és AL értéke? 85. A MOV AX,<szám> utasításnál milyen határok közé eshet a <szám>, hogy AH értéke nulla legyen? Adja meg a számtartományt és magyarázza el

részletesen! 86. Mi mutatja meg, hogy egy regiszter tartalma el�jeles, vagy el�jel nélküli szám? 87. Írja le másként a MOV AH,-2 utasítást, hogy ugyanazt jelentse (csak a számot kell megváltoztatni)! 88. Miért hibás a MOV AH,256 utasítás? Mi történik, ha AH helyett AX szerepel? 89. Miért hibás a MOV AX,FFh utasítás? Hogyan lenne helyes? 90. Miért hibás a MOV AX,70000 utasítás? Hogyan lenne helyes? 91. Miért hibás a MOV 5,AL utasítás? Hogyan lenne helyes? 92. Miért hibás a MOV AX,DL utasítás? Hogyan lenne helyes? 93. A MOV AL,BL utasítás végrehajtása el�tt AL=5 és BL=6. Mennyi lesz AL és BL? 94. Az ES szegmensregiszterbe nullát akarunk helyezni. Írja le a megoldást Assemblyben! 95. Helyes-e a MOV IP,0 utasítás? Miért? 96. Javítsa ki a MOV AX,SI utasítást úgy, hogy olvasson a memóriából! 97. Javítsa ki a MOV SI,AX utasítást úgy, hogy írjon a memóriába! 98. Mi a különbség a MOV utasításnál az SI és az [SI] között? 99. Mit jelent a MOV utasítás használatánál [SI]? Hány bájtot jelöl ki, mi a szegmens, mi az offset? 100. Mit jelent a MOV utasításnál a „bájt fordított alak”? Mondjon konkrét példát! 101. Mit jelent a MOV utasítás használatánál a „szegmensfelülíró prefix”? Mondjon konkrét példát! 102. Mondjon konkrét példát indexelt, bázis relatív, bázis relatív indexelt címzésre a MOV utasítással! Melyik mit jelent? 103. Hogyan értelmezi a számítógép a MOV AL,‘R’ utasítást? 104. Mit jelent az „adattípus ideiglenes átdefiniálása” a MOV utasításnál? Magyarázza meg részletesen, konkrét példával! 105. Mit jelentenek egy Assembly programban az alábbi sorok? Magyarázza meg részletesen: title, model small, model tiny, stack, data, code, mov

ax,4c00h és int 21h? 106. Hány részb�l áll a legb�vebb Assembly parancssor? Nevezze meg az egyes részeket magyarul és angolul! Melyik mire használható? Hogyan

választjuk el az els� és az utolsó részt a többit�l (konkrétan)? 107. Érzékeny-e az Assembly nyelv a kis/nagybet�kre? 108. Mi az Assembly forrásprogramot tartalmazó fájl kiterjesztése? 109. Borland Turbo Assemblernél mely utasítással fordítjuk le a programot? Hány lépésb�l áll a fordítás, mi történik ilyenkor? Milyen fájlkiterjesztés

keletkezik a fordítás végén? 110. Mire használhatók a .LIB fájlok, mit tartalmaznak? 111. Borland Turbo Assemblernél mely utasítással szerkesztünk egy programot? Milyen (kétféle) végeredmény keletkezhet? 112. Helyes-e a „modell small” utasítás? Miért? 113. Soroljon fel három hibalehet�séget, amit az Assembly programozás els� id�szakában elkövethetünk! 114. Mire jó az adatdefiniáló direktíva? 115. Milyen nagyságú (hány bitesek) a „byte”, „word”, „doubleword” típusú számok? 116. Hogyan használjuk az adatdefiniáló direktívát 1-2-4 bájtos esetben? Mondjon konkrét példát! 117. Mondjon két konkrét különböz� példát adatdefiniáló direktíva használatára! 118. Mit történik fordításkor az adatdefiniáló direktívákkal? Mi szerepel a gépi kódban? 119. Sorolja fel az aritmetikai alapm�veletek mnemonikjait (8 db)! Melyik mit jelent? Hogyan mondják angolul az egyes m�veleteket? 120. Az AH regiszter értéke 250. Az ADD utasítással hozzáadunk 10-et. Mennyi lesz a regiszter értéke, miért? 121. Az AX regiszter értéke 250. Az ADD utasítással hozzáadunk 10-et. Mennyi lesz a regiszter értéke, miért? 122. Az AH regiszter értéke 5. A SUB utasítással kivonunk 10-et. Mennyi lesz a regiszter értéke (el�jel nélküli formában), miért? 123. Az AX regiszter értéke 5. A SUB utasítással kivonunk 10-et. Mennyi lesz a regiszter értéke (el�jel nélküli formában), miért? 124. A szorzó Assembly utasításnál hány bájton keletkezik az eredmény (kétféle lehet�ség van)? 125. Az osztó Assembly utasításnál csak hányados keletkezik? 126. Adja meg az akkumulátor regiszter 1-gyel növelését kétféleképpen, két különböz� Assembly utasítást felhasználva! 127. Adja meg az akkumulátor regiszter 1-gyel csökkentését kétféleképpen, két különböz� Assembly utasítást felhasználva! 128. Hogyan támogatják az Intel CPU-k a BCD kódú számok kezelését? Mi a probléma és hogyan oldják meg? Sorolja fel, milyen m�veleteket támogat,

konkrét példákkal! 129. Hogyan m�ködik a LOOP utasítás? Melyik regiszter tartozik hozzá? 130. A LOOP el�l- vagy hátultesztel�s? 131. Hányszor futhat le a LOOP-os ciklus legkevesebbszer? Ilyenkor milyen értékkel kell indítani? 132. Hányszor futhat le a LOOP-os ciklus legtöbbször (de nem végtelenszer)? Ilyenkor milyen értékkel kell indítani? 133. Hogyan hozható létre végtelen ciklus LOOP-pal? Írjon le egy teljes példát! 134. Mit jelent az egymásba ágyazott ciklus? Ha LOOP-pal készítjük, mire kell ügyelnünk? 135. Készítsen egy ötször lefutó ciklust a LOOP utasítás használata nélkül! Írja le a megoldást Assemblyben! 136. Magyarázza el a „fordított ciklus” fogalmát! 137. Hány lépésben valósul meg az if-then-else szerkezet Assemblyben? Nevezze meg az egyes részeket (mi mit csinál)! 138. Melyik regiszter játszik az elágazás megvalósításánál kikerülhetetlen szerepet? 139. Hány irányú az elágazás Assemblyben? Miért, magyarázza meg konkrét példával! 140. A JZ / JNZ / JC / JNC milyen fajtájú utasítások és mikor „érvényesülnek” (utasításonként)? 141. Mi a feltétel nélküli ugrás Assembly mnemonikja? 142. Mit jelent a közeli/távoli ugrás? 143. Mit állítanak az ugró utasítások? 144. Milyen a „GOTO” jelleg� utasítások megítélése az Assemblyben és a strukturált nyelvekben? 145. Regiszter léptet�/forgató m�veletnél hová kerülhet a kilép� bit (kétfelé)? 146. Regiszter léptet�/forgató m�veletnél honnan származhat a belép� bit (három lehet�ség)? 147. Sorolja fel a regiszter léptet�/forgató 7 db utasítást! Melyik hogyan m�ködik, ismertesse röviden! 148. Miért speciális a SAR regiszterléptet� utasítás?

Page 4: Assembly programozás

13

149. Egy regiszter értéke 5 és CF=0. Mennyi lesz a regiszter értéke egy bittel balra / jobbra léptetés után? Mennyi lesz az értéke még egy balra / jobbra léptetés után?

150. Mire használhatók a regiszter léptet�/forgató utasítások? Mondjon két példát! 151. Mire használható az AND utasítás? Mondjon konkrét példát! 152. Hogyan nevezik az AND utasítást másképpen? 153. Mit jelent egy regiszter „legfels� bitje”, illetve „legalsó bitje”? Az akkumulátor regiszter példáján mutassa be! 154. Az AH regiszter legfels� bitjét törölni akarom, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasítást! 155. Az AH regiszter legfels� két bitjét törölni akarom, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasítást! 156. Az AH regiszter legfels� négy bitjét törölni akarom, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasítást! 157. Az AH regiszter legalsó bitjét törölni akarom, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasítást! 158. Mire használható az OR utasítás? Mondjon konkrét példát! 159. Az AH regiszter legfels� bitjét 1-be akarom állítani, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasítást! 160. Az AH regiszter legfels� két bitjét 1-be akarom állítani, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasí-

tást! 161. Az AH regiszter legfels� négy bitjét 1-be akarom állítani, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasí-

tást! 162. Az AH regiszter legalsó bitjét 1-be akarom állítani, a többi bit változatlan hagyása mellett! Adja meg az ezt megvalósító 1 db Assembly utasítást! 163. Egy regisztert törlünk. Mi történik? 164. Adja ki az AND utasítást az AH regiszterre úgy, hogy ne változzon az értéke! 165. Adja ki az OR utasítást az AH regiszterre úgy, hogy ne változzon az értéke! 166. Adjon ki egy AND és utána egy OR utasítást úgy, hogy végrehajtásuk után az AH regiszter értéke 1 legyen, függetlenül a tartalmától! Felcserélhet�-

e e két utasítás sorrendje? 167. Adja meg az AND / OR / XOR utasítások igazságtáblázatát, két bemenet esetén! 168. Nullázza le az AH regisztert három különböz� utasítással! Segítség: AND, MOV, XOR. 169. Mi a különbség a MOV-val, illetve az AND-dal történ� regiszternullázás között? 170. Egy regisztert kétszer XOR-olunk ugyanazzal a számmal. Mi történik, miért, mire használható ez a lehet�ség? 171. Mi a verem? Hol található? Milyen utasítások kapcsolódnak hozzá (sorolja fel a négy legfontosabbat)! 172. Mit jelent a LIFO és a FIFO, melyiket hol használják? 173. A verem alja vagy teteje rögzített? 174. Melyik szegmensben található a verem? Nevezze meg a szegmensregisztert is! 175. Melyik irányba n� a verem? 176. Mit mutat az SP regiszter? 177. Mire használható a verem (kétféle célra)? Mondjon mindegyikre konkrét példát! 178. Miért fontos, hogy annyi POP legyen, amennyi PUSH? Mi történik, ha több a PUSH, illetve ha több a POP? 179. Mi történik SP-vel egy PUSH utasítás hatására? 180. Miért különleges a PUSH SP utasítás? Segítség: Intel CPU kompatibilitás. 181. Mire használhatók a PUSHA és a PUSHF utasítások? Mi az ellentétük? 182. Mire használható a BP regiszter? 183. Mit jelent a szubrutin? Milyen utasítások tartoznak ide (sorolja fel a két legfontosabbat)! 184. Hogyan kerül a szubrutin a veremmel kapcsolatba? Ismertesse részletesen! 185. Készíthet�-e többszörös mélység� szubrutin? A választ indokolja! 186. Mit jelent a megszakítás, mi kezdeményezi, mire használható? 187. Mi a hasonlóság és a különbség a megszakítás és a szubrutin között? 188. Mit jelent a „megszakítás kiszolgálása”? 189. Sorolja fel a megszakítások fajtáit prioritás szerint (4 féle)! Melyikre mi jellemz�? 190. Mi az NMI? Mikor keletkezik? Minek a rövidítése az NMI angolul és magyarul? Letiltható-e az NMI az IBM PC-nél? 191. Mi az IRQ? Mikor keletkezik? Mikor érvényesül? 192. Hogyan történik egy megszakítás feldolgozása (7 lépés)? Ismertesse részletesen! 193. Melyik utasítás áll a megszakítás végén? Mi történik (3 lépés)? 194. Mire használhatóak a megszakítások? Mondjon egy konkrét hardver/szoftver példát! 195. Mit jelent a „megszakítási vektortáblázat”? Mit tárol? Hol található? Mekkora a mérete? 196. Miért jó (mire használható), ha átírjuk a megszakítási vektortáblázat értékeit? 197. Hányas szoftver megszakítás hívja meg az NMI-t? 198. Mondjon egy példát bels� megszakításra (eltérülésre)! 199. Mit jelent az, hogy ROM-BIOS megszakítás, illetve DOS megszakítás? 200. Mit jelent a „user timer interrupt” a megszakítási témánál? 201. Gyártófügg�-e a ROM tartalma? Hogyan ajánlatos elérni a tartalmát? 202. A hideg- vagy a melegindítás törli a megszakítási vektortáblázatot? 203. Hány interrupt-vezérl� van, hogyan vannak kötve, hány hardver megszakítást tudnak fogadni? 204. Melyik a gyorsabb: MOV AX, BX vagy PUSH AX? Miért? 205. Milyen módon lehet felcserélni az AX és BX regiszterek értékét? Adjon meg három (!) különböz� elv� megoldást (Assembly utasításokkal)! 206. Mit jelent a NOP utasítás? Minek a rövidítése? 207. Mire használható a NOP utasítás? Ismertessen két lehet�séget részletesen! 208. Mire használható a HLT utasítás? Minek a rövidítése? 209. Mire használható az XLAT utasítás? 210. Melyek a portkezel� utasítások (a két legfontosabb)? Mondjon konkrét példát! 211. Magyarázza el egy b�vített mondatban a stringkezel� utasítások célját, lehet�ségeit! 212. Melyik Assembly utasítás törli a carry flaget? 213. Melyik Assembly utasítás állítja egybe a carry flaget? 214. Melyik Assembly utasítás állítja ellentétes érték�re a carry flaget? 215. Melyik Assembly utasítás tiltja le a hardver megszakításokat? Vonatkozik-e ez az NMI-re? 216. Melyik Assembly utasítás engedélyezi a hardver megszakításokat? 217. Állítja-e a MOV utasítás a flageket? 218. Ismertesse a Windows 3.x/9x/ME-t lefagyasztó Assembly utasítássorozatot és magyarázza el röviden, hogyan m�ködik! 219. Mire jó a „mov ah,8; int 21h; cmp al,27; je kilepes” utasítássorozat? Magyarázza el részletesen! Mit jelent itt a „kilepes”? 220. Mikor használnak small és mikor tiny memóriamodellt? 221. Ismertesse a small és a tiny memóriamodell jellemz�it részletesen (számokkal együtt)! 222. Ismertesse a BX tartalmát binárisan (16 biten) kiíró program megoldási logikáját! 223. Ismertesse a BX tartalmát hexában (16 biten) kiíró program megírási logikáját! 224. Ismertesse a .COM fájlok jellemz�it (4 jellemz�t)! Hogyan készíthet� Borland Turbo Assemblerrel? 225. Mi a „probléma” a Windows-beli command.com-mal fájlméret-ügyben és mi a probléma feloldása? 226. Ismertessen három fatális hibát .COM fájl készítésekor, amikor a fordító nem jelez hibát, csak a linker! 227. Használhatunk-e vermet .COM fájlnál? 228. Ismertesse az .EXE fájlok jellemz�it! 229. Melyik fájltípushoz kapcsolódik a fejléc (header) fogalma? 230. Mi a relokációs táblázat, melyik fájlnál van, mi történik betöltés után és mi ennek az oka? 231. Elkülönül-e az IBM PC-nél a szöveges és a grafikus monitor-üzemmód? 232. Ismertesse a szöveges üzemmódú képerny�memória jellemz�it: mi a képerny�memória kezd�címe (lineáris és szegmens-offset alakban), hogyan

tárolódnak a sorok, egy pozícióhoz hány bájt tartozik, milyen az attribútum bájt részletes (bitenkénti) felépítése?

Page 5: Assembly programozás

14

233. Hogyan történik a szöveges üzemmód gyors képerny�törlése (mi az elve)? 234. Mondjon egy, csak szöveges módban m�köd� monitortípust és legalább négy grafikus típust! 235. Ismertesse részletesen a DOS szöveges üzemmódú képerny�memória felépítését, jellemz�it! 236. Ismertesse részletesen a VGA-MCGA üzemmódot: sorok és oszlopok száma, egyid�ben hány szín lehet a képerny�n, mi a képerny�memória

kezd�címe (lineáris és szegmens-offset alakban), egy képpont hány bájt, hogyan tárolódnak a sorok? 237. Hogyan rajzolhatunk a VGA-MCGA módban a képerny� közepére egy zöld pontot? Ismertesse a lépéseket (konkrét utasítások nem kellenek, csak

az elv)! 238. A „vertical blank” melyik témakörhöz tartozik, mit jelent, mi a jelent�sége? 239. Összesen hány szín (színárnyalat) van VGA-MCGA módban? Nem kell konkrét szám, csak a kiszámítás módja. 240. Hol található a video interrupt (int 10h) programja és mire használható? 241. Hanggenerálás a PC Speaker segítségével (2 rövid mondat). 242. Paraméterátvétel parancssorból (2 rövid mondat, konkrétumokkal). 243. Egérkezelés Assemblyben hogyan valósítható meg? (2 rövid mondat.) 244. Memóriarezidens programok (mit jelent, m�ködésének elve, mire használható, legalább 3 példával). 245. Hol helyezkedhet el egy memóriarezidens program? 246. Hogyan kerül egy memóriarezidens programra a vezérlés? 247. Ismertesse az IBM PC memóriatérképét (csak felsorolás szükséges, konkrét számok nélkül)! 248. Az Assembly utasítások felépítése (milyen két részb�l áll, melyik mit jelent)? 249. Mondjon az Assembly különleges lehet�ségei közül négyet! 250. Tudunk-e szektoronként kezelni egy háttértárat Assemblyben? 251. Mit jelent a futás közbeni kódátírás, hogyan m�ködik? Megvalósítható-e Assemblyben? Megvalósítható-e magas szint� programozási nyelven? 252. Ismertesse a POST-ot: mit jelent, hol található, mikor indul el, mi történik? 253. Ismertesse a ROM-scant: mit jelent, mi végzi el, mikor érvényes és ha érvényes, mi történik? 254. Egy számítógép bekapcsolásakor általában a videokártya jelentkezik be néhány másodpercre, ezután jön az alaplap képerny�je a RAM teszttel. Mi

teszi lehet�vé a videokártya bejelentkezését (bekapcsolódását) a rendszerbe? Hogyan történik a boot-eprommal felszerelt hálózati kártya bekap-csolódása a rendszerbe?

255. Hol található a floppy lemez boot szektora (konkrét számokkal: head stb.)? 256. Hol található a Master Boot Record (konkrét számokkal: head stb.)? 257. Melyik konkrét RAM címre tölti be a boot szektort bekapcsolásnál a gép? 258. Mit csinál a megszakítások átirányításánál (int 1ch) leírt mintapélda és milyen elven m�ködik? 259. Mi a Debug program, hol található, része-e a Windowsnak, mire használható? Ismertessen legalább négy felhasználási lehet�séget! 260. Ismertesse egy-egy mondatban a Turbo Debugger, Sourcer, Tech Help, Assembly keretprogramok jellemz�it (mire használhatók)? 261. Mit jelent az „Assembly demó”? 262. Mit jelent a Ralph Brown-féle megszakítási lista? 263. Válasszon ki öt tetsz�leges, de különböz� típusú Assembly utasítást. Írjon le egy-egy konkrét példát velük és magyarázza meg, mi történik! 264. Az alábbi Assembly utasítások közül ismertesse a tanár által kijelölt egyiket:

- hány paraméter tartozik az utasításhoz és milyen típusúak (szám / regiszter / memóriacím)? - írjon le egy konkrét példát! - hogyan m�ködik az utasítás? - mire (milyen probléma megoldására) használható egy programban az utasítás?

ADD, SUB, MUL, DIV, INC, DEC, AND, OR, XOR, TEST, NEG, NOT, MOV, XCHG, IN, OUT, LOOP, CMP, JMP, JE, JNE, JZ, JNZ, JC, JNC, PUSH, POP, PUSHA, POPA, PUSHF, POPF, CALL, RET, INT, IRET, SHL, SHR, ROL, ROR, RCL, RCR, SAR, CLC, CMC, STC, CLI, STI, HLT, NOP.

265. Az IBM PC megszakítás-vektorai közül válasszon ki egy olyat, amelyhez IRQ is tartozik, és egy olyat, amelyhez nem. Ismertesse, melyik mire használható?

266. A Debug programmal egy rövid Assembly programot akarunk megírni és elindítani. Ismertesse, milyen lépésekre van szükség! 267. Mi a paritásgenerátor, hol található? 268. A „cmp al,27” és „je kilepes” utasításoknál melyik jelz�bit jut f�szerephez? 269. Mondjon hardver példát az AND és XOR kapuk használatára! 270. Mi egy .EXE fájl els� két bájtja? 271. Miért nem fagyasztható le a Windows 2000/XP a közölt 3 bájtos .COM programmal? 272. Milyen el�nye és hátránya volt a Hercules grafikus kártyának? 273. Hogyan tárolja a képet a 24 bites True Color üzemmód? 274. Milyen alapszínekb�l állítják el� a képet a monitorok és a színes nyomtatók? Hogyan rövidítik? Melyik az additív és melyik a szubsztraktív? Hány

különböz� festéket használnak a színes nyomtatók? 275. Ismertesse a 0-tól 65535-ig elszámoló program m�ködési elvét részletesen! A felhasznált módszerek és a lépések kellenek, konkrét utasítások

nem! 276. (Az el�z� programnál) milyen alakban tárolja a kiírandó számot a program? 277. (Az el�z� programnál) melyik résznél használunk rekurzív szubrutint, és hogyan m�ködik? 278. Mire használható az msinfo32 program? 279. Mit jelent az IRQ megosztás? 280. Mit jelent az IRQ ütközés? 281. Milyen számrendszerben vannak írva az alábbi számok: 00h, 00b, 0x0000? 282-283. Az alábbiakban leírunk egy-egy komplett Assembly programot, melyet .COM fájlra kívánunk lefordítani:

(1) .modell tiny .modell tiny (2) .code 100 .data 100 (3) org 100 szoveg db 'Hello' (4) start .code 100 (5) mov bh,2 org 100 (6) mov dl,256 start (7) int 21 mov ah (8) int20 mov cx,offset szoveg (9) end int 21 (10) int20 (11) end

A programok mindegyik sorában van hiba. - Javítsa ki mindegyik sort, hogy helyes legyen! - Melyik sor tartalmazott szintaktikai és melyik szemantikai (logikai) hibát? - A kijavított program mit tud? - A kijavított programnál mi történik, ha a forráskódból kitöröljük az els� / második / harmadik stb. sort (de mindig csak egyet)? Külön-külön minden

egyes sor kihagyásakor adjon választ az alábbi kérdésekre: lefordítható-e így a program, keletkezik-e .COM fájl, mi történik a program futtatása-kor?

Page 6: Assembly programozás

15

2. Minta-vizsgafeladatok és megoldásuk Kettesért és hármasért 30 percet dolgozhatnak, négyesért 60 perc, ötösért 70 perc áll rendelkezésre. A vizsgán bármely, nyomdában készült jegyzet, tankönyv, Tantárgyi útmutató használható, tollal írt és nyomtatóval kinyomtatott papírok azonban nem! A vizsgafeladatok felépítése olyan, hogy ez a Tantárgyi útmutató teljesen elegend� bármely feladat megoldásához. A vizsgán az itt közreadottakhoz hasonló feladatok lesznek. Mindaddig sikertelen, amíg nem tartalmaz önál-ló gondolatot, csupán kimásolt programrészleteket! Mindegyik programot számítógépen (kivételes esetben papíron) kell elkészíteni. A forrásfájl neve VIZSGA.ASM legyen és .COM-ra kell lefordítani (a vizsgáztató külön kérése esetén .EXE-re)! Feladatok kettes-hármas osztályzatért: 1. Kettesért: Készítsen Assembly programot, amely udvariasan beolvas egy 8 jegy� bináris számot (például: 10001100)

és eldönti, hogy a szám páros-e vagy páratlan, továbbá (kettes komplemens ábrázolást feltételezve) negatív-e vagy pozitív. A két eredményt szövegesen írja ki a képerny�re, egymás alá. A számbevitelt nem szükséges ellen�rizni. Hármasért annyi kiegészítés szükséges, hogy a program a bevitel során csak a 0 és 1 számjegyeket fogadja el, más billenty� leütésére ne reagáljon, az Esc ütésére viszont azonnal érjen véget!

2. Kettesért: Készítsen Assembly programot, amely udvariasan beolvas egy 8 jegy� számot és eldönti, hogy hányas számrendszer� a szám: bináris, ha csak a 0 és 1 jegyeket tartalmazza, hexadecimális, ha el�fordulnak az A-F karak-terek, egyébként decimális. A döntést írja ki a képerny�re. A számbevitelt nem szükséges ellen�rizni. Hármasért: a beolvasott szám 1-8 jegy� lehet (befejezés Enterre), és a számbevitelt ellen�rizni kell: a program csak a 0-9 és A-F billenty�ket fogadja el, más billenty�t hagyjon figyelmen kívül (ne jelenjen meg a képerny�n sem).

3. Kettesért: Készítsen programot, amely beolvas egy pontosan 4 karakterb�l álló hexadecimális számot. A számbevi-telt ellen�rizni kell, tehát a program nem fogadhat el se kevesebb, se több karaktert, valamint 0-9 és A-F-t�l különbö-z� billenty�ket (az eltér� karaktert vagy ne vegye figyelembe, vagy adjon hibajelzést és kezdje elölr�l a bevitelt)! He-lyes beolvasás után írja ki (újból) a beolvasott számot a képerny�re.

4. Kettesért: Készítsen programot, amely beolvas egy pontosan 2 jegyb�l álló hexa számot (00-FF) és kiírja az értékét binárisan, tagolva a képerny�re. Például a 00 beolvasása esetén írja ki: „00000000 00000000”. A számbevitelt nem szükséges ellen�rizni.

5. Kettesért: Készítsen programot, amely beolvas egy 0-9 közé es� számot és kiírja, hogy a szám kettes számrend-szerbeli alakjában az x. és y. bit értéke 0 vagy 1 (x és y értékét a vizsgáztató adja meg, értékük 0-7 közé eshet, a legalsó helyiérték a nulladik). Konkrét példa: ha az 5. és 6. bitet kell megállapítani, a 0 szám megadása esetén a program írja ki: „Az 5. bit értéke: 0; a 6. bit értéke: 0”.

6. Kettesért: Készítsen programot, mely beolvas a billenty�zetr�l egy karaktert és kiírja, hogy a karakter ASCII kódjában hány 0 és hány 1-es bit található. Például ha a szóközt adjuk meg, mivel annak ASCII kódja 32=00100000b, a prog-ram írja ki: „7 db. 0 bit, 1 db. 1 bit”. Hármasért: nem karaktert adunk meg, hanem egy kétjegy� számot (00-99).

7. Hármasért: Készítsen programot, amely beolvas egy nyolcjegy� bináris számot (például: 10001100) és megkérdezi, hogy balra, vagy jobbra történjen a léptetés, valamint hogy hány hellyel, a megadható válasz: 1-7 (mást ne fogadjon el). Ezután a beolvasott szám bitjeit eltolja a megadott irányba, a megadott hellyel, egyesével és minden lépést írjon ki a képerny�re, egymás alá! Az eltolás módját a vizsgáztató dönti el:

7a. A kilép� bit a túloldalon visszajön 7b. A kilép� bit elvész és a túloldalon mindig 0 lép be.

A számbevitelt nem szükséges ellen�rizni. 8. Hármasért: Készítsen programot, amely beolvas kett� darab nyolcjegy� bináris számot (például: 10001100 és

00110100) és megkérdezi, hogy az AND, OR vagy XOR m�veletet választom-e. A felhasználó az alábbi billenyt�kkel válaszolhat: a, A, o, O, x, X, Esc (ekkor befejez�dik a program), más billety�t ne fogadjon el. Utána a két számot írja ki egymás alá a képerny�re és bitenként hajtsa végre a választott logikai m�veletet. A végeredményt jelenítse meg a következ� sorban. A számbevitelt nem szükséges ellen�rizni.

9. Hármasért: A feladat megegyezik az el�z�vel, csak kett� darab egyjegy� számot (0-9) olvasunk be. 10. Hármasért: Készítsen programot, amely beolvas egy nyolcjegy� bináris számot (például: 10001100) és kiírja alá az

egyes komplemens alakját, szintén binárisan. A számbeolvasást ellen�rizni kell: csak a 0 és 1 jegyeket fogadja el, más billenty� leütésére ne reagáljon, az Esc ütésére viszont azonnal érjen véget!

11. Hármasért: Készítsen programot, amely beolvas egy egyjegy� számot (0-9), ezután ezt kiírja a képerny�re binárisan, utána kiírja alá az egyes komplemens alakját, szintén binárisan. A számbevitelnél ne fogadjon el más karaktereket!

12. Hármasért: Készítsen programot, amely beolvas egy nyolcjegy� bináris számot (például: 10001100) és kiírja alá a kettes komplemens alakját, szintén binárisan. A számbeolvasást ellen�rizni kell: csak a 0 és 1 jegyeket fogadja el, más billenty� leütésére ne reagáljon, az Esc ütésére viszont azonnal érjen véget!

13. Hármasért: Készítsen programot, amely beolvas egy egyjegy� számot (0-9), ezután ezt kiírja a képerny�re binárisan, utána kiírja alá a kettes komplemens alakját, szintén binárisan. A számbevitelnél ne fogadjon el más karaktereket!

14. Hármasért: Készítsen programot, amely beolvas egy kétjegy� hexa számot (00-FF) és tíz lépést kiír a képerny�re, hexadecimálisan úgy, hogy minden lépésnél a számot eggyel növeli. Például ha a 08-at adtuk meg, akkor a gép írja ki a képerny�re: 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12! A számbevitelt nem kell ellen�rizni. Négyesért: a számbevi-telnél hibás számot ne fogadjon el a gép, a lépések számát is meg kell adni (0-9 lehet), valamint ha a kiírás eléri az FF-et, álljon le a program.

Page 7: Assembly programozás

16

15. Hármasért: A feladat megegyezik az el�z�vel, csak a számot eggyel csökkenteni kell (négyesnél: a program álljon le 00-nál).

16. Hármasért: Készítsen programot, amely beolvas egy nyolcjegy� bináris számot (például: 10001100), utána megkér-dezi, hogy az els� négy, vagy az utolsó négy jegyét vegye-e figyelembe. A válasz (billenty�leütés) után a megadott négyjegy� szám (a példa esetében 1000 vagy 1100) értékét írja ki decimálisan a képerny�re! A számbevitelt nem szükséges ellen�rizni.

17. Hármasért: Készítsen programot, amely beolvas két darab kétjegy� számot (pl. 25 és 16) és összeadja �ket. A vég-eredményt kiírja a képerny�re ilyen formában: „25+16=41”. A számbevitelt nem szükséges ellen�rizni. A felhasználó úgy adja meg a két számot, hogy összegük legfeljebb 99 legyen.

18. Hármasért: Készítsen programot, amely beolvas két darab kétjegy� számot (pl. 25 és 16) és kivonja �ket. A vég-eredményt kiírja a képerny�re ilyen formában: „25-16=09”. A számbevitelt nem szükséges ellen�rizni. A felhasználó úgy adja meg a két számot, hogy különbségük ne legyen negatív.

19. Hármasért: Készítsen programot, amely beolvas két darab kétjegy� számot (pl. 09 és 15), összeszorozza �ket és a végeredményt kiírja a képerny�re ilyen formában: „09*15=135”.

20. Hármasért: Készítsen programot, amely beolvas két darab egyjegy� számot (pl. 9 és 4), ezután elosztja �ket egy-mással és kiírja a hányadost és a maradékot ilyen formában: „9/4: hányados=2, maradék=1”. Nullával osztás esetén adjon hibaüzenetet!

21. Hármasért: Készítsen programot, amely letörli a képerny�t és elszámol 21a. 0-tól 99-ig 21b. 99-t�l 0-ig (a vizsgáztató döntése szerint).

A számokat írja ki a képerny�re, egymás mellé, egyesével és mindig egy billenty� leütésére lépjen tovább, Esc-re vi-szont azonnal érjen véget! Négyesért: a program kérdezze meg, hogy hányasával számoljon (1, 2 vagy 3)!

Feladatok négyes-ötös osztályzatért: 22. Négyesért: Készítsen programot, amely beolvas egy nyolcjegy� bináris számot (például: 10001100) és kiírja az érté-

két decimálisan (a beírt szám el�jel nélküli!). Ezután kérdezze meg, hogy melyik bitjét kívánom 22a. törölni 22b. 1-re állítani 22c. ellentétesre állítani (a háromból egyet kérdezzen a program, a vizsgáztató dönti el).

A megadható válasz: 0-7 (a legalsó helyiérték a 0). Ezt hajtsa végre és írja ki a végeredményt bináris és decimális formában. A számbevitelt nem szükséges ellen�rizni.

23. Négyesért: Készítsen programot, amely beolvas egy 0-255 közé es� számot és kiírja, hogy prímszám-e! (A program matematikai m�veletekkel számoljon, ne táblázatból válassza ki a választ.)

24. Négyesért: Készítsen programot, mely udvariasan bekér kett�, 1 és 9 közé es� számot, majd az így megadott kez-d�értékekkel számolva kiírja a Fibonacci számokat, 99-ig! (Képlet: an=an-2+an-1)

25. Négyesért: Készítsen programot, amelynél a billenty�zet LED-jeit a billenty�r�l vezérelhetjük, mégpedig: az 1-es billenty� lenyomására, kigyullad a NumLock LED, 2-re a CapsLock, 3-ra a ScrollLock, 4-re mindhárom. A billenty� elengedésére a LED(ek) aludjanak el. Kilépés Esc-re.

26. Négyesért: Készítsen programot, amely beolvas egy 0-7 közé es� számot, ezt átváltja kettes számrendszerre és kiírja a képerny�re, továbbá a billenty�zet LED-jein is jelenítse meg az eredményt (világító LED=1-es bit, nem világí-tó=0)! Például a 0 megadása esetén írja ki a képerny�re: „000” és egyik LED se világítson. A számbeolvasásnál a program ne fogadjon el hibás megadást!

27. Ötösért: Készítsen programot, amely grafikus üzemmódban a képerny� teljes szélességében közepére kirajzol egy olyan, 20 képpont vastag szakaszt, amelynek eleje teljesen pi-ros, fokozatosan egyre kékebb és a vége teljesen kék (állóképr�l van szó). A program egy billenty� leütésére érjen véget. Variáció: a színátmenet a teljes képerny�n történjen, felülr�l lefelé!

28. Ötösért:

Készítsen programot, amely egy el�re eltárolt rövid szöveget (pl. "Világ") keres meg a képerny�memóriában: ha megtalálta, írja felül "-----" jelekkel és a legfels� sorba írja ki a találatok számát. Mindvégig szöveges képerny�n dolgozunk. A program induláskor ne törölje le a képerny�t és 9 találat után álljon meg!

29. Ötösért: Készítsen programot, amely felgyújtja a billenty�zeten a CapsLock LED-et, a másik két LED ne világítson. Ezután

29a. a bal és jobb Shift-tel 29b. az egér bal és jobb gombjával 29c. az egér balra-jobbra mozgatásával

„mozogjon” a LED balra-jobbra (Num/Caps/Scroll Lock). Körbeforgás nem kell, tehát pl. a NumLock-nál tartva a balra parancsot ne hajtsa végre a program. Kilépés Esc-re, vagy a 10. lépés után. (Segítség: 29a és 29b-nél a gomb felen-gedését is figyelni kell!)

piros kék

Találat: 3 db. ----- ----- ----- C:\>_

Page 8: Assembly programozás

17

Vizsgafeladatok megoldással Készítsen programot, amely letörli a képerny�t és egy megadott stringet for-dítva kiír a következ� sorba.

Hármasért: a szöveget egy udvarias felszólításra kell begépelni, max. 10 kar. lehet, befejezés Enterre.

Négyesért: a szöveget a program indítósorában paraméterként adjuk meg, szóközt is tartalmazhat.

A program adjon hibaüzenetet, ha nem írtunk be szöveget! Segítség: használja a vermet a szöveg tárolására!

; FORDIT1.ASM ; , , , , ; SZOVEGFORDITO PROGRAM HARMASERT ; TITLE fordit1 ; a program neve .MODEL TINY ; .COM állomány lesz .CODE ; kódszegmens (program) ORG 100h ; .COM-nál fontos és kötelezö! ; (a prg 100h offsettöl induljon) START: ; program kezdödik mov ax,3 ; képernyötörlés ROM megsza- int 10h ; kítás hívásával mov ah,9 ; tájékoztató üzenet kiírása mov dx,offset szoveg ; DOS megszakítással int 21h ; (DS:DX-töl $-ig) ; --- 1. Szöveg bekérése és verembe helyezése --- xor cx,cx ; CX=számláló, nullázzuk vissza1: ; végtelenített hurok indul mov ah,8 ; billentyü bekérése (AL-be) int 21h cmp al,enter_ ; Enter? Ha igen-->kiugrunk je tovabb cmp al,backspace ; Backspace? Ha nem-->tovább jne ide1 cmp cx,0 ; Ha még nem írtunk szöveget, jne t1 ; a Backspace hatástalan lesz call hang jmp vissza1 t1: ; A Backspace lekezelése pop dx dec cx mov ah,9 mov dx,offset torles int 21h jmp vissza1 ide1: ; (Ha nem ütöttünk Backspace-t) cmp cx,10 ; Elértük a 10. karaktert? jne ide2 call hang ; Ha igen, nem írhatunk be többet jmp vissza1 ide2: ; Ha nem: push ax ; a karaktert elmentjük a verembe inc cx ; a számlálót eggyel növeljük mov ah,2 ; a karaktert kiírjuk a képernyöre mov dl,al ; (DL-böl történik) int 21h jmp vissza1 ; hurok vége, kötelezö visszaugrás ; --- 2. Vizsgálat: beírtunk-e szöveget? --- tovabb: mov ah,9 ; soremelés mov dx,offset ujsor int 21h cmp cx,0 ; van beírt szöveg? jne ide3 mov ah,9 ; Ha nincs: hibaüzenet... mov dx,offset nincs_szoveg int 21h call hang ; ...hangjelzés... int 20h ; ...és kilépés DOS-ba

; --- 3. Szövegvisszaírás veremböl képernyöre --- ide3: mov ah,2 ; karakter kiíratás elökészítése vissza2: ; ciklus indul, számláló=CX (!!!) pop dx ; karaktert veremböl vissza DL-be int 21h ; karakter kiírása a képernyöre loop vissza2 ; ciklus vége int 20h ; kilépés DOS-ba (.COM esetén) ; --- 4. Rövid szubrutin, amely hangjelzést ad --- hang proc ; szubrutin kezdödik mov ah,2 ; hangjelzés mov dl,hangjelzes int 21h ret ; visszatérés a call "mögé" hang endp ; szubrutin vége ; --- 5. Minden egyéb adat a program végén --- enter_ equ 13 ; konstansok backspace equ 8 ; (billentyük ASCII kódjai) hangjelzes equ 7 szoveg db 'A program bekér egy max. 10 betüs s' db 'zöveget és fordítva kiírja a képern' db 'yöre. Backspace-javítás, Enter-' db 'vége',10,13,10,13,'Kérek egy szöveget: $' nincs_szoveg db 'Hiba! Nem írt be szöveget!$' torles db backspace,' ',backspace,'$' ujsor db 10,13,'$' END START ; program vége, belépési pont ; a "start" címkénél ; Megjegyzések: ; ------------- ; ; 1. A program kezeli a Backspace-t, a 10. betü után ; nem enged többet beírni, hangjelzést is ad, azaz ; alaposan túlhaladja a minimálkövetelményeket és ; a hármas szintet. ; 2. Az ea-on megismert rengeteg assembly utasítás ; közül a programban kb. 10 félét, tehát roppant ; keveset használunk csak fel! ; Természetesen a vizsgán is így lesz. ; Ezeket az utasításokat fejböl kell ismerni. ; mov = értékadó utasítás ; int = szoftver megszakítás (szubrutin hívása) ; cmp = "compare" (összehasonl, flagek állítása) ; je = "jump if equal" (ugrás ha egyenlö) ; jne = "jump if not equal" (ugrás ha nem egyenlö) ; jmp = "jump" (kötelezö ugrás) ; loop = CX=CX-1 és ugrás ha nem 0 (ciklus végén) ; inc = regiszter tartalmának növelése 1-gyel ; dec = regiszter tartalmának csökkentése 1-gyel ; push = regiszter mentése a verembe (16 bitet!) ; pop = verem tetejéröl vissza a regiszterbe ; call = szubrutin hívása ; ret = visszatérés a szubrutinból ("return") ; 3. Az "enter_ equ 13"-nál a végére azért kell ; aláhúzás, mert van egy ilyen assembly parancs, ; hogy ne legyen kavarodás (a fordító figyelmez- ; tet-"Warning"). ; 4. A felhasznált megszakítások a Tantárgyi útmuta- ; tó 73-74. oldalán találhatók meg. ; 5. Bonyolítási lehetöség: a program a "szürke" ; billentyüket ne kezelje le (a szürkék két kód- ; dal térnek vissza és az elsö visszatérésnél ; AL=0, így lehet felfedezni)!

A szöveg: Balaton notalaB C:\>_

Page 9: Assembly programozás

18

; FORDIT2.ASM ; , , , , ; SZOVEGFORDITO PROGRAM NEGYESERT ; TITLE fordit2 ; a program neve .MODEL TINY ; .COM állomány lesz .DATA ; adatok az adatszegmensben! szoveg db 'A program a prompt után beírt szöveget ' db 'fordítva kiírja a képernyöre.',10,13 db 10,13,'$' nincs_szoveg db 'Hiba! Nem írt be szöveget!',7,'$' .CODE ; kódszegmens (program) ORG 80h ; PSP-n belülre megyünk szoveghossz db ? ; a paramétersor hosszára ; egy változót állítunk! ; ("db ?"--> a változó kezdöér- ; téke az lesz, ami akkor abban ; a memóriarekeszben található!) ORG 100h ; .COM-nál fontos és kötelezö! ; (a prg 100h offsettöl induljon) START: ; program kezdödik mov ax,3 ; képernyötörlés ROM megsza- int 10h ; kítás hívásával mov ah,9 ; tájékoztató üzenet kiírása mov dx,offset szoveg ; DOS megszakítással int 21h ; (DS:DX-töl $-ig) cmp szoveghossz,0 ; van valami a paramétersorban? jne tovabb mov ah,9 ; Ha nincs: hibaüzenet... mov dx,offset nincs_szoveg int 21h int 20h ; ...és kilépés DOS-ba tovabb: ; Ha van: mov ah,2 ; karakter kiíratás elökészítése xor ch,ch ; a ciklusszámlálónak (CX) érté- mov cl,szoveghossz ;ket adunk (xor nulláz!) mov si,81h ; SI-t ráállítjuk a legutolsó ka- add si,cx ; rakterre ciklus: ; ciklus kezdödik mov dl,[si] ; aktuális karaktert betöltjük int 21h ; karakter kiírása (DL-böl) dec si ; elözö karakter loop ciklus ; ciklus vége int 20h ; kilépés DOS-ba (.COM esetén) END START ; program vége, belépési pont ; a "start" címkénél ; Megjegyzések: ; ------------- ; ; 1. A program rövidebb, mint a FORDIT1.ASM, viszont ; bonyolultabb (négyes szintü). ; ; 2. A PSP 80h értéke tartalmazza a paramétersor ; hosszát (erre állítottunk rá egy változót), ; 81h=" " vagy "/" és 82h-tól találhatók a karak- ; terek. ; ; 3. A megoldásban nem használjuk fel a vermet. ; ; 4. A paramétersorban kb. 120 karaktert adhatunk ; meg.

Kettesért: Készítsen programot, amely letörli a képer-ny�t, bekér két egyjegy� számot és összeadja az ábrán látható módon. A két számot a felhasználó úgy adja meg, hogy ösz-szegük max. 9 lehet. ; OSSZEAD.ASM ; , , , ; OSSZEADO PRG HARMASERT ; ; TITLE osszead .MODEL TINY .CODE ORG 100h START: mov ax,3 ; képernyötörlés int 10h mov ah,9 ; üzenet kiírása mov dx,offset szoveg1 int 21h mov ah,1 ; elsö számjegy int 21h ; bekérése (AL-be) mov elso_szam,al ; és eltárolása mov ah,9 ; új sor+üzenet ki- mov dx,offset szoveg2 ; írása int 21h mov ah,1 ; második számjegy int 21h ; bekérése és el- mov masodik_szam,al ; tárolása mov ah,elso_szam ; összeg kiszámolása add ah,masodik_szam sub ah,'0' mov osszeg,ah mov ah,9 ; végeredmény kiírása mov dx,offset vegeredmeny int 21h int 20h ; kilépés DOS-ba ; --- Adatok a program végén --- vegeredmeny db 10,13 elso_szam db ? db '+' masodik_szam db ? db '=' osszeg db ? db '$' ; fontos a végén a $ jel! szoveg1 db 'A program összead két egyjegyü számot. ' db 'Semmilyen ellenörzés nincs. Ha az össze' db 'g 9-nél nagyobb, rossz eredményt ad.' db 10,13,10,13,'Kérek egy számot: $' szoveg2 db 10,13,'Egy másik számot: $' END START ; Megjegyzések: ; ------------- ; 1. Számból karaktert az add regiszter,'0' uta- ; sítással tudunk csinálni. Igy lesz a 0 számból ; "0" karakter, az 1 számból "1" karakter stb. ; Tehát pont az lesz, ami nekünk kell, amit majd ; DL-böl kiíratunk! ; Hasonló módon az ellentéte, karakterböl szám: ; sub regiszter,'0'. ; Amikor a végén összeadom a két számjegyemet, a ; fent leírtak miatt kell kiadnom a sub ah,'0' ; utasítást, hogy "normális", kiíratható szám- ; karaktert kapjak! ; 2. A "vegeredmeny" tulajdonképpen egy string, a- ; melynek egy-két adata ismeretlen, ezeket a ; program a futása alatt kitölti és a végén a ; szövegkiírató megszakítással kiíratjuk.

Kérek egy számot:5 Egy másik számot:3 5+3=8 C:\>_

Page 10: Assembly programozás

19

Kettesért: Készítsen programot, amely letörli a kép-erny�t, kiírja az „Üssön le bet�ket és számokat, Esc, q, Q - vége!" üzenetet, és a leütött karaktereket kiírja egymás mellé, de az "1", "2" és "3" leütésekor a számok helyett az „egy", „kett�", „három" szavakat je-lenítse meg! A program a 10. leütött billenty�re, Esc-re, ”q"-ra vagy "Q"-ra érjen véget (amelyik el�bb bekövetke-zik).

; BETUK2.ASM ; , ; PROGRAM KETTESERT ; TITLE betuk2 .MODEL TINY .CODE ORG 100h START: mov ax,3 ; képernyötörlés int 10h mov ah,9 ; üzenet kiírása mov dx,offset szoveg int 21h ;--- A lényeg --- mov cx,10 ; ciklus, max. 10 kar. bekérése ciklus: ; ciklus indul mov ah,8 ; karakter csendes bekérése (AL) int 21h cmp al,escape ; Esc,q,Q ? Ha igen-->kilépés je kilepes cmp al,'q' je kilepes cmp al,'Q' je kilepes cmp al,'3' ; !!! Az ASCII-nál a számok a ka- ja karakter ; rakterek elött vannak. ; ja=jump if above, ugrás ha na- ; gyobb ; Az 1,2,3-at ütöttem le: mov ah,9 ; string kiírás elökészítése mov dx,offset egy ; DX-et a megfelelö helyre cmp al,'2' ; pozícionálom jne tovabb1 mov dx,offset ketto tovabb1: cmp al,'3' jne tovabb2 mov dx,offset harom tovabb2: int 21h ; string kiíratása jmp ide ; kötelezö ugrás a ciklus végére karakter: ; normális karaktert ütöttem le: mov ah,2 ; karakter kiírása (DL-böl) mov dl,al int 21h ide: loop ciklus ; ciklus vége kilepes: int 20h ; kilépés DOS-ba ;--- adatok a program végén --- szoveg db 'Ussön le betüket és számokat, Esc, q,' db ' Q - vége!',10,13,'$' egy db 'egy$' ketto db 'kett�$' harom db 'három$' escape equ 27 END START

Kettesért: Készítsen programot, amely letörli a kép-erny�t, megkérdezi „Hogy hívnak?" és bekér egy ne-vet, amely kettesért pontosan 5 bet�b�l áll, hárma-sért maximum 10 karakter és Enterre fejez�dik be. Ezután a következ� sorba írja ki: „Szia, <név>!". Hármasért a program még hibaüzenetet is adjon, ha nem írunk be szöveget!

; SZIA.ASM ; , , ; PROGRAM HARMASERT ; TITLE szia .MODEL TINY .DATA szoveg db 'Hogy hívnak? $' hiba db 10,13,'Hiba! Nem írt be semmit',hang,'$' kiirjuk db 10,13,'Szia, ' ide db 11 dup ('$') ; 11 dollárjel egymás után hang equ 7 ; konstansok enter_ equ 13 .CODE ORG 100h START: mov ax,3 ; képernyötörlés int 10h mov ah,9 ; üzenet kiírása mov dx,offset szoveg int 21h ;--- 1. Szöveg bekérése --- mov di,offset ide ; DI-t rápozícionálom arra a ; memóriaterületre, ahová a be- ; olvasott szöveget eltárolom. ; (Az elején "$"-okból áll.) mov cx,10 ; ciklus, max. 10 kar. olvasása ciklus: ; ciklus indul mov ah,8 ; karakter csendes bekérése AL-be int 21h cmp al,enter_ ; Enter? Ha igen-->kiugrás je tovabb1 mov [di],al ; A leütött karaktert eltárolom! inc di ; következö memóriapozíció mov ah,2 ; a leütött kar. kiírása (DL-böl) mov dl,al int 21h loop ciklus ; ciklus vége ;--- 2. Új sorba szövegkiírás, vagy hibaüzenet --- tovabb1: mov ah,9 ; szövegkiíratás elökészítése mov dx,offset kiirjuk ; default=amit beírtunk mov di,offset ide ; ha nincs beírt szöveg, DX-et cmp byte ptr [di],'$' ; átpozíc. a hibaüzenetre! jne tovabb2 mov dx,offset hiba tovabb2: int 21h ; üzenet kiírása mov ah,2 ; "!" kiírása mov dl,'!' int 21h int 20h ; kilépés DOS-ba

Üssön le bet�ket: wXegykettoK4Gharom kettoE C:\>_

Hogy hívnak? Gabi Szia, Gabi! C:\>_

Page 11: Assembly programozás

20

END START ; Megjegyzés: ; ----------- ; ; A program "cseles": a szöveget karakteres megszakítás- ; sal kérem be és minden betüt eltárolok az adatszegm.- ; ben egy megfelelö helyen. Pontosabban ez a hely "$" ; -okat tartalmaz eredetileg, azokat írom felül. Ennek ; oka, hogy utána a stringkiírató megszakítással írom ki ; a következö sorba a szöveget, azaz az ELSO "$" pont ; ott lesz, ahol az eltárolt szövegem véget ér! Más nem ; marad hátra, mint a "!" kiírása és kész. ; ; Az elején azért adtam meg TIZENEGY dollárjelet, mert ; ha neadjisten kihasználom a 10 leüthetö karaktert, ; pont marad még egy "$" a végén, amely befejezteti a ; szövegkiírást (INT 21h 9-es alszolgáltatása). ; ; Azt, hogy van-e beírt szöveg úgy figyeljük, hogy meg- ; nézzük az elsö "$"-t megvan-e még. Ha megvan, nem ; írtunk be szöveget, a stringkiírást (DX-et) átpozício- ; nálom a "hiba" címkére. Ha nincs, DX nem változik. ; ; Ha a cmp byte ptr [di],'$'-nél kihagyjuk a "byte ptr" ; -t, a fordító figyelmeztet (Warning), de lefordítja a ; programot, amely mindaddig jól müködik, amíg egy üres ; Entert nem ütök, ekkor nem ad hibaüzenetet (rosszul ; müködik)! ;

Négyesért: Készítsen programot, amely grafikus üzemmódban a kék háttérszín� képerny� közepére kicsiben kirajzolja a magyar zászlót. Ezután várjon egy billenty� leütésére és cserélje fel a zöld és piros színeket, valamint a hátteret feketére, majd egy újabb billenty�re érjen véget.

Ötösért: a billenty�leütés után a színátmenet lassan,

fokozatosan történjen, kb. 10 mp alatt!

; ZASZLO.ASM ; , , ; GRAFIKUS PROGRAM NEGYESERT (VGA-MCGA) ; TITLE zaszlo .MODEL TINY .DATA ; átállítandó színek: szinek db 0,0,0,63 ; háttér-->kék db 1,63,0,0 ; 1. elötér-->piros db 2,63,63,63 ; 2. elötér-->fehér db 3,0,63,0 ; 3. elötér-->zöld ; billentyüleütés után: db 0,0,0,0 ; háttér-->fekete db 1,0,63,0 ; 1. elötér-->zöld db 3,63,0,0 ; 3. elötér-->piros .CODE ORG 100h START: mov ax,0a000h ; képernyömem. kezdöcímét mov es,ax ; ES-be töltjük mov ax,13h ; váltás VGA-MCGA üzemmódba int 10h

;--- 1. Színek beállítása --- mov si,offset szinek ; SI-t rááll. az adatainkra mov cx,4 ; 4 színt kell átállítani call palettabeallitas ; beállító szubr. meghívása ;--- 2. Zászló megrajzolása közvetlen --- ; képernyömemória használattal ; (3 egymásba ágyazott ciklus) mov di,320*49+80 ; zászló bal felsö sarka mov al,1 ; 1.színnel kezdjük (piros) mov cx,3 ; a zászló 3 színböl áll ciklus1: push cx mov cx,25 ; egy szín vastagsága ciklus2: push cx mov cx,160 ; zászló szélessége ciklus3: mov es:[di],al ; képpont kigyújtása inc di ; következö képpont loop ciklus3 add di,320-160 ; egy sorral lejjebb pop cx loop ciklus2 inc al ; következö szín jön pop cx loop ciklus1 ;--- 3. Billentyü leütése + vertical blank --- mov ah,8 ; billentyüre várunk int 21h ; (csendes bekérés) mov dx,3dah ; vert. blank, hogy a szín- var: in al,dx ; váltás ne legyen "csúnya" test al,1000b jz var ;--- 4. Paletta átállítása --- mov cx,3 ; 3 színt kell átállítani call palettabeallitas ; szubrutin hívása ; (SI pont jó helyen áll!) ;--- 5. Befejezés --- mov ah,8 ; billentyüre várunk int 21h mov ax,3 ; 80x25-ös szöveges üzemmód int 10h ; és képernyötörlés int 20h ; kilépés DOS-ba ; --- Palettabeállító szubrutin --- palettabeallitas proc ; kiküldjük az átállítandó mov dx,3c8h ; szín sorszámát és az RGB mov al,[si] ; bájtokat. CX mondja meg, out dx,al ; hogy hány színt kell át- inc dx ; állítani mov al,[si+1] out dx,al mov al,[si+2] out dx,al mov al,[si+3] out dx,al add si,4 loop palettabeallitas ; ciklus(!), a köv. szín ret palettabeallitas endp END START

Page 12: Assembly programozás

21

3. Önálló gyakorló feladatsor Bevezet� A most következ� feladatsort azoknak ajánljuk, akik még nem programoztak Assemb-lyben. Ez a tizen-egynéhány oldal segít leküzdeni a kezdeti nehézségeket. A teljes feladatsor elvégzése mintegy 2 órát igényel. A lépéseket egymás után végezze el, ne hagyjon ki, ne ugorjon át semmit. Az egyes lépések után megadunk egy képerny�má-solatot is, ezzel ellen�rizheti munkáját: ha számítógépén hasonló jelenik meg, minden rendben van, ellenkez� esetben valamit rosszul csinált. Ekkor javítsa ki, és utána folytassa a gyakorlást. Fontos! Ne dolgozzon órákat egyhuzamban, egészségének kímélése érdekében 40-45 percenként tartson rövid szünetet! A számítógépes munkahelyeken ma már törvény írja el� szünetek beiktatását (50/1999. (XI.3.) EüM rendelet a képerny� el�tti munkavégzés minimális egészségügyi és biztonsági követelményeir�l, valamint 3/2002. (VIII.30.) ESzCsM rendelet a képerny� el�tti munkavégzés minimális egészségügyi és biztonsági követelményeir�l szóló 50/1999. (XI.3.) EüM rendelet módosításáról). Az MS-DOS felület elindítása Az Assembly programozást MS-DOS rendszer alatt fogjuk gyakorolni. Az MS-DOS megle-het�sen régi, de a Windows - a felülr�l kompatibilitás miatt - tartalmazza. Ezért ez a fel-adatsor Windows 95/98/ME/XP-s, vagy csak DOS-t tartalmazó (régi) számítógépen is el-végezhet�. Másra nincs is szükségünk, egészen a 30. oldalig. Ezt követ�en egy Assemb-ler fordítóprogram is kell majd. A számítógép bekapcsolása és az operációs rendszer betölt�dése után indítsuk el az MS-DOS felületet (taszkot): egérrel kattintsunk a Start - Minden program - Kellékek - Parancs-sor -ra (Windows 95/98-nál: Start-Programok-MS-DOS parancssor, Windows ME-nél: Start-Programok-Kellékek-MS-DOS parancssor):

El�fordulhat, hogy ezt a sort nem találjuk a Start gombra kattintáskor. Van egy másik megoldás is: Start - Futtatás, majd írjuk be: cmd (Enter), erre biztosan elindul (Windows 95/98/ME-nél dosprmpt-t írjunk be):

Page 13: Assembly programozás

22

Megjelenik a DOS felület (fekete háttér, prompt jel, villogó kurzor). Ha ablakban jelenik meg, célszer� a bal Alt és az Enter billenty� egyidej� lenyomásával teljes képerny�re vál-tani (az ablakba visszaváltás ugyanígy történik), de ha gondoljuk, dolgozhatunk ablakban is:

Most hozzunk létre egy könyvtárat, ahol gyakorolni fogunk, vagy lépjünk be a TEMP könyvtárba, amely az ideiglenes fájlok gy�jt�helye és itt gyakoroljunk. A TEMP könyvtárba lépéshez adjuk ki az alábbi parancsokat (a sorok végén üssünk Entert):

C:\>cd\ C:\>md temp A könyvtár már létezik. C:\>cd temp C:\TEMP>_

Magyarázat: a cd parancs könyvtárat vált. A „\” jel a gyökérkönyvtárat jelenti, oda lépünk, bárhol is va-gyunk. A „\” jelet a jobb Alt és a Q bet� egyidej� lenyomásával hozhatjuk el�, vagy tartsuk lenyomva a bal Alt-ot és a billenty�zet jobb szélén található numerikus billenty�zeten üssük le a 9-es, majd a 2-es számot, majd engedjük fel az Alt-ot (azaz 92-es ASCII kód); ha nem megy, mindenekel�tt nyomjuk meg a NumLock gombot. Az md paranccsal létrehozzuk a TEMP könyvtárat, mert néhány esetben nem létezik. Ha már van TEMP, az utasítás hatástalan. A legalsó sor végén látható „_” jel a villogó kurzor. Ezeket a DOS parancsokat Ön már nyilvánvalóan fejb�l tudja, csak a biztonság kedvéért írtuk le. Ez a kiindulóhelyzet. Minden újrakezdésnél a fenti lépéseket kell újra elvégeznünk. A Windows rendszerben a DOS ablak általános lehet�ségei:

• DOS parancsokat tudunk kiadni (az el�bb pl. kiadtuk a cd és az md parancsot); • Magyar nyelv� Windows XP esetén a Shift+Alt (Windows 95/98/ME-nél Ctrl+Alt+F1 és

Ctrl+Alt+F2) billenty�zetkombinációval válthatunk az angol és a magyar billenty�zet között. Ha magyar van beállítva, a billenty�zetre festett kiegészít� jelek a jobb Alt billenty� lenyomásával érhe-t�k el, pl. \=jobb Alt+Q stb;

Page 14: Assembly programozás

23

• A DOS ablak kétirányban tud kommunikálni a Windows Vágólappal: teljes képerny�s üzemmódban a PrintScreen billenty� átmásolja a képerny� tartalmát a Vágólapra (szöveges/grafikus módban). Ab-lakos üzemben az Alt+PrintScreen kimásolja az ablak tartalmát a Vágólapra, mindig grafikusan. A bal fels� sarokban található ikonra kattintva, majd a Szerkesztés-Megjelölést választva a képerny� egy részét kimásolhatjuk a Vágólapra (egérrel kijelölve a téglalap alakú területet és Entert ütve), il-letve a Szerkesztés-Beillesztés paranccsal a Vágólap tartalmát billenty�zetleütés (!) formájában átad-hatjuk a DOS ablakban éppen futó programnak;

• Az exit (Enter) parancs kiadásával a DOS ablak (taszk) bezáródik és „visszatérünk” a Windowsba - ez a szabályos kilépés;

• Ha programunk lefagy (Assemblyben nem ritka), az el�z� lépést nem tudjuk végrehajtani. Ekkor az ablakot rendszerszinten a Ctrl+Alt+Delete és utána Enter segítségével zárhatjuk be.

1. Gépi kód Els� feladatként írjunk egy gépi kódú programot, ami kiír a képerny�re egy A bet�t! (Egy új programozási nyelv megismerésekor az els� program általában egy szöveg megjelenítése szokott lenni, ezt a szokást követjük mi is. A „Hello World!” kiírása számtalan program-nyelven megtalálható itt: http://www.latech.edu/~acm/HelloWorld.shtml). Tartsuk lenyomva a bal Alt-ot és a billenty�zet jobb oldali, ún. numerikus részén üssük le a 9-est, majd a 2-est és engedjük fel az Alt-ot! Ha a képerny�n megjelenik egy „\” jel, akkor rendben van, ellenkez� esetben nyomjuk meg a NumLock gombot és próbáljuk meg még egyszer. Ha megjelent, a Backspace („visszanyíl”) billenty�vel töröljük le! Gépeljük be a következ� parancsot: copy con gepikod.com (a végén üssünk Entert). Ez-után úgy mint el�bb, írjuk be az alábbi számokat: 180, 2, 178, 65, 205, 33, 205, 32. Tehát nyomjuk le a bal Alt-ot, üssük le a jobb oldalon az 1-8-0-t és engedjük fel a bal Alt-ot. A képerny�n megjelenik egy furcsa jel, a 180 ASCII kódja. Ugyanígy jön a következ� szám stb. Legvégül üssük le az F6-ot és Entert:

C:\TEMP>copy con gepikod.com �^B�A=!= ^Z 1 fájl másolása megtörtént C:\TEMP>_

Magyarázat: a copy parancs eredetileg fájlok másolására szolgál, de a con a konzolt, billenty�zetet jelenti, azaz a billenty�zetr�l közvetlenül egy fájlba írjuk az adatokat. A fájl tartalma 180, 2 stb. (bájtok), ezt a DOS megjeleníti ASCII formában, pl. 65=”A” de a többi egyéb jel, ezért láthatunk kriksz-krakszot. A fájl vége DOS-ban Ctrl+Z, egy billenty�vel F6, ezért adtuk ki a gépelés befejezéseként. Futtassuk le! Írjuk be: gepikod (Enter). Ha jól dolgoztunk, megjelenik az A bet�:

C:\TEMP>gepikod A C:\TEMP>_

Ha valamit elrontottunk, elképzelhet�, hogy programunk lefagy. Ekkor zárjuk be a taszkot rendszerszinten, és kezdjük elölr�l az egészet. A rendszerszint� bezárás magától is bekö-vetkezhet. Ekkor nyissuk meg újra a DOS ablakot és lépjünk be a megfelel� (TEMP) könyvtárba. Ez lenne tehát a gépi kód: számokból áll, minden szám valamilyen utasítást, vagy ahhoz tartozó adatot jelent a processzornak és ami a legfontosabb: a CPU bekapcsolástól kikap-csolásig másodpercenként akár tízezer-százezer gépi kódú utasítást hajt végre! A pro-

Page 15: Assembly programozás

24

cesszor csak ezt érti meg, tehát bármilyen programozási nyelven írjunk programot, a for-rásprogram nem futtatható, csak fordítás után. A CPU az Assembly nyelvet sem érti meg, ezt is le kell majd fordítani gépi kódra. A gépi kóddal többet nem foglalkozunk, elég ez a rövid bepillantás. 2. Assembly program írása a Debug programmal Láthatjuk, hogy gépi kódban nem könny� programozni. A DOS része egy DEBUG nev� segédprogram (küls� DOS parancs, debug.exe, kb. 20 KB méret� – rövid!), amely képes Assembly nyelven írt utasításokat lefordítani gépi kódra és vissza, azaz egy assemb-ler/disassembler program. Indítsuk el a debug (Enter) parancs kiadásával:

C:\TEMP>debug -_

A megjelen� gondolatjel (mínusz jel) a debug saját promptja. Írjuk be: ? (Enter), megjelen-nek a használható parancsok. Az „a” bet� (parancs) kiadásával váltsunk át assember módba (az idéz�jelet nem kell be-írni, tehát üssük le az a bet�t és Enter)! Írjuk be az alábbi Assembly utasításokat, a sorok végén üssünk Entert:

mov ah,2 mov dl,41 int 21 int 20

Az utolsó Enter után nyomjuk le a Ctrl+Break-et is (a Break billenty� a PageUp felett talál-ható), ezzel kilépünk az assembler üzemmódból. A képerny�n ezt láthatjuk:

-a 146E:0100 mov ah,2 146E:0102 mov dl,41 146E:0104 int 21 146E:0106 int 20 146E:0108 ^C -_

(Magyarázat: a sorok elején a szegmens-offset memóriacím látható, ahová kerül a prog-ram, ez RAM terület. Az Ön számítógépén a szegmens cím, azaz a kett�spont el�tti szám más is lehet, mint a képen. Az offset cím viszont mindig 100h-tól kezd�dik, azaz .COM jelleg� fájlt készíthetünk. Az offset cím kettesével n�, azaz véletlenül mind a négy utasítá-sunk 2 bájtos. A Debug-ban minden szám hexadecimális, így a 41h valójában 65, az A bet� ASCII kódja. Az egyes Assembly parancsok jelentését itt most nem magyarázzuk el. Ismeretüket feltételezzük, megtalálhatók a tananyag többi részében.)

A „g” parancs (go, futtatás) segítségével futtassuk le programunkat (az idéz�jelet továbbra se írjuk be)! A képerny�n megjelenik az A bet� és egy üzenet, hogy programunk lefutott:

Page 16: Assembly programozás

25

-g A A program normál módon véget ért. -_

Adjuk ki az „u” parancsot (unassemble, visszafejtés, disassemblálás)! A Debug a beírt báj-tokat visszafordítja Assembly utasításokra, visszakapjuk az el�z�leg beírt négy parancsot. A beírt Assembly sorokat a Debug nem jegyezte meg, hanem a gépi kódot fordította visz-sza Assemblyre!

-u 146E:0100 B402 MOV AH,02 146E:0102 B241 MOV DL,41 146E:0104 CD21 INT 21 146E:0106 CD20 INT 20 146E:0108 741A JZ 0124

Csak az els� négy sor a „mienk”, a többi a memóriában maradt maradék, nem része prog-ramunknak. Az ötödik sortól lehet, hogy nem is az itt látható JZ 0124 fog megjelenni. A Debug nemcsak Assembler/Disassembler, hanem egyéb lehet�ségeket is nyújt, ame-lyek a program módosítására, hibakeresésre használható. Ezekb�l nézzünk meg néhá-nyat. Adjuk ki a „d” parancsot (dump)! A Debug a memória tartalmát megjeleníti hexadecimáli-san, és – ahol lehet – ASCII karakterekkel. Az els� 8 bájt (a „20”-ig) a programunk. A jobb oldalon láthatjuk az A bet�nket (negyedik karakter). -d 146E:0100 B4 02 B2 41 CD 21 CD 20-74 1A 64 80 3E 49 00 07 ...A.!. t.d.>I.. Írjuk át programunkat hogy „A” helyett „B” bet�t írjon ki! Látható, hogy az „A” bet� a 146E:0103h memóriarekeszben helyezkedik el (szegmens-offset cím; mert B4=100h, 02=101h stb.). Az itt található 41h-t kell átírni 42h-ra (ASCII kód). Adjuk ki az „e 103” (En-ter, adatbevitel, elég az offset cím) parancsot, írjuk be a 42-t és Enter. Utána a „g” (go, futtatás) paranccsal futtassuk le újra programunkat:

-e 103 146E:0103 41.42 -g B A program normál módon véget ért. -_

Adjuk ki ismét az „u” (unassemble, disassembler) és a „d” (dump, memóriatartalom megje-lenítése) parancsokat és figyeljük meg a változást. A parancsokat „u 100” és „d 100” for-mában adjuk ki! Ezzel jelezzük, hogy a 100h offset címt�l történjen, mert különben a Debug attól a memóriarekeszt�l folytatja, ahol az el�bb abbahagyta. Az „r” parancs megjeleníti a regisztereket, és a következ� végrehajtandó utasítást (ami programunk els� utasítása):

Page 17: Assembly programozás

26

-r AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=146E ES=146E SS=146E CS=146E IP=0100 NV UP EI PL NZ NA PO NC 146E:0100 B402 MOV AH,02 -_

A „p” paranccsal programunkat lépésenként futtathatjuk. Adjuk ki 4-szer egymás után és lefut programunk. Közben figyeljük meg a regiszterek értékének változását! A végén meg-jelenik: „A program normál módon véget ért.” üzenet. Az „r” parancs újbóli kiadása után láthatjuk, hogy az utasításmutató (IP regiszter) a prog-ram végére állt. Állítsuk vissza a programunk elejére: „r ip” (Enter), írjuk be: 100 (Enter):

A program normál módon véget ért. -r AX=0242 BX=0000 CX=0000 DX=0042 SP=FFEE BP=0000 SI=0000 DI=0000 DS=146E ES=146E SS=146E CS=146E IP=0106 NV UP EI PL NZ NA PO NC 146E:0106 CD20 INT 20 -r ip IP 0106 :100 -_

Ezek után programunk újból lefuttatható, akár a „g” (teljes program futtatása), akár a „p” (lépésenkénti programvégrehajtás) paranccsal, most azonban a „t” parancsot adjuk ki többször. Amíg a „p” a szubrutinokat, megszakításokat egy lépésben hajtja végre, a „t” parancs „belép” a szubrutinokba! Tehát az INT 21h utasításnál a megszakítást feldolgozó programot is láthatjuk (belépés után a képerny� bal szélén a szegmens cím megváltozik)! Hajtsunk végre kb. 10 lépést: 10-szer írjuk be a „t” parancsot és üssünk Entert. Ezután „g”-vel futtassuk a programot a végéig! Lehet, hogy a taszk rendszerszinten bezáródik, ekkor indítsuk el a Start menüb�l újra a DOS ablakot. Adjuk ki a „q” (quit, kilépés) parancsot, kilépünk a Debugból, megjelenik a DOS prompt. Most indítsuk el újra a Debug-ot a korábban megírt gepikod.com programmal és fejtsük vissza! Láthatjuk, hogy a gyakorló feladatsor elején beírt 8 bájt gépi kód megegyezik a most beírt négy Assembly utasítással. Végén a „q” paranccsal lépjünk ki. Mindezek végre-hajtása során az alábbi képerny�képet láthatjuk:

C:\TEMP>debug gepikod.com -u 1499:0100 B402 MOV AH,02 1499:0102 B241 MOV DL,41 1499:0104 CD21 INT 21 1499:0106 CD20 INT 20 1499:0108 315A58 XOR [BP+SI+58],BX 1499:010B 9D POPF 1499:010C 3D4100 CMP AX,0041 1499:010F 7503 JNZ 0114 1499:0111 E99AF8 JMP F9AE 1499:0114 E9CDBB JMP BCE4 1499:0117 8E1E66CF MOV DS,[CF66] 1499:011B FE06C403 INC BYTE PTR [03C4] 1499:011F 06 PUSH ES -q C:\TEMP>_

Page 18: Assembly programozás

27

3. További programírás a Debuggal: a „Hello” szó kiíratása Következ� Assembly programunk képerny�törlés után kiírja a képerny�re a „Hello” szót. Ez a program egy picit bonyolultabb az el�z�nél, de csak egy picit. Menet közben jegyez-zük meg a nehézségeket, sajnos a Debug lehet�ségei korlátozottak, majd a Turbo As-sembler könnyít a helyzeten. El�ször is a „Hello$” szó bet�inek (végén dollárjel) ASCII kódjára van szükségünk, mert a Debug-ba így kell bájtonként beírnunk. Egy ASCII kódtáblából kinézve, az ASCII kódok rendre: 72, 101, 108, 108, 111, 36. Ezt a Windows Számológéppel (Start – Futtatás – calc) alakítsuk át hexadecimálisra: 48, 65, 6c, 6c, 6f, 24. E számokat nemsokára fel fogjuk használni, most csak jegyezzük meg. Programunkat .COM fájlba szeretnénk menteni. A Debug tud menteni, de szektoronként. Ezért azt a megoldást választjuk, hogy létrehozunk egy üres fájlt (feltöltjük x bet�kkel), ezt betöltjük a Debugba, módosítjuk, majd mentjük. Azaz adjuk ki: copy con hello.com (végén Enter), gépeljünk be 20 db. x-et, majd F6 és En-ter. Programunk pontos méretét még nem ismerjük, megbecsüljük, ezért lett 20. Ha a tényleges méret nem lesz ennél több, akkor nem lesz baj. A képerny�n a következ� jelenik meg:

C:\TEMP>copy con hello.com xxxxxxxxxxxxxxxxxxxx^Z 1 fájl másolása megtörtént C:\TEMP>_

Indítsuk el a Debug programot a „debug hello.com” paranccsal, fájlunk betölt�dik. A „d” parancsra a memóriatartalom megjelenik a képerny�n, jobb oldalon láthatjuk a 20 db. x bet�t:

C:\TEMP>debug hello.com -d 1499:0100 78 78 78 78 78 78 78 78-78 78 78 78 78 78 78 78 xxxxxxxxxxxxxxxx 1499:0110 78 78 78 78 E9 CD BB 8E-1E 66 CF FE 06 C4 03 06 xxxx.....f...... 1499:0120 57 1E 56 1E 06 1F BE B9-86 26 C6 06 0D E5 00 E8 W.V......&......

E bet�ket fogjuk felülírni programunkkal: adjuk ki az „a” parancsot (assembler) és írjuk be az alábbi sorokat (képerny�törlés, szöveg kiíratása $ jelig, kilépés DOS-ba). A sorok vé-gén üssünk Entert, az utolsó Enter után még egy Ctrl+Break-et is:

mov ax,3 int 10 mov ah,9 mov dx,0 int 21 int 20

(A program m�ködésébe most nem megyünk bele. Képerny�törlés, szöveg kiírása és kilé-pés DOS-ba, ebb�l áll. Részletesen a tananyagban, vagy a 73-74. oldalon.)

Page 19: Assembly programozás

28

A képerny�n ezt láthatjuk:

-a 1499:0100 mov ax,3 1499:0103 int 10 1499:0105 mov ah,9 1499:0107 mov dx,0 1499:010A int 21 1499:010C int 20 1499:010E ^C -_

Beírtuk magát a programot. Hátra van még a „Hello$” szó elhelyezése. Hová helyezzük el? Legjobb lesz, ha a program végére, az int 20h utolsó utasítás utáni memóriahelyekre helyezzük (mentéskor nem vész el, a hello.com fájl része lesz)! Tehát feladataink: 1. eltá-rolni a szót, 2. DX-et ráállítani a megfelel� címre (jelenleg mov dx,0 szerepel, mert még nem tudjuk a pontos értékét és valamit meg kellett adni), 3. menteni. A képerny�n leolvashatjuk, hogy az utolsó utasítás utáni els� szabad memóriacím értéke 10eh (itt ütöttünk Ctrl+Break-et). Ez offset cím, a szegmens cím gépenként más és más lehet, most nem számít (mert .COM fájlt készítünk). Adjuk ki a következ� hosszú paran-csot: „e 10e 48,65,6c,6c,6f,24” parancsot! Mivel E=enter, vagyis adatbevitel, most megad-juk a kezd�címet és az összes beviend� értéket is (lásd „?”-help), ami nem más, mint a „Hello$” ASCII kódokban, amit nemrég számoltunk ki!

-e 10e 48,65,6c,6c,6f,24 -_

Ellen�rzési lehet�ség: a „d 10e” parancsra, próbáljuk ki! A jobb oldalon látható a „Hello$”. Adjuk ki az „u” (unassemble, visszafejtés) parancsot:

-u 1499:0100 B80300 MOV AX,0003 1499:0103 CD10 INT 10 1499:0105 B409 MOV AH,09 1499:0107 BA0000 MOV DX,0000 1499:010A CD21 INT 21 1499:010C CD20 INT 20 1499:010E 48 DEC AX 1499:010F 65 DB 65 1499:0110 6C DB 6C 1499:0111 6C DB 6C 1499:0112 6F DB 6F 1499:0113 24E9 AND AL,E9 1499:0115 CDBB INT BB 1499:0117 8E1E66CF MOV DS,[CF66] 1499:011B FE06C403 INC BYTE PTR [03C4] 1499:011F 06 PUSH ES -_

Itt láthatjuk a beírt Assembly sorokat és utána a Hello szó kódjait is (6 db. szám), amit egyébként a Debug megpróbált visszafejteni Assembly utasításokra, több-kevesebb siker-rel, pl. a dec ax már egy ilyen utasítás, de ide nem kerül a program vezérlése, a CPU nem fogja ezeket utasításként értelmezni. Feladatunk a „mov dx,0” utasítást megváltoztatni és most már tudjuk az új értéket: „mov dx,10e”. A képerny�r�l leolvashatjuk, hogy ez az uta-

Page 20: Assembly programozás

29

sítás a 107h offset címt�l található (és 3 bájtos)! Ezért adjuk ki: „a 107” (Enter), írjuk be: „mov dx,10e” (Enter és Ctrl+Break):

-a 107 1499:0107 mov dx,10e 1499:010A ^C -_

(Megjegyzés: természetesen ez az utasítás pont annyi bájtból áll, mint a „mov dx,0”, azaz nem írjuk felül az utána következ� „int 21h” parancsot.) Adjuk ki az „u 100” parancsot és gy�z�djünk meg a változásról. A sima „u” továbbfolytatja a visszafejtést onnantól, ahonnan abbahagyta, ezért adjuk meg, hogy a 100h offset címt�l történjen a visszafejtés. Az utolsó lényeges bájt (a $ jel, ASCII kódja 24h) a 113h címen van, 113h-100h+1=14h=decimális 20. Programunk tehát pont 20 bájtot foglal el, pont annyit, ameny-nyit lefoglaltunk, mentéskor a teljes program kikerül a háttértárra! A „w” paranccsal (write, írás a háttértárra) mentsük el programunkat, majd „q”-val lépjünk ki bel�le!

-w 00014 bájt írása -q C:\TEMP>_

Indítsuk el programunkat a „hello” kiadásával, képerny�törlés után megjelenik a szó:

Hello C:\TEMP>_

Elkészültünk. A „dir” parancs kiadása után is láthatjuk, hogy a „hello.com” fájl valóban 20 bájtos. (Ha az elején 20-nál több x-et írunk be a fájlba, a maradék a fájl végén ott marad, de nem okoz gondot, csak felesleges.) Megjegyzés: ha van id�nk és kedvünk, próbáljuk ki a Debug további lehet�ségeit. A „?” megjeleníti az ösz-szes parancsot és leírását, bár meglehet�sen sz�kszavúan. 4. Programírás Borland Turbo Assemblerrel Foglaljuk össze a Debug program imént megismert tulajdonságait:

• A Windows, pontosabban a DOS része (debug.exe), nem kell külön beszerezni; • Használata egyszer�, egybet�s parancsokkal vezérelhet�, de régimódi, nehézkes; • Assembly nyelv� programot le tud fordítani gépi kódra (assembler) és vissza

(disassembler); • Hibakeres� szolgáltatásokat nyújt: lépésenkénti programvégrehajtás (p és t), me-

móriatartalom kilistázása (d), megváltoztatása (e) stb., egyszóval monitorprogram.

Page 21: Assembly programozás

30

A Debug Assembly programozással kapcsolatos hátrányai: • Nem használhatunk címkéket (emlékezzünk vissza: a DX regisztert kézzel kellett

ráállítanunk a „Hello$”-ra, miután helyet találtunk neki, szintén manuálisan); • Adatterületre nem írhatunk be karaktereket, csak számokat (emlékezzünk megint a

Hello-ra, nekünk kellett megkeresni az egyes bet�k ASCII kódját); • Csak a gépi kód menthet�, az Assembly nyelv� forrás nem, emiatt a program ké-

s�bbi módosítása nehézkes, csak a futtatható fájlban módosíthatunk; • Csak 8086/8088 utasítások használhatók, a 80286 és feletti már nem (most nem

volt rá szükség, de pl. egy PUSHA vagy POPA néha jól jön). A felsorolt hátrányokat egy fejlett Assembler program mind tartalmazza, ezért kényelme-sebb a programírást ezen végezni. A Debug pedig megmarad „vész esetére”, vagy ha egy egyszer� változtatást kell végeznünk gyorsan, vagy programhiba keresésére (bár erre is vannak jobb debugger programok). Most tehát írjuk meg az el�bbihez hasonló, a „Helló világ!” szöveget kiíró programot Borland Turbo Assemblerben! (Ha mást, pl. Microsoft Macro Assemblert vagy egyéb prog-ramot használunk, a szintaxis eltér� lehet.) A Turbo Assembler nem része a Windowsnak, külön kell megszerezni és feltelepíteni. Ne-künk a tasm.exe és a tlink.exe fájlokra van szükség (az els� a compiler-fordító, a másik a linker-szerkeszt�), ami remélhet�leg benne van az elérési útban, azaz a path-ban. Adjuk ki tehát: tasm (Enter), utána tlink (Enter)! Ha az alábbi képerny�felirat jelenik meg, akkor sajnos nem tudjuk tovább folytatni a gyakorló feladatsort, mert vagy nincs gépünkön Turbo Assembler, vagy nincs benne a path-ban:

C:\TEMP>tasm Rossz parancs vagy fájlnév. C:\TEMP>tlink Rossz parancs vagy fájlnév. C:\TEMP>_

Ha egy kb. 1 oldalas leírás jelenik meg, akkor minden rendben, folytathatjuk. A programírás lépései: el�ször egy szövegszerkeszt�vel megírjuk a forrásprogramot és elmentjük .ASM fájlba. A szövegszerkeszt� bármi lehet, csak egyszer� .TXT típusban tud-jon menteni.

Szövegszerkesztésre felhasználható programok:

• copy con <fájlnév> (ezt már használtuk; el�nye, hogy az operációs rendszer része és szinte letörölhe-tetlen, mert a command.com parancsértelmez� hajtja végre; hátránya, hogy a beírt sor Enter ütése után már nem javítható);

• edit (a DOS klasszikus szövegszerkeszt� programja); • Windows Jegyzettömb (Notepad); • Microsoft Word (mentéskor a fájl típusa „MS-DOS szöveg sortöréssel (*.txt)” legyen)

Mi az edit programot fogjuk használni. Utána a tasm paranccsal lefordítjuk .OBJ (object, tárgykód) fájlra, a tlink segítségével pedig továbbfordítjuk .EXE-re vagy .COM-ra.

Page 22: Assembly programozás

31

Kezdjük tehát a forrásprogram megírásával! Adjuk ki az „edit vilag.asm” parancsot, elindul a szövegszerkeszt�. Nagyon figyelmesen gépeljük be az alábbi képen látható sorokat, a sorok végén üssünk Entert. Ügyeljünk arra, hogy ne hagyjunk ki semmit.

Beírás után ellen�rizzük:

• A 2. sorban a model szót egy L-lel kell írni, és el�tte van egy pont; • A 3. és 5. sorban a data és code szavak el�tt is egy-egy pont áll; • A 4. sorban a szoveg-et a tagolás miatt írjuk két szóközzel beljebb. Utána egy szó-

köz, majd db, újabb szóköz és két aposztróf (’) közé írjuk a szöveget! Az aposztróf angol billenty�zet (Ctrl+Alt+F1) esetén az L-bet�t�l kett�vel jobbra található – az Á bet�n - és Shift nélkül kell megnyomni. Magyar billenty�zet (Ctrl+Alt+F2) esetén Shift+1. Minden esetben: bal Alt+39. Tehát a UNIX-os ` jel („egyszeres nyitó idéz�-jel”) nem jó! A dollárjel jobb Alt+É, vagy Shift+4, vagy bal Alt+36.

• Az 6. sorban az org után egy szóköz áll, majd egybeírva: 100h (százhá) - a h jelzi, hogy a szám hexadecimális;

• A 7. sorban a start után egy kett�spont áll. Ha úgy gondoljuk, hogy minden rendben: bal Alt+F, utána K és Enter (kilépés mentéssel). Adjuk ki a „dir vilag” parancsot, megjelenik a most készített vilag.asm fájl:

C:\TEMP>dir vilag A(z) C meghajtóban lév� kötet: GYURI A kötet sorozatszáma: 0F35-12E1 C:\TEMP könyvtára VILAG ASM 193 08-03-01 12:00p vilag.asm 1 fájl 168 bájt 0 könyvtár 1,539,088,384 bájt szabad C:\TEMP>_

Elkészültünk a forrásprogrammal. Hasonlítsuk össze a Debug-beli lehet�ségekkel: a kiiratandó szöveg helyét címkével jelöltük meg, minden mást a Turbo Assembler fog ki-számolni – nem könnyebb? A forrásprogram elmenthet�, programunknak a title parancs-csal nevet is adhatunk, megjegyzéseket is írhatunk bele – nem jobb?

Page 23: Assembly programozás

32

Következik a fordítás (.OBJ tárgykódra), a compiler program segítségével. Adjuk ki a „tasm vilag” parancsot! A fájl kiterjesztését nem kell megadni, ha az a szokás szerinti .ASM.

C:\TEMP>tasm vilag Turbo Assembler Version 3.2 Copyright (c) 1988, 1992 Borland International Assembling file: vilag.ASM Error messages: None Warning messages: None Passes: 1 Remaining memory: 418k C:\TEMP>_

A fenti képerny�másolat azt mutatja, hogy a fordítás sikerült (mert nincs hibaüzenet: „Error messages: None”). Ha nem ez jelenik meg, akkor hibát vétettünk. A Turbo Assembler kiír-ja a hibás sor(ok) számát. Indítsuk el az edit programot, és javítsuk ki a hibá(ka)t! Adjuk ki ismét a „dir vilag” parancsot! A vilag.asm mellett megjelent a vilag.obj tárgykód fájl, amit a Turbo Assembler az imént készített el. Hiba esetén a tárgykód fájl nem jön lét-re. Következik a szerkesztés (.COM, .EXE fájl készítés), a linker program segítségével. Adjuk ki: „tlink/t vilag”:

C:\TEMP>tlink/t vilag Turbo Link Version 5.1 Copyright (c) 1992 Borland International C:\TEMP>_

(Megjegyzés: a /t paraméter a .COM fájl miatt szükséges, .EXE-nél elmarad. Adjuk ki üre-sen a „tlink” parancsot, és keressük ki a lehet�ségek listájából a „/t”-t. A fájl kiterjesztését itt sem kell megadni, a vilag.obj-t fogja keresni.) Ha forrásprogramunk hibátlan, a fenti kép jelenik meg. Ellenkez� esetben hibaüzenetet is kapunk, ekkor az edit szövegszerkeszt�vel javítsuk ki a forrásprogramban. Adjuk ki ismét a „dir vilag” parancsot! A vilag.asm és vilag.obj mellett megjelent a vilag.com, a futtatható fájl! (Van még egy vilag.map tájékoztató fájl, amit megnézhetünk pl. a „type vilag.map” paranccsal.) Indítsuk el programunkat a „vilag” (Enter) kiadásával! Képerny�törlés után megjelenik a képerny�n a „Helló világ!” üzenet:

Helló világ! C:\TEMP>_

Page 24: Assembly programozás

33

Most, hogy programunk m�ködik, kövessünk el szándékosan néhány hibát! Ennek az len-ne a célja, hogy a jöv�ben kevesebb eséllyel kövessük el újra, illetve ha mégis, könnyeb-ben ki tudjuk javítani. Indítsuk el a szövegszerkeszt�t: „edit vilag.asm”. A 4. sorban az aposztrófokat cseréljük ki a UNIX féle ` jelre („egyszeres nyitó idéz�jel”; angol billenty�zeten a Tab feletti 0 gombot üssük le), a 6. sorban az „org 100h”-t írjuk egybe: „org100h”, valamint a 7. sorban a start után töröljük a kett�spontot! Mentsünk (Alt+F, K, Enter) és adjuk ki a „tasm vilag”-ot:

C:\TEMP>tasm vilag Turbo Assembler Version 3.2 Copyright (c) 1988, 1992 Borland International Assembling file: vilag.ASM **Error** vilag.ASM(4) Extra characters on line **Error** vilag.ASM(6) Illegal instruction **Error** vilag.ASM(7) Illegal instruction **Error** vilag.ASM(14) Undefined symbol: START Error messages: 4 Warning messages: None Passes: 1 Remaining memory: 418k C:\TEMP>_

Négy hibaüzenetet kapunk, és nem keletkezik .OBJ fájl. A hibaüzenetek ()-ek között tar-talmazzák a hibás sor számát és egy rövid angol nyelv� magyarázatot. A címkénél a ket-t�spont hiánya két hibaüzenetet okozott: a 7. sorban a start szót parancsnak próbálta ér-telmezni a fordító és a 14. sorban („end start”) a start címkére történik egy hivatkozás, de a címkét nem találja a Turbo Assembler. Adjuk ki: „edit vilag.asm” és állítsuk vissza az eredeti, szintaktikailag helyes állapotot (a 4., 6. és 7. sorban kell javítani)! Most felsorolunk néhány gyakrabban elkövethet� hibát. Próbáljuk ki mindegyiket! A lépé-sek hasonlóak az el�z�höz: a forrásprogramban végezzük el a változtatást (ami a hibát fogja okozni), utána adjuk ki a „tasm vilag” parancsot és tanulmányozzuk a megjelen� hi-baüzenetet. Majd indítsuk el a szövegszerkeszt�t, állítsuk helyre a forrásprogramot a m�-köd� változatra és jön a következ� hibalehet�ség. Javaslat (Windows XP-nél nem kell, mert alapból tudja): indítsuk el a „doskey” segédprogramot, ezután a �� kurzornyilakkal el�hozhatjuk a korábban beírt DOS parancsokat, gyorsabban tudunk dolgozni. A doskey még azt is tudja, hogy ha leütünk egy vagy több bet�t és az F8-at, ekkor kiírja a megadott bet�vel (bet�kkel) kezd�d�, korábban begépelt parancsot.

• Legyen a címke ékezetes („szoveg” helyett legyen „szöveg”, 4. és 11. sor)! Eredmény: régebbi Assemblernél szintaktikai hiba, az újabbaknál nincs hiba, min-den rendben lesz.

• A 4. sorban töröljük le a $ jelet!

Eredmény: a program lefordítható („tasm vilag” és „tlink/t vilag”) és futtatáskor mást is ki fog írni. Ennek oka, hogy a kiírás a $ jelre fejez�dik be, így írták meg a meg-szakítást, amit használunk. Emiatt a gép addig írja ki a memória tartalmát, amíg nem talál egy $ jelet. Általában 10-15 sor szokott megjelenni. Tehát ez a hiba nem

Page 25: Assembly programozás

34

szintaktikai, hanem logikai. Sajnos a fordító csak a szintaktikai hibákat találja meg, az elvi hibákat nem, pedig de jó lenne �.

• A 9. sorban „int 10h” helyett írjunk „int 10”-et!

Eredmény: a program lefordítható és futtatható, de a képerny�törlés nem történik meg, mert a hexa 10 helyett a decimális 10-es megszakítást hajtja végre (logikai hiba).

• Hagyjuk ki az „org 100h” sort (írjunk elé egy pontosvessz�t, a fordító megjegyzés-

ként értelmezi)! Eredmény: a tasm hibátlanul lefut, a tlink jelez (súlyos elvi hiba, nem készíthet� .COM fájl):

C:\TEMP>tlink/t vilag Turbo Link Version 5.1 Copyright (c) 1992 Borland International Fatal: Cannot generate COM file : invalid initial entry point address C:\TEMP>_

• A „.model tiny” után, a második sorba írjuk be: „.stack” (pont van az elején!).

Eredmény: a tasm hibátlanul lefut, a tlink jelez (súlyos elvi hiba, nem készíthet� .COM fájl):

C:\TEMP>tlink/t vilag Turbo Link Version 5.1 Copyright (c) 1992 Borland International Fatal: Cannot generate COM file : stack segment present C:\TEMP>_

Vermet használhatunk .COM fájlnál is, a 64 K-s szegmens végét�l indul visszafelé, de a „.stack <veremméret>” paranccsal külön nem hozhatjuk létre.

• Az els� sort írjuk két L-lel: „.modell tiny”!

Eredmény: a fordító minden sorra hibát jelez, mert nem ismeri fel, hogy memória-modellel dolgozunk (elég rémiszt�, pedig csak egy bet� okozta a hibát):

C:\TEMP>tasm vilag Turbo Assembler Version 3.2 Copyright (c) 1988, 1992 Borland International Assembling file: vilag.ASM **Error** vilag.ASM(2) Illegal instruction **Error** vilag.ASM(3) Model must be specified first **Error** vilag.ASM(4) Code or data emission to undeclared segment **Error** vilag.ASM(5) Model must be specified first **Error** vilag.ASM(8) Code or data emission to undeclared segment **Error** vilag.ASM(9) Code or data emission to undeclared segment **Error** vilag.ASM(10) Code or data emission to undeclared segment **Error** vilag.ASM(11) Undefined symbol: SZOVEG **Error** vilag.ASM(12) Code or data emission to undeclared segment **Error** vilag.ASM(13) Code or data emission to undeclared segment **Error** vilag.ASM(14) Undefined symbol: START Error messages: 11 Warning messages: None Passes: 1 Remaining memory: 418k C:\TEMP>_

Page 26: Assembly programozás

35

• Töröljük az utolsó utasítást (azaz az int 20h-t, tegyünk elé egy pontosvessz�t, így a fordító megjegyzésként értelmezi)! Eredmény: a program lefordítható, rendben lefut, de utána nem lép ki DOS-ba, ha-nem a memóriában található további bájtokat (ami most a „Hello$” szóveg bet�i) megpróbálja utasításokként értelmezni! Eredmény lefagyás, vagy a Windows rend-szerszinten bezárja a taszkot (lásd a képet), esetleg visszajön a prompt jel.

Lefagyás vagy bezárás esetén indítsuk el újból az MS-DOS parancssort és lépjünk be a C:\TEMP könyvtárba.

Végezetül írjuk át a programot .EXE formátumra! Készítsünk egy új fájlt: adjuk ki az „edit vilag1.asm” parancsot! A begépelend� forrásprogram (vigyázat: a 6. sorban egy aláhúzásjel is található, ne hagyjuk ki!):

.model small

.data szoveg db 'Helló világ!$' .code start: mov ax,_data mov ds,ax mov ax,3 int 10h mov ah,9 mov dx,offset szoveg int 21h mov ax,4c00h int 21h end start

Mentsünk, lépjünk ki az edit-b�l, majd adjuk ki a „tasm vilag1”, majd „tlink vilag1” (a /t nem kell!) parancsokat:

C:\TEMP>tasm vilag1 Turbo Assembler Version 3.2 Copyright (c) 1988, 1992 Borland International Assembling file: vilag1.ASM Error messages: None Warning messages: None Passes: 1 Remaining memory: 418k C:\TEMP>tlink vilag1 Turbo Link Version 5.1 Copyright (c) 1992 Borland International Warning: No stack C:\TEMP>_

Page 27: Assembly programozás

36

A tlink kiír egy figyelmeztetést, hogy nem definiáltunk veremszegmenst. Most nem kell, nem baj, programunk attól még létrejön. A „vilag1” paranccsal futtassuk le programunkat (remélhet�leg lefut). A „dir vilag1” kiadásával ellen�rizhetjük, hogy valóban .EXE fájl kelet-kezett. Adjuk ki a „debug vilag1.exe” parancsot, majd az „u”-val fejtsük vissza a programot:

C:\TEMP>debug vilag1.exe -u 17E4:0000 B8E517 MOV AX,17E5 17E4:0003 8ED8 MOV DS,AX 17E4:0005 B80300 MOV AX,0003 17E4:0008 CD10 INT 10 17E4:000A B409 MOV AH,09 17E4:000C BA0600 MOV DX,0006 17E4:000F CD21 INT 21 17E4:0011 B8004C MOV AX,4C00 17E4:0014 CD21 INT 21 17E4:0016 48 DEC AX 17E4:0017 65 DB 65 17E4:0018 6C DB 6C 17E4:0019 6C DB 6C 17E4:001A A22076 MOV [7620],AL 17E4:001D 69 DB 69 17E4:001E 6C DB 6C 17E4:001F A06721 MOV AL,[2167] -_

Megjelenik a visszafejtett Assembly lista, figyeljük meg, hogy:

• A program nem feltétlenül a 100h offset címen kezd�dik (.COM-nál mindig); • A forrásprogram „mov ax,_data” és „mov dx,offset szoveg” utasításai már nem így

szerepelnek, a címkék helyére konkrét számok kerültek. Bizonyosodjunk meg róla, hogy a DS:DX (szegmens-offset) címen tényleg a „Helló világ!” bet�i találhatók! A képerny�r�l leolvasva láthatjuk, hogy jelen esetben DS-be 17E5 kerül (az AX regiszteren keresztül, lásd az els� sort), DX-be pedig 0006 (6. sor). Azaz adjuk ki a „d 17e5:0006” parancsot (vigyázat: lehet hogy az Ön gépén más számok jelennek meg, akkor természetesen azokat írja be!). A képerny�n ezt láthatjuk:

-d 17e5:0006 17E5:0000 48 65-6C 6C A2 20 76 69 6C A0 Hell. vil. 17E5:0010 67 21 24 8B 36 63 04 1E-8E 1E 65 04 AC 1F 3C 7C g!$.6c....e...<| 17E5:0020 74 07 3C 7C 74 03 E9 D1-00 8B 16 BF 06 B8 20 3D t.<|t......... = 17E5:0030 CD 21 73 03 E9 31 FF 8B-D8 B0 FF 86 47 18 A2 18 .!s..1......G... 17E5:0040 00 26 8B 3E EF DA 33 C9-1E 8E 1E 65 04 80 3C 0D .&.>..3....e..<. 17E5:0050 1F 75 03 E9 07 FF B0 7C-1E 8E 1E 65 04 38 04 1F .u.....|...e.8.. 17E5:0060 74 F1 1E 8E 1E 65 04 80-3C 7C 1F 74 E6 1E 8E 1E t....e..<|.t.... 17E5:0070 65 04 AC 1F AA E8 26 F1-74 0B 1E 8E 1E 65 04 A4 e.....&.t....e.. 17E5:0080 1F 41 41 EB E8 3C .AA..< -_

A jobb oldalon jelenik meg a „Helló világ!”, pontosabban megjelenik, de az ékezetes bet�k helyén egy-egy pont áll.

A „q” paranccsal lépjünk ki a debug programból.

Ezzel az utolsó lépéssel a gyakorló feladatsor végére érkeztünk. A „del.” parancs kiadásá-val töröljük munkánkat (illetve a teljes TEMP könyvtár tartalmát) és az „exit” parancs ki-adásával térjünk vissza a Windows-ba.

Page 28: Assembly programozás

65

Kiegészítések a Prezentációhoz 37. oldal: (Számrendszerekhez) A kettes számrendszer egyik jellemz�je, hogy a 0.1 (nulla egész egy tized) szám végte-

len értékes számjeggyel ábrázolható csak, míg decimálisan végessel. A kettes komplemens további képzési módja: képzem az egyes komplemens alakot és hozzáadok egyet.

39. oldal: A RAM paritásvédelem leírt változata a régi alaplapokra volt jellemz�. Itt egy 9. chip tárolta a paritásbiteket. Manapság az alaplapon egy ún. paritásgenerátor állítja el� a (mindig helyes) paritásbitet.

41. oldal: (Memóriacímzés) Nemcsak a memória legalsó, hanem a legfels� 16 bájtját is csak egyféleképpen érhetjük el szegmens-offset címzéssel. A legalsó címeknél a szegmens értéke 0, a legfels� címeknél FFFFh. (Más.) Az „Unreal mode” elérése: valós módból átkapcsolunk védettbe, majd speciális módon visszaváltunk valósba (a szegmensregiszter határt nem változtatjuk meg). Ezután címezhetünk 4 GB-ot valós módban. To-vábbi információk a Horváth Gábor féle ajánlott irodalomban találhatók. (Más.) Az 1 és 2 bájtos regiszterekben tárolható számtartomány értékek szorosan összefüggnek a magas szint� nyelvekben használható változók típusával (pl. integer), mert ugyanarról van szó!

46. oldal: Példa az egymásba ágyazott ciklus használatára: ha a ciklusmagot 65536-nál többször kívánjuk végrehajtani (pl. NOP-id�húzás).

47. oldal: A „fordított ciklus”-nál a ciklusváltozók a következ�képpen változnak (ha mindkét ciklus 1..3-ig tart):

Normál ciklus: Fordított ciklus: 1 1 1 1 1 2 2 1 1 3 3 1 2 1 4 2 2 2 5 3 2 3 3 1 3 2 3 3

Vagyis látható, hogy ha ezt nem támogatja egy programozási nyelv (a magas szint� nyelvek általában ilye-nek), egy if-es utasítással szimulálhatjuk. (Más.) Elágazás és ugrások: vannak olyan programozható számológépek, amelyekben nem létezik ez a lehe-t�ség. Egy másodfokú egyenlet gyökeit ki tudjuk így számolni, de nagyon lerontja az eszköz használatát, ha hiányzik az elágazás. (Más.) Assemblyben elegánsan kiadjuk a „cmp al,27” és „je kilepes” sorokat és minden OK (Esc billenty� üté-se esetén ugrik a program), de itt valójában más a lényeg. A zérus jelz�bit jut f�szerephez. Ugyanis az törté-nik, hogy a cmp utasítás beállít több jelz�bitet (mintha kivonás történne), és ha AL=27, akkor ZF=1 lesz. A JE utasítás pedig lekérdezi ZF-et és ugrik, ha 1. Ezeket a lépéseket már az Assembly utasítások (cmp és je) is „elrejtik” és megmaradnak bels� ügynek. (Más.) A magas szint� nyelveknél, a gépi kódra lefordításkor, egy elágazás (if-then-else jelleg� utasítás) vala-hol egy jelz�bit beállítást, lekérdezést és ett�l függ� ugrást fog jelenteni. Ugyanígy a 49. oldalon is: egy eljárás vagy függvény hívása valahol egy CALL szubrutinhívást jelent.

48. oldal: (Logikai m�veletek) az AND/OR/XOR utasítások bitenként végzik el a két operandussal a logikai m�veletet, az eredmény az igazságtábla alapján keletkezik. Ezért m�ködnek így. A kapuk hardveres használatára példa: az 1 bites összeadó egy AND és egy XOR kapuból áll. A XOR képzi az összeget, az AND az átvitelt! (A XOR utasítás használatához) egy bájt spórolása Assemblyben (XOR AX,AX és MOV AX,0) nagy eredmény Assembly programozásnál. Régebben a felhasználható memória kicsi volt, pl. néhány kilobájt méret�, minden bájt számított. A XOR utasítást nagyon gyakran használták regiszter nullázására. (Más.) A képerny� felett úgy tudom mozgatni az alakzatot, hogy a mozgó alakzat képpontjait a képerny�memória aktuális képpontjával nem felülíró, hanem XOR logikai kapcsolatba hozom (megjelenik az alakzat). Még egyszer ugyanígy XOR-olva elt�nik az alakzat és visszakapom a képerny� eredeti állapotát. Ezen módszer el�nye, hogy nem kell a képerny�memóriát elmentenem. Hátrány: a mozgó alakzat villoghat. (Más.) A titkosításnál ne úgy képzeljük el, hogy 8 bittel XOR-olom a titkosítandó üzenet bájtjait, hanem mond-juk 256 bites kulccsal + egyéb transzformációkat is felhasználva. Rögtön nehezebb lesz a visszafejtés! A ma használt titkosító eljárások is felhasználják ezt a módszert!

51. oldal: A megszakításokat feldolgozó áramkör régebben valóban az ábrán látható külön chipekb�l állt, a mai integráci-ós módszereknél nem látható ennyire külön-külön egységekben az alaplapon. (Más.) Látható, hogy a szabad IRQ vonalak száma kevés mert sok gyárilag hozzá van rendelve egy-egy hard-verhez. A kevés szabadra csatlakozó eszközök közül néhány konfliktusba kerülhet egymással és ekkor egyik sem m�ködik. Ez az ún. „IRQ ütközés”. Lásd még a 70. oldalon is!

52. oldal: A három bájtos Windows-lefagyasztó .COM fájl nem m�ködik Windows 2000/XP alatt. Ennek oka, hogy a 386-os védett CPU üzemmódban az IN/OUT utasítások és a megszakítások virtuálisak (nem közvetlenek), azaz az operációs rendszer észleli �ket és eldöntheti, mi történjen. A Windows 2000/XP mint operációs rendszer fel is használja ezt a lehet�séget. A program gépi kódjánál jól látszik, hogy a 254 azt jelenti, hogy 1 bájtot ugorjon hátra (a cli-t jelent� 250-es bájtra). 253 esetén 2 bájtot lépne hátra, 252-nél hármat stb., míg 1, 2, 3 esetén az ugrás el�re történik. Az ugró utasítás ez esetben tehát egy 1 bájtos el�jeles szám, így jön ki az, hogy legfel-jebb 128 bájtot lehet hátra és 127-et el�re ugrani.

56. oldal: Bármely .EXE fájl els� két bájtja „MZ” (pontosabban az ennek megfelel� ASCII kódok). A fejléc tartalmaz egy ellen�rz� összeget is, ha a program indításakor valami nem stimmel, „Error in EXE file” (hiba az EXE fájlban) üzenetet kapjuk. Az .EXE fájl a fejléc miatt nem lehet egy bizonyos méretnél kisebb, míg létezhet akár 1 bájtos .COM fájl is.

Page 29: Assembly programozás

66

(Más.) A Hercules kártya azért volt „mellékvágány”, mert a képerny�memória nem B8000h-n kezd�dött, mint a többi kártyának, hanem B0000h-nál. Így pl. egy EGA grafikus képerny�re írt program csak egy emulátorprog-ram segítségével futott rajta. Volt viszont egy olyan el�nye, hogy egy számítógépen két monitorral tudtunk egyid�ben dolgozni, az egyik Hercules, a másik CGA/EGA/VGA! Ez az 1980-as években nagy szó volt, ma-napság már a Windows alapból ismeri a „multimonitor” funkciót. (Más.) Az SVGA/XGA gyártóknál típustól függ�en másképp m�ködtek a megszakítás-hívások és az üzemmó-dok, nagy volt a káosz, ezért kell külön drivert telepíteni. Ezt egységesítette a VESA szabvány. A saját driver a különleges funkciók elérésében segít, de Windows alatt megpróbálhatjuk a „szabvány SVGA” beállítást is (lásd az alábbi képen; a kép Windows ME alatt készült).

(Más.) A VGA-MCGA üzemmód színpaletta sorszámot tárol, nem úgy, mint pl. a 24 bites True Color üzem-módban (lásd az alábbi képen, amely Windows ME alatt készült), ahol képpontonként 1-1-1 bájt tárolja az adott képpont RGB értékeit.

Egyébként a monitorok RGB színképzése additív: a fehér képpont mindhárom színösszetev� magas értékekor keletkezik. A színes nyomtatók YMCK (Yellow, Magenta, Cyan és BlacK azaz fekete is, mert a feketét szebb fekete festékkel el�állítani, mint kikeverni) színképzése szubsztraktív: fekete festékpont jön ki. A modernebb színes nyomtatónál nemcsak ez a 4 festékszín van, a szebb min�ség elérése miatt még több festékb�l keverik ki a képet.

57. oldal: Elírás: nem vízszintes egyenest rajzolunk, hanem szakaszt. (Más.) Nemcsak „vertical blank” van, van „horizontal blank” is, de ennek ideje sokkal rövidebb, még keveseb-bet lehet ezalatt csinálni. A vertical blank használatakor a kép vibrálása csökken.

60. oldal: Az INC AX és INC BX utasítások gépi kódja jól van leírva, de csak 7 bit szerepel. A 8. bit a számok elején található nulla.

61. oldal: A szektoronkénti formattálási lehet�ség - pl. a floppy egy részét formattáljuk csak le - kit�n� lehet�ség volt régebben a másolásvédelemre. (Más.) A „futás közbeni kódátírás” olyan, hogy a futó program módosítja azt a memóriaterületet, amelyen ön-maga van. Nem az adatterületet, hanem a gépi kódú programterületet! Így, amikor a módosított helyre ér, az ott található átírt számok már más gépi kódú utasítást fognak jelenteni. Kit�n� lehet�ség a programvisszafej-tés nehezítésére! A futás közbeni kódátírás magas szint� programozási nyelvekben elképzelhetetlen.

64. oldal: További Internet cím: http://rs1.szif.hu/~tomcat/asm (Assembly kurzus)

Page 30: Assembly programozás

67

A 0-65535-ig elszámoló program forráskódja ; CMP_ASM.ASM (A példaprogramok között szerepel! Lásd még a 40. oldalon!) ; ; A Turbo Pascal, Borland C++ és az Assembly összehasonlítása. Ugyanaz a feladat melyik

nyelven a leggyorsabb (Assemblyben) és melyik nyelven írva lesz a legrövidebb (Assemb-lyben). Letöröljük a képerny�t, hangjelzés, elszámolunk 0-tól 65535-ig (vajon miért pont eddig?), majd még egy hangjelzés és kilépünk DOS-ba. A két sípolás között eltelt id� utal a program gyorsaságára. A többi fájl: CMP_PAS.PAS, CMP_C.C, CMP_PAS.EXE és CMP_C.EXE. Fontos! Komoly következtetéseket ebb�l nem vonhatunk le, mert most csak a különféle programrendszerek FOR ciklusának gyorsaságát teszteltük!

.MODEL TINY .CODE org 100h start: mov ax,0b800h ; képerny�memória kezd�címe ES-be mov es,ax mov ax,3 ; 80*25-ös szöveges mód+képerny�törlés int 10h mov ah,2 ; hangjelzés (a 7-es kód kiküldése) mov dl,7 int 21h xor cx,cx ; küls� ciklus 65536-szor vissza: ; (mert ennyiszer kell kiírni a számot) push cx ; --- "szám" kiírása közvetlenül a képerny�mem-ba --- lea si,szam ; az els� számjegyre állunk xor di,di ; kiírás pozícionálása a bal fels� sarokba mov cx,5 ; 5 számjegy van ide: mov al,[si] add al,'0' ; számjegyb�l karakter mov es:[di],al ; kiíratás a képerny�memóriába írással inc si ; következ� számjegy add di,2 ; következ� képerny� pozíció loop ide

; --- "szam" növelése eggyel --- lea si,szam+4 ; az utolsó számjegyre pozícionálunk call novel ; szubrutinhívás pop cx loop vissza ; küls� ciklus vége mov ah,2 ; még egy hangjelzés mov dl,7 int 21h int 20h ; kilépés DOS-ba novel proc ; --- szubrutin --- ; M�ködése: az aktuális pozíció számjegyét eggyel

; növeli. Túlcsordulás esetén (9-->10) helyébe 0-t ; ír, az el�z� helyiértékre lép és REKURZIV újrahív- ; ja magát (!). Ha nincs túlcsordulás, visszatér. inc byte ptr [si] cmp byte ptr [si],10 je tovabb ; "jump if equal" - ugrás, ha egyenl� ret ; kilépés1 tovabb: mov byte ptr [si],0 dec si call novel ret ; kilépés2 novel endp ; szubrutin vége ; --- a kiíratandó szám (5 számjegy) --- szam db 0,0,0,0,0 ; ZONAZOTT BCD - 1 számjegy 8 biten tárolódik! ; értékét fokozatosan növeljük 6,5,5,3,5 -re END start

Page 31: Assembly programozás

68

Az IBM PC XT/AT Input-Output portjai A 0000H-00FFH portokat az alaprendszer használja, a 0100H-03FFH portokat b�vít� kár-tyák használják, a 0400H-FFFFH portok a rendszerbusszal nem érhet�k el. AT PC/XT LEÍRÁS 000-01F 000-00F DMA vezérl� #1, 8237A-5. 020-03F 020-021 Megszakítás vezérl�, 8259A. 040-05F 040-043 Timer 8253-5 (AT: 8254.2).

060-063 PPI (Programable Peripheral Interface) billenty�zet, konfigurációs kapcsolók, timer 060-06F Billenty�zet vezérl� 8042 070-07F Valós idej� óra, CMOS memória, NMI 080 Diagnosztikai port 080-09F 080-083 DMA lapregiszter 74LS612 0A0 NMI tiltás 0A0-0BF Megszakítás vezérl� #2, 8259A 0C0-0DF DMA vezérl� #2, 8237A-5 0F0-0FF Matematikai társprocesszor 170-177 Merevlemez (másodlagos)

1F0-1F7 Merevlemez 200-207 200-20F Játék I/O (joystick A/D port) 210-217 B�vít� egység 278-27F 278-27F Párhuzamos printer port #2 (#3 MDA-val) 2C0-2DF 2C0-2DF EGA #2 2F8-2FF 2F8-2FF Asszinkron adatpter port #2 300-31F Prototípus kártya

320-32F Merevlemez 370-377 FDC - Floppy diszk vezérl� (másodlagos) 378-37F 378-37F Párhuzamos printer port #1 (#2 MDA-val) 380-38F 380-38F Szinkron vezérl� (SDLC) 3A0-3AF 3A0-3A9 Biszinkron port #1 (BSC) 3B0-3BF 3B0-3BF Monokróm képerny� adapter/printer #1 3B0-3DF 3B0-3DF VGA 3C0-3CF 3C0-3CF EGA #1 3D0-3DF 3D0-3DF CGA és EGA 3F0-3F7 3F0-3F7 FDC - Floppy diszk vezérl� 3F8-3FF 3F8-3FF Aszinkron Adapter Port #1

A FLAGS (állapotregiszter) felépítése

(CF=carry flag, ZF=zero flag stb.)

Page 32: Assembly programozás

69

Memóriacímzés valós és védett (80286+) módban

valós mód védett mód Lapozás (80386+)

A Norton Guide program az INT 27-et ismerteti

Page 33: Assembly programozás

70

Számítógép konkrét hardver adatainak megtekintése A „Rendszerinformáció” program, amelyet a Start-Futtatás-msinfo32 (Enter) módon indít-hatunk el, elemzi számítógépünk hardver-szoftver felépítését. Az alábbiakban néhány képerny�másolatot láthatunk egy viszonylag modern, Pentium IV Celeron 2.4 GHz, 512 MB DDR RAM 333 MHz-es számítógépen lefuttatott Rendszerin-formáció programból. Hasonlítsuk össze az eredményeket tanult elvi ismereteinkkel! Pró-báljuk ki a programot saját számítógépünkön is! Az Ütközés/megosztás kiírja azokat a port-, IRQ-, illetve memóriacímeket, amelyeknél ugyanazt a címet több eszköz használ. Ha a közös használat problémamentes, megosz-tásról beszélünk, ellenkez� esetben ütközésr�l. A „0x” azt jelenti, hogy a szám hexadeci-mális alakú, maga a szám a 0x-et követ� karaktersorozat.

Az I/O kilistázza az Input-Output portokat és megnevezi az ahhoz tartozó eszközt (lásd a 68. oldalon is):

Page 34: Assembly programozás

71

A Megszakításkérelmek (IRQ) kilistázza a hardver megszakításokat és az azt használó eszközöket. Vessük össze az 51. oldallal (IRQ 0, 1, 6)!

A Memória kiírja a ROM-RAM memória felosztását. Vessük össze a 60. és 83. oldallal (pl. rendszerlap: 0-9FFFFh)!

A Billenty�zet adatainál ismét láthatjuk a hozzá tartozó portot és IRQ címet:

Page 35: Assembly programozás

72

5. A gyakorlatokon kit�zött feladatok Az alábbi, egyre nehezed� feladatokat a gyakorlaton készítjük el és beszéljük meg. Az egyes Konzultációs Központok kismértékben eltérhetnek ett�l és más feladatokat is kit�z-hetnek. Ezért különösen akkor javasoljuk e példák átgondolását, ha nem tud részt venni a gyakorlatokon. A gyakorláshoz használja fel az Útmutató 73-74. oldalán található össze-foglalót!

Továbbá ebben az Útmutatóban, a 21. oldaltól kezd�d�en egy hosszabb, otthon önállóan elvégezhet� gyakorló feladatsor is található, melyet f�leg akkor ajánlunk, ha még egyálta-lán nem foglalkozott az Assembly nyelvvel. 1. Készítsünk Assembly programot, amely kiír egy karaktert a képerny�re. A karakter az AH regiszterben

található. A programot .COM-ra fordítsuk le! 2. Készítsünk Assembly programot, amely vár egy karakter leütésére és az ABC-ben mellette állót írja ki a

képerny�re (pl. „A” leütésekor „B”-t írjon ki). A programot .COM-ra fordítsuk le! 3. Készítsünk programot, amely kiírja a „Helló világ!” szöveget a képerny�re! A programot .COM-ra fordít-

suk le! Ha elkészültünk, b�vítsük a programot: minden lépést dolgozzunk ki, próbáljuk ki és ha m�ködik, tegyük hozzá az alatta találhatót!

• Tegyünk az elejére egy képerny�törlést! • A szöveg kiírása ötször történjen meg, egymás alá! • Mindegyik kiírás után álljon meg a program és várjon egy billenty� leütésére. • Ha a felhasználó Esc-et üt, a program azonnal érjen véget! • Ne ötször történjen a kiírás, hanem az elején a program kérjen be egy 0-9 közé es� számot és

annyiszor! • A számbeírás legyen ellen�rzött: ha más billenty�t ütök be, a program ne vegye figyelembe! • Alakítsuk át a programot .EXE típusúra!

4. Készítsünk programot, amely az AH regiszter tartalmát binárisan megjeleníti a képerny�n. Bonyolítás: az AX-et jelenítse meg (8 bitenként tagoltan, pl. „00000000 00000000”)!

5. Készítsünk programot, amely az AH regiszter tartalmát decimálisan megjeleníti a képerny�n. Bonyolítás: az AX-et jelenítse meg!

6. Készítsünk programot, amely az AH regiszter tartalmát hexadecimálisan megjeleníti a képerny�n. Bo-nyolítás: az AX-et jelenítse meg!

7. Készítsünk programot, amely udvariasan (bekér� üzenetet segítségével) beolvas a billenty�zetr�l egy nyolcjegy� bináris számot, ezt helyezze el a DL regiszterbe, majd írja ki a szám ASCII karakterét (pl. 00100000b=32d�szóközt írjon ki). A számbevitelt nem kell ellen�rizni. Bonyolítás: a számbeolvasásnál más billenty� leütésére ne reagáljon a program, Esc ütésére viszont azonnal érjen véget!

8. Készítsünk programot, amely udvariasan beolvas a billenty�zetr�l egy kétjegy� számot (00-99) és kiírja a képerny�re ennek az ASCII karakterét. Például ha 32-t adunk meg, egy szóközt írjon ki.

9. Készítsünk programot, amely letörli a képerny�t és a bal fels� sarokban kiírja az egérgombok lenyomá-sának pillanatnyi állapotát („bal", „jobb", „mindkett�", „egyik sem"). Kilépés Esc-re. Ezt a programot Win-dows alatt készítsük el (Start-Programok-Kellékek-Parancssor), az egér-driver miatt!

10. Készítsünk programot, amely letörli a képerny�t és egymás után felvillantja a NumLock, CapsLock, ScrollLock LED-eket (kb. fél másodpercig világítson egy-egy LED és ugyanennyi ideig egyik sem).

11. Készítsünk programot, amely letörli a képerny�t és a jobb Shift háromszori megnyomása (majd felenge-dése) után ér véget. Minderr�l tájékoztassa a felhasználót!

12. Készítsünk programot, amely átvált VGA-MCGA grafikus üzemmódba, kirajzol a kék háttérre egy piros X-et, vár egy billenty� leütésére, az X ezután váltson sárgára és egy újabb billenty� leütésére a program érjen véget.

A továbbiakban a minta-vizsgafeladatok közül beszélünk meg néhányat.

Jó tanulást és sikeres vizsgát kívánunk!

Page 36: Assembly programozás

73

6. Assembly - összefoglaló Ez a két oldal röviden összefoglalja a vizsgán leggyakrabban el�forduló ismereteket. 1. Egyszer� .COM forrásprg. felépítése: .model tiny .data

;<adatok> .code

org 100h start: ;<f�program> int 20h ; kilépés end start

2. .COM program fordítási lépései Turbo Assembler használatával:

1. Forrásprogram megírása szövegszerkeszt�vel 2. C:\> tasm fájlnév 3. C:\> tlink/t fájlnév 4. C:\> fájlnév (a program kipróbálása) 5. � 1. (hibakeresés)

A 2-3-4. pontnál a fájl kiterjesztését nem kell megadni, ha az 1. pontban .ASM kiterjesztést használunk.

3. Néhány vezérl�billenty� ASCII és SCAN kódja:

ASCII kódok: Enter=13, Backspace=8, Space=32, Esc=27, hangjelzés (sípszó) =7. SCAN kódok: Esc=01h, kurzor fel=48h, balra=4Bh, jobbra=4Dh, le=50h A bet�k ASCII kódjait nem kell fejb�l tudni, használható mov dl,'X' ; cmp al,'y' stb. is.

4. A leggyakrabban használt megszakítások:

Fontos! A hívások egy része (pl. a karakter kiírása) más regisztereket is felhasznál, érté-küket átírja! Emiatt elképzelhet�, hogy programunk nem fog jól m�ködni. Ha erre gya-nakszunk, felhasznált regisztereinket a hívás el�tt mentsük el, pl. a verembe!

• Karakter kiírása: AH=2, DL=karakter ASCII kódja, INT 21h

pl. mov ah,2 mov dl,'X' int 21h

• Szöveg kiírása: AH=9, DS:DX=szöveg els� karakterének helye, INT 21h A kiírandó szöveg $ jelre végz�djön (a dollárjel nem kerül kiírásra)!

pl. mov ah,9 mov dx,offset szoveg ; vagy: lea dx,szoveg int 21h továbbá az adatok részben: szoveg db 'Assembly',10,13,'$'

(.COM fájl esetén, mivel egy szegmens van, DS magától beáll a helyes értékre. .EXE ese-tén a mov ax,_data ; mov ds,ax is szükségesek. Új sorhoz a 10 és 13 kódokat kell kiküldeni, pl: .data és utána ujsor db 10,13,’$’.)

• Billenty� bekérése és kiírása: mov ah,1 ; int 21h A beolvasott karakter ASCII kódja AL-be kerül. A megszakítás addig vár, amíg nem nyo-munk le egy billenty�t. A kiírás a standard outputra (alapeset a képerny�) történik. Ez a megszakítás a váltóbillenty�k (Shift, Ctrl, Alt) önálló lenyomását NEM érzékeli!

• Billenty� „csendes" bekérése: mov ah,8 ; int 21h Hasonló az el�z�höz, csak nem ír ki a képerny�re (pontosabban a standard outputra). Vagy: mov ax,0 ; int 16h. Itt az ASCII kód AL-be, a scan kód AH-ba kerül.

• Billenty�zet állapota: mov ax,100h ; int 16h Ha van lenyomott billenty�, a zérus jelz�bit értéke 0, egyébként 1 lesz. A megszakítás nem vár semmire, rögtön visszatér.

Page 37: Assembly programozás

74

• Kilépés DOS-ba: .COM fájlszerkezet esetén: int 20h .EXE és .COM : mov ah,4ch ; mov al,kilépési_kód (DOS errorlevel) ; int 21h • Megszakítási cím lekérdezése: AL=megszakítás sorszáma, AH=35h, INT 21h

A megadott megszakítás aktuális címe az ES:BX regiszterekbe kerül (szegmens-offset). • Megszakítás átírása: AL=megsz. sorszáma, DS:DX=új cím, AH=25h, INT 21h • Program rezidenssé tétele: DX=els� felesleges bájt offset címe, INT 27h

5. Képerny�kezelés:

• Szöveges üzemmód: A képerny�memória kezdete B800:0000h. A tárolás soronként történik, „balról jobbra". Egy pozíciót 2 bájt határoz meg, az els� a karakter ASCII kódja, a másik az attribútuma. A kurzor pozicionálása: DH=sor (0..24), DL=oszlop (0..79), BX=0, AH=2, INT 10h

• VGA-MCGA grafikus üzemmód: A képerny�memória kezd�címe: A000:0000h. Egy képpontot 1 bájt határoz meg. Váltás VGA-MCGA üzemmódba: mov ax,13h ; int 10h (Vissza)váltás 80*25-ös szöveges módba és képerny�törlés: mov ax,3 ; int 10h Egy szín beállítása (újradefiniálás): mov dx,3c8h mov al,átállítandó_szín ;(0=háttérszín, 1..255=el�térszín) out dx,al ; kommunikálás a videokártyával inc dx mov al,piros_összetev� out dx,al mov al,zöld_összetev� out dx,al mov al,kék_összetev� out dx,al ahol a színösszetev�k értéke 0..63 lehet (6 bites értékek), pl. 0-0-63 = tiszta (nem kevert), leger�sebb kék, 0-0-0 = fekete, 63-63-63 = fehér stb. A képerny� tetsz�leges pontjának kigyújtása: mov ax,0a000h ; A videomem. szegmens kezd�címe ES-be mov es,ax mov al,szín_sorszáma ; 0..255 (0=háttér, 1..255=el�tér)

mov di,kiíratás_helye ; DI=0 ���� bal fels� sarok, 319 ���� el- ; s� sor legutolsó képpontja stb.

mov es:[di],al ; képpont kigyújtása

6. Egyebek (hármas-négyes-ötös szint� példákhoz):

• Parancssori paraméterátvétel: A DS:80h címén kezd�dik, 80h�hossz bájtban, 81h�" " vagy "/", 82h-tól a paraméterek.

• Egérkezelés: mov ax,3 és int 33h után: BX=0�nincs lenyomva egérgomb, BX=1�bal gomb lenyomva, BX=2�jobb gomb lenyomva, BX=3�mindkét gomb lenyomva, CX�x koordináta, DX�y koordináta (a bal fels� sarokban CX=DX=0). Szöveges üzemmódnál CX és DX nyolcasával változik. A megszakítás nem vár semmire, rögtön visszatér. M�ködéséhez driver program jelen-léte szükséges (pl. Windows „MS-DOS parancssor" alatt van egér meghajtó).

• Váltóbillenty�k: mov ah,2 és int 16h után AL 0. bitje jelzi a jobb Shift, 1. bitje a bal Shift állapotát (0�felengedve, 1�lenyomva). A megszakítás nem vár semmire, rögtön visszatér.

• A billenty�zet LED-jeinek vezérlése (a Lock billenty�k állapotát NEM befolyásolja): mov al,0edh ; out 60h,al ; <id�húzás loop és nop> ; mov al,K ; out 60h,al ; <id�húzás loop és nop, 65536-szor> ahol a K alsó 3 bitje vezényli a LED-eket (1-világít, 0-elalszik), Caps/Num/Scroll sorrend.

Page 38: Assembly programozás

75

7. Assembly programozás a mai modern operációs rendszerek alatt

Az utóbbi években jelentek meg és egyre nagyobb népszer�ségnek örvendenek az ope-rációs rendszerek képességeit kihasználó, grafikus felületét megszólító „felhasználóbarát” Assemblerek. Ezen programok széles tárháza és dokumentációja megtalálható az Interne-ten, az alábbi címeken: Assemblerek és dokumentációik Windows operációs rendszerekhez (Windows 95-t�l): • Microsoft Macro Assembler 32 (MASM): http://thestarman.narod.ru/asm/win32 Micro-

soft fejlesztés� komoly program rengeteg kiegészít� lehet�séggel, példákkal. • Radasm : http://radasm.visualassembler.com • WDOSX: http://michael.tippach.bei.t-online.de/wdosx Letöltés és kicsomagolás után a

„DOC" könyvtár tartalmazza a readme-t, melyben a 2. fejezetben vannak az Assembly-re vonatkozó témák, példák és forráskódok.

• WinASM Studio32 v3.0.0.0: http://winasm.certifika.com • FlatAssembler v1.5 for Windows: http://flatassembler.net/fasm-1.50.tar.gz • NetWide Assembler: http://sourceforge.net/projects/nasm Assemblerek és dokumentációik Linux operációs rendszerekhez: • HLA v1.60 (High Level Assembler) : http://webster.cs.ucr.edu/Page_Linux/0_Linux.html • FlatAssembler for Linux: http://flatassembler.net/fasm-1.50.tar.gz Egyéb hasznos linkek (tippek, trükkök:, tanácsok): • http://masmforum.com/viewforum.php?f=16&sid=4e18a1041b1b97606acd837af690e573 • http://board.win32asmcommunity.net • http://ebm.lap.hu • http://bobrich.lexitech.com • http://webster.cs.ucr.edu • http://programozas.lap.hu Végül bemutatjuk a Microsoft Macro Assembler 32 (MASM) program legels� mintapéldá-ját. A program az Example1\3dframes könyvtárban található és egy Windows ablakot nyit meg, néhány menüponttal és gombbal. Látható, hogy egy egyszer� feladatnál is több száz soros a forráskód. A forráskód (3dframes.asm): ; ######################################################################### ; ; The framing affects are drawn on the client area by a single procedure, ; "Frame3D". In the WmdProc message handling Proc, the WM_PAINT message ; calls another Proc called "Paint_Proc" which contains the procedure calls ; to "Frame3D". ; ; ######################################################################### .386 .model flat, stdcall option casemap :none ; case sensitive ; #########################################################################

Page 39: Assembly programozás

76

include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib ; ######################################################################### ;============= ; Local macros ;============= szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM m2m MACRO M1, M2 push M2 pop M1 ENDM return MACRO arg mov eax, arg ret ENDM ;================= ; Local prototypes ;================= WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD TopXY PROTO :DWORD,:DWORD Paint_Proc PROTO :DWORD, hDC:DWORD Frame3D PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD PushButton PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD .data szDisplayName db "3D Frames",0 CommandLine dd 0 hWnd dd 0 hInstance dd 0 .code start: invoke GetModuleHandle, NULL mov hInstance, eax invoke GetCommandLine mov CommandLine, eax invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT invoke ExitProcess,eax ; ######################################################################### WinMain proc hInst :DWORD, hPrevInst :DWORD, CmdLine :DWORD, CmdShow :DWORD ;==================== ; Put LOCALs on stack ;==================== LOCAL wc :WNDCLASSEX LOCAL msg :MSG LOCAL Wwd :DWORD LOCAL Wht :DWORD LOCAL Wtx :DWORD LOCAL Wty :DWORD ;================================================== ; Fill WNDCLASSEX structure with required variables ;================================================== mov wc.cbSize, sizeof WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW \ or CS_BYTEALIGNWINDOW mov wc.lpfnWndProc, offset WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL m2m wc.hInstance, hInst ;<< NOTE: macro not mnemonic mov wc.hbrBackground, COLOR_BTNFACE+1 mov wc.lpszMenuName, NULL mov wc.lpszClassName, offset szClassName invoke LoadIcon,hInst,500 ; icon ID mov wc.hIcon, eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor, eax mov wc.hIconSm, 0 invoke RegisterClassEx, ADDR wc ;================================ ; Centre window at following size ;================================ mov Wwd, 500 mov Wht, 350 invoke GetSystemMetrics,SM_CXSCREEN invoke TopXY,Wwd,eax mov Wtx, eax invoke GetSystemMetrics,SM_CYSCREEN invoke TopXY,Wht,eax mov Wty, eax szText szClassName,"Template_Class" invoke CreateWindowEx,WS_EX_LEFT, ADDR szClassName, ADDR szDisplayName,

Page 40: Assembly programozás

77

WS_OVERLAPPEDWINDOW, Wtx,Wty,Wwd,Wht, NULL,NULL, hInst,NULL mov hWnd,eax invoke LoadMenu,hInst,600 ; menu ID invoke SetMenu,hWnd,eax invoke ShowWindow,hWnd,SW_SHOWNORMAL invoke UpdateWindow,hWnd ;=================================== ; Loop until PostQuitMessage is sent ;=================================== StartLoop: invoke GetMessage,ADDR msg,NULL,0,0 cmp eax, 0 je ExitLoop invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg jmp StartLoop ExitLoop: return msg.wParam WinMain endp ; ######################################################################### WndProc proc hWin :DWORD, uMsg :DWORD, wParam :DWORD, lParam :DWORD LOCAL hDC :DWORD LOCAL Ps :PAINTSTRUCT .if uMsg == WM_COMMAND ;======== menu commands ======== .if wParam == 1000 invoke SendMessage,hWin,WM_SYSCOMMAND,SC_CLOSE,NULL .elseif wParam == 1900 szText TheMsg,"Assembler, Pure & Simple" invoke MessageBox,hWin,ADDR TheMsg,ADDR szDisplayName,MB_OK .endif ;====== end menu commands ====== .elseif uMsg == WM_PAINT invoke BeginPaint,hWin,ADDR Ps mov hDC, eax invoke Paint_Proc,hWin,hDC invoke EndPaint,hWin,ADDR Ps return 0 .elseif uMsg == WM_CREATE jmp @F Butn1 db "&Save",0 Butn2 db "&Cancel",0 Butn3 db "&Help",0 @@: invoke PushButton,ADDR Butn1,hWin,350,30,100,25,500 invoke PushButton,ADDR Butn2,hWin,350,60,100,25,500 invoke PushButton,ADDR Butn3,hWin,350,90,100,25,500 .elseif uMsg == WM_CLOSE szText TheText,"Please Confirm Exit" invoke MessageBox,hWin,ADDR TheText,ADDR szDisplayName,MB_YESNO .if eax == IDNO return 0 .endif .elseif uMsg == WM_DESTROY invoke PostQuitMessage,NULL return 0 .endif invoke DefWindowProc,hWin,uMsg,wParam,lParam ret WndProc endp ; ######################################################################## TopXY proc wDim:DWORD, sDim:DWORD shr sDim, 1 ; divide screen dimension by 2 shr wDim, 1 ; divide window dimension by 2 mov eax, wDim ; copy window dimension into eax sub sDim, eax ; sub half win dimension from half screen dimension return sDim TopXY endp ; ######################################################################### Paint_Proc proc hWin:DWORD, hDC:DWORD LOCAL btn_hi :DWORD LOCAL btn_lo :DWORD LOCAL Rct :RECT invoke GetSysColor,COLOR_BTNHIGHLIGHT mov btn_hi, eax invoke GetSysColor,COLOR_BTNSHADOW mov btn_lo, eax ; -------------------------------------------------------- ; The following 2 calls draw the border around the buttons ; -------------------------------------------------------- invoke Frame3D,hDC,btn_lo,btn_hi,340,20,460,125,2 invoke Frame3D,hDC,btn_hi,btn_lo,337,17,463,128,2 ; ----------------------------------------------------- ; The following 2 calls draw the left window frame area ; ----------------------------------------------------- invoke Frame3D,hDC,btn_lo,btn_hi,17,17,328,290,2 invoke Frame3D,hDC,btn_hi,btn_lo,20,20,325,287,1 ; ----------------------------------------------------------

Page 41: Assembly programozás

78

; The following code draws the border around the client area ; ---------------------------------------------------------- invoke GetClientRect,hWin,ADDR Rct add Rct.left, 1 add Rct.top, 1 sub Rct.right, 1 sub Rct.bottom, 1 invoke Frame3D,hDC,btn_lo,btn_hi, Rct.left,Rct.top, Rct.right,Rct.bottom,2 add Rct.left, 4 add Rct.top, 4 sub Rct.right, 4 sub Rct.bottom, 4 invoke Frame3D,hDC,btn_hi,btn_lo, Rct.left, Rct.top,Rct.right,Rct.bottom,2 return 0 Paint_Proc endp ; ######################################################################## PushButton proc lpText:DWORD,hParent:DWORD, a:DWORD,b:DWORD,wd:DWORD,ht:DWORD,ID:DWORD szText btnClass,"BUTTON" invoke CreateWindowEx,0, ADDR btnClass,lpText, WS_CHILD or WS_VISIBLE, a,b,wd,ht,hParent,ID, hInstance,NULL ret PushButton endp ; ######################################################################## Frame3D proc hDC:DWORD,btn_hi:DWORD,btn_lo:DWORD, tx:DWORD, ty:DWORD, lx:DWORD, ly:DWORD,bdrWid:DWORD ; -------------------------------- ; prototype and example usage code ; -------------------------------- ; LOCAL btn_hi :DWORD ; LOCAL btn_lo :DWORD ; invoke GetSysColor,COLOR_BTNHIGHLIGHT ; mov btn_hi, eax ; invoke GetSysColor,COLOR_BTNSHADOW ; mov btn_lo, eax ; invoke Frame3D,hDC,btn_lo,btn_hi,50,50,150,100,2 ; invoke Frame3D,hDC,btn_hi,btn_lo,47,47,153,103,2 ; -------------------------------- LOCAL hPen :DWORD LOCAL hPen2 :DWORD LOCAL hpenOld :DWORD invoke CreatePen,0,1,btn_hi mov hPen, eax invoke SelectObject,hDC,hPen mov hpenOld, eax ; ------------------------------------ ; Save copy of parameters for 2nd loop ; ------------------------------------ push tx push ty push lx push ly push bdrWid ; ------------ lpOne: invoke MoveToEx,hDC,tx,ty,NULL invoke LineTo,hDC,lx,ty invoke MoveToEx,hDC,tx,ty,NULL invoke LineTo,hDC,tx,ly dec tx dec ty inc lx inc ly dec bdrWid cmp bdrWid, 0 je lp1Out jmp lpOne lp1Out: ; ------------ invoke CreatePen,0,1,btn_lo mov hPen2, eax invoke SelectObject,hDC,hPen2 mov hPen, eax invoke DeleteObject,hPen ; ------------

pop bdrWid pop ly pop lx pop ty pop tx lpTwo: invoke MoveToEx,hDC,tx,ly,NULL invoke LineTo,hDC,lx,ly invoke MoveToEx,hDC,lx,ty,NULL inc ly invoke LineTo,hDC,lx,ly dec ly dec tx dec ty inc lx inc ly dec bdrWid cmp bdrWid, 0 je lp2Out jmp lpTwo lp2Out: ; ------------ invoke SelectObject,hDC,hpenOld invoke DeleteObject,hPen2 ret Frame3D endp ; ############################################################ end start

A végeredmény (3dframes.exe) lefuttatva:

Page 42: Assembly programozás

79

8. Az Intel 8086/8088 és 80286 processzorok teljes utasításkészlete – valós (real) mód

Jelölések: src - forrás operandus (source) src8 - 8 bites forrás operandus src16 - 16 bites forrás operandus dest - cél operandus (destination) reg/mem - regiszter vagy memória operandus flag - állapotregiszter bitje port8 - 8 bites periféria portcím reg16 - 16 bites regiszter mem16 - 16 bites memória hivatkozás [ ] - a szögletes zárójelbe írt érték által mutatott ROM/RAM memóriarekesz tartalma / - a két utasítás megegyezik, a forrásprogramban bármelyik használható (pl. JE/JZ) /286/ - csak 80286-os, vagy jobb processzornál használható Aritmetikai és logikai utasítások ADD dest, src dest � (src + dest) ADC dest, src dest � (src + dest + CF) INC dest dest � (dest + 1) SUB dest, src dest � (dest - src) SBB dest, src dest � (dest - src - CF) DEC dest dest � (dest - 1) CMP dest, src dest és src összehasonlítása kivonással (dest-src), a flag-ek beállítása (dest és src értéke nem változik) NEG dest dest � (0 - dest) (2-es komplemens) MUL src az AL(AX) el�jel nélküli szorzása (reg/mem)-vel AX � (AL* src8) DX:AX � (AX * src16) IMUL src az AL(AX) el�jeles szorzása (reg/mem)-vel AX � (AL*src8)

DX:AX � (AX*src16) IMUL reg16, r/m, immed reg16 � (r/m8 * immed) /286/ reg16 � (r/m16 * immed) IMUL reg16, immed8 reg16 � (reg16 * immed8) /286/ DIV src el�jel nélküli oszás (reg/mem)-vel AL � (AX / src8) , AH � (AX MOD src8) AX � (DX:AX / src16) , DX � (DX:AX MOD src16) IDIV src az AX(DX:AX) el�jeles osztása (reg/mem)-vel AL � (AX / src8) , AH � (AX MOD src8) AX � (DX:AX / src16) , DX � (DX:AX MOD src16) AAA AX kiigazítása zónázott BCD összeadás után AAS AX kiigazítása zónázott BCD kivonás után AAM AH � AL/10 , AL � AL mod 10 AX kiigazítása zónázott BCD szorzás után AAD AL � AH * 10 + AL , AH �0 AX kiigazítása zónázott BCD osztás (DIV vagy IDIV) el�tt Tulajdonképpen AX-et zónázott BCD alakról átkonvertálja binárisba. DAA AL � AL tömörített BCD kiigazítása összeadás után DAS AL � AL tömörített BCD kiigazítása kivonás után CBW AX � AL el�jel kiterjesztéssel CWD DX:AX � AX el�jel kiterjesztéssel AND dest, src dest � (dest & src) logikai 'és' TEST dest, src flag-ek � (dest & src eredménye alapján) OR dest, src dest � (dest | src) logikai 'vagy' XOR dest, src dest � (dest ^ src) logikai 'kizáró vagy' NOT dest dest � 1-es komplemense (0 és 1-es bitek cseréje) Adatmozgató utasítások MOV dest, src dest � src XCHG dest, src dest csere src IN AX, port8(DX) byte: AL � [port] word: AL � [port], AH � [port+1] OUT port8(DX),AX byte: [port] � AL word: [port] � AL, [port+1] � AH XLAT AL � DS: [BX+AL]

Page 43: Assembly programozás

80

LEA reg16,addr reg16 � (addr effektív címe) LDS reg16,mem reg16 � [mem16] , DS � [mem16+2] LES reg16,mem reg16 � [mem16] , ES � [mem16+2] LAHF AH � flag-regiszter alsó byte-ja (SF, ZF, AF, PF, CF) SAHF flag-regiszter alsó byte-ja � AH PUSH src SP=SP-2 , SS:[SP] � src PUSH érték SP=SP-2 , SS:[SP] � 16 bites érték /286/ PUSHA SP=SP+10H , PUSH AX, BX, CX, DX, SI, DI, BP, SP /286/ PUSHF SP=SP-2 , SS: [SP] � flag-ek POP dest dest � SS: [SP] , SP=SP+2 POPA POP SP, BP, DI, SI, DX, CX, BX, AX, SP=SP+10H /286/ POPF flag-reg � SS: [SP] , SP=SP+2 Vezérlésátadó utasítások CALL címke eljárás hívás Ha FAR CALL (inter-szegmens) PUSH CS CS � cél_seg (Továbbá minden esetben:) PUSH IP IP � cél_offszet RET opcionális érték POP IP Ha FAR RETURN (inter-szegmens), akkor még: POP CS (Továbbá minden esetben:) SP � SP + opcionális érték (ha meg van adva) JMP címke feltétel nélküli ugrás short:IP � (IP+(el�jeles cél eltolás)) near: IP � (IP+(16 bites cél eltolás)) indirekt: IP � (regiszter vagy memória) far: SS � cél_seg , IP � cél_ offset JCXZ short_címke ugrás, ha CX=0 LOOP short_címke CX � (CX-1) és ugrás, ha CX <>0 LOOPE short_címke CX � (CX-1) és ugrás, ha CX <>0 és ZF=1 LOOPZ LOOPNE short_címke CX � (CX-1) és ugrás, ha CX <>0 és ZF=0 LOOPNZ Jfelt. short_címke ugrás ha a feltétel teljesül IP � (IP+8 bites eltolás) JE/JZ short_címke ugrás, ha = (ZF=1) JNE/JNZ short_címke ugrás, ha <> (ZF=0) JA/JNBE short_címke ugrás, ha > (CF=0 és ZF=0 el�jel nélkül) JAE/JNB short_címke ugrás, ha ≥ (CF=0 el�jel nélkül) JB/JNAE short_címke ugrás, ha < (CF=1 el�jel nélkül) JBE/JNA short_címke ugrás, ha ≤ (CF=1 vagy ZF=1 el�jel nélkül) JG/JNLE short_címke ugrás, ha > (SF=OF és ZF=0 el�jeles) JGE/JNL short_címke ugrás, ha ≥ (SF=OF el�jeles) JL/JNGE short_címke ugrás, ha < (SF<>OF el�jeles) JLE/JNG short_címke ugrás, ha ≤ (SF<>OF és ZF=1 el�jeles) JC short_címke ugrás, ha (CF=1) JNC short_címke ugrás, ha (CF=0) JO short_címke ugrás, ha túlcsorult (0F=1) JNO short_címke ugrás, ha nics túlcsordulás (OF=0) JP/JPE short_címke ugrás, ha paritás páros (PF=1) JNP/JPO short_címke ugrás, ha paritás páratlan (PF=0) JS short_címke ugrás, ha negatív (SF=1) JNS short_címke ugrás, ha nem negatív (SF=0) BOUND reg16,mem ha (reg16 < DS: [mem]) vagy (reg16 > DS: mem+2]) akkor INT 5 /286/ ENTER méret:szint paraméterátadáshoz veremterület kijelölése /286/ LEAVE az ENTER által lefoglalt veremterület felszabadítása /286/ INT szám szoftver megszakítás hívása PUSHF, IF� 0, TF�0, PUSH CS , PUSH IP , IP � 0000: [szám *4]; CS � 0000:[(szám * 4)+2] INTO ha OF=1, akkor INT 4 INT INT 3 IRET visszatérés megszakításból POP IP, POP CS, POPF

Page 44: Assembly programozás

81

Bitforgató és biteltoló utasítások Az utasítás általános felépítése: <parancs> dest,1/CL Példa: SHL AL,1; SHR BX,CL stb.

SHL/SAL SHR (logikai eltolás balra/jobbra)

ROL ROR (forgatás balra/jobbra)

RCL RCR SAR (forgatás balra/jobbra CF-fel) (aritmetikai eltolás jobbra) SHL/SHR/SAL/SAR dest,db /286/ ROL/ROR/RCL/RCR dest,db /286/ ahol db=0..31 Stringkezel� utasítások ± jelentése: +, ha DF=0 és -, ha DF=1 REP/REPE/REPZ (prefixum) ameddig CX <> 0 (MOVS, LODS, STOS) string utasítás CX �CX-1 ____________________

ameddig CX <> 0 (CMPS,SCAS) string utasítás CX � CX-1 ha ZF = 0 az ismétlés befejezése REPNE/REPNZ (prefixum) ameddig CX <> 0 (MOVS, LODS, STOS) string utasítás CX � CX -1 ____________________

ameddig CX <> 0 (CMPS, SCAS) string utasítás CX � CX-1 ha ZF = 1 az ismétlés befejezése MOVSB ES: [DI] � DS: [SI] (byte, bájt) SI � SI ± 1 DI � DI ± 1 MOVSW ES: [DI] � DS: [SI] (word, szó)

SI � SI ± 2 DI � DI ± 2 LODSB AL � DS: [SI] SI � SI ± 1 LODSW AX � DS: [SI] SI � SI ± 2 STOSB ES: [DI] � AL DI � DI ± 1 STOSW ES: [DI] � AX DI � DI ± 2 CMPSB flag-ek � CMP DS: [SI], ES: [DI] (byte) SI � SI ± 1 DI � DI ± 1 CMPSW flag-ek � CMP DS: [SI], ES: [DI] (szó) SI � SI ± 2 DI � DI ± 2

Page 45: Assembly programozás

82

CMPSW SI � SI ±n DI � DI ± n SCASB flag-ek � CMP ES: [DI],AL DI � DI ±1 SCASW flag-ek � CMP ES: [DI],AX DI � DI ± 2 INSB, INSW ES: [DI] � ( byte vagy szó a DX portról) /286/ DI � DI ± (1 illetve 2) OUTSB, OUTSW (DX portra) � DS: [SI] (byte vagy szó) /286/

SI � SI ± (1 illetve 2) 80x86 vezérl� utasítások CLC CF � 0 (clear carry flag) CMC CF � CF komplemense (ellentéte) (complement carry falg) STC CF � 1 (set carry flag) CLD DF � 0 (string utasításoknál SI/DI növelését okozza) (clear direction flag) STD DF � 1 (string utasításoknál SI/DI csökkentését okozza) (set direction flag) CLI IF � 0 (hardver megszakítások tiltása; az NMI-re nem vonatkozik) (clear interrupt flag) STI IF � 1 (hardver megszakítások engedélyezése) (set interrupt flag) HLT a processzor leállítása egy hardver megszakításig, NMI-ig, vagy reset jelig WAIT várakozás a TEST (BUSY) vonalak aktív állapotára. Küls� hardver – pl. coprocesszor – szinkronizálására használják ESC opkód, src utasítás átadása a coprocesszornak (8087, 80287) LOCK (prefixum) a buszok lezárása az utasítás végrehajtásának idejére. Az XCHG, MOV és MOVS utasítások el�tt használható. segreg: (prefixum) az alapértelmezett szegmenskijelölés átállítása, pl. MOV ES:[DI],AX

9. AZ IBM PC XT/AT MEGSZAKÍTÁSVEKTORAI Itt csak felsoroljuk a lehetséges 256 megszakítást. Az egyes hívások részletezése hosszú oldalakat tenne ki. A leírásban a „BIOS” azt jelenti, hogy a megszakítást kiszolgáló rutin a ROM-BIOS-ban található (hacsak nem lett átirányítva), a „DOS” pedig azt, hogy a DOS dolgozza fel (pontosabban egy memóriarezidens fájl a RAM-ban). Az „IRQ” jelentése: az adott hardver megszakítás hívja ezt a megszakítást.

INT 00H Osztás túlcsordulás (DIV, IDIV) INT 01H Lépésenkénti végrehajtás INT 02H NMI INT 03H Program töréspont INT 04H Túlcsordulás INT 05H Képerny�tartalom nyomtatása INT 06H Foglalt INT 07H Foglalt INT 08H IRQ0 - 8253 számláló INT 09H IRQ1 - Billenty�zet vezérl� INT 0AH (AT): IRQ2 - LAN Adapter 1 IRQ9 INT 0BH IRQ3 - COM2 8250 INT 0CH IRQ4 - COM1 8250 INT 0DH (AT): IRQ5 - LPT2 ACK INT 0EH IRQ6 - Floppy Disk Vezérl� INT 0FH (AT): IRQ7 - LPT1 ACK és slave 8259 INT 10H BIOS KEZEL�: Video INT 11H BIOS KEZEL�: Konfigurációs lista INT 12H BIOS KEZEL�: A használható memória méret INT 13H BIOS KEZEL�: Lemez I/O INT 14H BIOS KEZEL�: Serial port (COM) I/O INT 15H (AT): BIOS : AT b�vített funkciók INT 16H BIOS KEZEL�: Billenty�zet I/O INT 17H BIOS KEZEL�: Printer I/O INT 18H BIOS KEZEL�: ROM BASIC indítás INT 19H BIOS KEZEL�: Rendszerindítás INT 1AH BIOS KEZEL�: Dátum és id� I/O INT 1BH BIOS KEZEL�: Ctrl-Break kezelése INT 1CH BIOS KEZEL�: Felhasználói timer (09H) INT 1DH BIOS Mutató: 6845 Video paramétertáblák INT 1EH BIOS Mutató: Floppy disk paraméterek INT 1FH BIOS Mutató: Grafikus karakterkészlet 2 INT 20H DOS: a program kilépés kezel�je (.COM) INT 21H DOS: DOS hívások INT 22H DOS: Program-kilépés címe INT 23H DOS: Ctrl-Break kezel� címe INT 24H DOS: Kritikus hibakezel� címe INT 25H DOS: Abszolút lemezolvasás INT 26H DOS: Abszolút lemezírás INT 27H DOS: rezidens kilépés (.COM) INT 28H DOS: A DOS hívja, ha szabad INT 29H DOS: CON device output kezel�

INT 2AH DOS: 3.x: Hálózati kommunikáció INT 2BH DOS: Foglalt INT 2CH DOS: Foglalt INT 2DH DOS: Foglalt INT 2EH DOS: DOS parancssor végrehajtása INT 2FH DOS: Multiplex interrupt INT 30H DOS: Foglalt INT 31H DOS: Foglalt INT 32H DOS: Foglalt INT 33H MOUSE interrupt INT 34H – INT 3EH 8087/80287 EMULÁTOR által használt INT 3FH DOS: Foglalt INT 40H BIOS: lemezkezel� belépési pontja INT 41H BIOS Mutató: merevlemez 0 paramétertábla INT 42H EGA: Video vektor INT 43H EGA: Inicializáló paraméterek INT 44H EGA: Grafikus karakterek INT 45H Foglalt INT 46H (AT): Mutató - merevlemez 1 paramétertábla INT 47H Foglalt INT 48H Foglalt INT 49H Foglalt INT 4AH (AT): Felhasználói alarm rutin (70H) INT 4BH Foglalt INT 4CH – INT 5FH Foglalt INT 60H – INT 66H Overlay megszakítások INT 66H INT 67H Intel/Lotus/Microsoft~ EMS kezel� INT 68H – INT 6FH Nem használt INT 70H (AT): IRQ8 - Valós idej� óra INT 71H (AT): IRQ9 - LAN adapter 1 (to IRQ2) INT 72H (AT): IRQ10 - Foglalt INT 73H (AT): IRQ11 - Foglalt INT 74H (AT): IRQ12 - Foglalt INT 75H (AT): IRQ13 - 80287 hiba ( NMI) INT 76H (AT): IRQ14 - Merevlemez vezérl� INT 77H (AT): IRQ15 - Foglalt INT 78H – INT 7FH Nem használt INT 80H – INT 85H Foglalt a BASIC által INT 86H NetBIOS: Relokált INT 18h INT 87H – INT F0H Foglalt a BASIC által INTERPRETER módban INT F1H – INT FFH Nem használt