Assembly direktívák, masm, link, regiszterek és még sok más
Ebben az Assembly cikkben a direktívákról és a MASM illetve
a LINK használatáról olvashatsz. A cikk vége fele szót ejtek még a
regiszterekről és a feltétel bitekről. Lássuk hát:
A
MASM a Microsoft Macro Assembler rövidítése, aminek használatával szöveges
assembly forrásfájlokból készíthetünk bináris futtatható exe/com fájlokat. A
forráskód megírásához használhatunk egyszerű szövegszerkesztőt - akár még a
Windows notepad-ját is – vagy direkt a parancssoros fordítókhoz készült ún.
programozói szövegszerkesztőket (pl. az ingyenes ConTextet). Az elkészített
szövegfájlt paraméterként adhatjuk meg az assemblernek, ami ebből egy
úgynevezett bináris tárgykódot készít. Ez az “obj” kiterjesztésű fájl még nem
futtatható. Ahhoz hogy igazi futtatható fájlt kapjunk, a linkert kell
használnunk, szintén paraméterkent megadva a tárgykódot, illetve tárgykódokat.
Erre azért van szükség, amikor több, akár különböző nyelven írt objectet
szeretnénk összeszerkeszteni (csatolni, linkelni), akkor ezt is
megtehessük. Az assembler és a linker számtalan paraméterrel meghívható,
amelyek akár verzióként is változhatnak, ezekről a parancssorban megadható
paraméterekről a dokumentációban találhatunk leírást.
MASM programozásban használt direktívák, csak a felsorolás
szintjén.
DIREKTIVÁK
DE EZEK MIRE VALOK? Jo lenne elmagyarazni, akar csak egy
konkret peldaval is!!!
-
A programstruktúra definiálására:
SEGMENT, ENDS, END, GROUP, ASSUME, ORG, EVEN
-
Szimbólum definiálására:
DB, DW, DD, DQ, DT, LABEL, EQU, =
Ezeket a 2. generacios nyelvektol
valtozo azonositonak hivjak, az EQU pedig kulonvalasztando, mert az az
konstansok elnevezesere valo!!
-
Szubrutinok:
PROC, END
-
Külső szimbólumok definiálása:
EXTRN, PUBLIC
A PUBLIC es az EXTERN sem tartozik azonos fogalmi
kategoriaba, magyarazzuk meg szepen, mi mire valo!!
-
Makrók:
MACRO, ENDM, LOCAL, EXITM, PURGE
-
Kódismétlő makrók:
REPT, IRP, IRPC
-
Feltételes fordítás:
IF, IFE, IF1, IF2, IF(N)DEF, IF(N)B, IFIDN, IFDIF, ELSE,
ENDIF
-
Adatszerkezetek:
STRUC, ENDS, RECORD
Ezt korabbra, ne az elofordito
direktivak koze tegyuk!!
-
Fordításvezérlés:
INCLUDE, .RADIX, %OUT, NAME, TITLE, SUBTTL, PAGE
-
Listázás:
.XLIST, .LIST, .SFCOND, .LFCOND, .TFCOND, .SALL, .LALL,
.XALL, .XCREF, .CREF
A MASM HASZNÁLATA BŐVEBBEN:
A
MASM fordítóprogram assembly forrásprogramokat fordít le gépi kódú
utasításokra. Ha nem ismerjük a paramétereit, akkor csak a nevének leírásával
is hívhatjuk, ilyenkor interaktívan bekéri az alábbiakat:
-
Forrásfájl neve (.ASM)
-
Tárgyfájl neve (.OBJ)
-
Listafájl neve (.LST) { ide
kerül a fordítási lista }
-
Hivatkozásfájl neve (.CRF) { ide
kerül a hivatkozási lista }
Fájlnevek
helyett használható speciális eszközök:
- NUL fiktív, nem létező fájl // ne igy irjuk, mert letezo fajl, csak eppen egy szivacs befele-kifele: a kimeneten hasznalva mindent elnyel, bemenetkent pedig soha nem szolgaltat adatot. DOS fagyasztas: COPY NUL NUL oszt' helló :)
-
CON képernyő
-
PRN nyomtató
-
AUX soros vonal
-
Alkönyvtár
Megadható
egyetlen parancssorral is, ilyenkor a fájlneveket egymástól vesszővel
választjuk el. Ha az implicit értéket akarjuk használni, akkor a paraméterlista
megfelelő elemét üresen hagyjuk. A listát ';' zárjuk le
A LINK HASZNÁLATA
Az
assemblerrel előállított tárgymodulok még nem tölthetőek és nem futtathatók, előbb
azokat a szerkesztőprogrammal fel kell dolgozni. A szerkesztőprogram összefűzi
az assembler vagy egyéb fordítók tárgymoduljait, feloldja a külső
hivatkozásokat és módosítja a címkonstansok eltolás részeit.
// nalam a
helyesirasellenorzo alahuzta, h cimkonstans. Ilyen valoban nincs, nehogy ilyent
kiejts a szadon. Inkabb azt, hogy azonosito, vagy szimbolum. Mert a Konstansnak
NINCS CIME!! Ez nagyon durva igy. Rad felrne egy programfejlesztes szigorlat!
Interaktív
futtatásnál bekért fájlok:
-
Tárgymodul(ok) neve (.OBJ)
-
Végrehajtható fájl neve (tárgy.EXE)
-
Listafájl neve (NULL.MAP)
-
Könyvtárfájlok neve (NUL.LIB)
A
speciális eszközöket és a használatra vonatkozó egyéb megjegyzéseket ld. a MASM
leírásában.
A REGISZTEREK
A
8086-os és a 8080-as processzor regiszterei:
A
regiszterek a processzor belső tárolói. A műveletekhez regiszterekben kell
megadnunk az operandusokat, illetve egyes műveleteknél az egyik operandus lehet
memóriacím, vagy konstans is.
// A
muveletekhez TARTOZNAK operandusok, nem megadni kell oket. Ez Formatum!
Például
az adatok mozgatására szolgál a “mov” utasítás. Ennek iránya (intel
szintaktikájú asm-nél, mert AT&T-nél pont fordítva van): jobbról balra
történik ( <= ), azaz:
“mov
ax, bx” ; a bx értéket az ax regiszterbe helyezi.
Egysoros
megjegyzéseket pontosvessző karakter után írhatunk. Ezeket a sorokat az
assembler figyelmen kívül hagyja, így dokumentálhatjuk a forráskódunkat,
ezáltal áttekinthetőbb lesz, és másvalaki, vagy esetleg mi saját magunk, ha
évek múlva újból elővesszük, hamarabb meg fogjuk érteni.
A
8086/8080 processzor általános regiszterei a következők:
AX
│ AH AL │ akkumulátor
BX
│ BH BL │ bázisregiszter
CX
│ CH CL │ számlálóregiszter
DX
│ DH DL │ adatregiszter
A
regiszterek 16 bitesek és a fenti 4 felbontható 2 darab 8 bitesre. Ahol az
egyik a magasabb (high) 8 bit, a másik az alacsonyabb 8 bit (low).
A
regiszterek általánosak, mert a legtöbb műveletben szerepelhetnek, de amint
látjuk mindegyiknek van speciális feladata is. Az AX a 8 bites processzorok
akkumulátor megfelelője, de nincs olyan kitüntetett szerepe mint ott. Itt is
vannak azonban olyan műveletek - például szorzás/osztás - amiknél kötelező
operandus az AX.
// ez kenyes kerdes, ugyanis implicit operandus, magatol
ertetodik, ezert kell vele vigyazni
A
BX regiszter az egyedüli az általános regiszterek között amit címzésre
használhatunk. Az CX a ciklusszámláló, például a loop-os ciklusnál illetve a
“rep” prefix-szel ellátott műveleteknél. A DX regiszter egyes műveletekben az
AX kiterjesztése (például 32 bites eredménynél alsó 16 bit AX felső 16 bit DX),
illetve port írás/olvasásnál szokás még használni.
//
szokjuk meg, hogy kiemeljuk a kuklcsszavakat, pl. LOOP ciklusoknal, illetve a
REP prefix eseteben.
SI - forrás
(source) indexregiszter
DI - cél
(destination) indexregiszter
A
forrás és cél indexregisztereket az úgynevezett sztringműveleteknél
használhatjuk (nincs köze a magas szintű nyelvekben használatos sztringekhez,
ezek pl. movs, stos, lods, cmps) ilyenkor a forráscímet SI-ben kell megadnunk,
a célcímet (például adatok másolása memóriában egyik címről a másikra) pedig
DI-ben.
// de van koze a stringmuveletekhez. Mit jelent a string?
Karakterlanc, ezek pedig lancmuveletek. Ejnye!
SP -
verem (stack) mutató
A verem egy memória szegmens, aminek az aktuális offsetcíme az SP regiszterben van. A verem úgynevezett LIFO (last in, first out) szerveződésű, ami azt jelenti hogy az utoljára belerakott elemet vehetjük ki először, egy zsákhoz szokták hasonlítani amibe egymás tetejére halmozhatjuk az elemeket. A verem az alacsonyabb címek irányába nő, vagyis ha belerakunk egy elemet, akkor a veremmutató értéke csökken, ha kiveszünk, nő.
BP -
bázis mutató (pointer)
A
8080/8086-os processzorok vermét nem címezhetjük meg közvetlenül a veremmutató
használatával, többek között erre szolgál a BP regiszter. Általánosan
elmondható, hogy a magas szintű nyelveknél, függvényhíváskor a vermen keresztül
adódnak át a paraméterek, illetve a lokális változók is ide kerülnek. Ilyenkor
a BP regiszterbe szokás tölteni a SP mutató értékét és azon keresztül érhetjük
el a vermet.
IP -
utasítás (instruction) mutató (számláló)
Vagy
régi nevén PC (program counter), az utasításszámláló regiszter. Ez tartalmazza
az következő végrehajtandó utasítás offsetcímét.
// erdekessegkent megemlithetjuk, hogy ez PRIVATE gepi
nyelvi regiszter, de tartalmat kis trukkel el lehet erni, pl:
CALL $0 ; letoljuk IP-t a verembe
POP AX ; es mar itt is van
CS - kód
(code) szegmensregiszter
Ez
az a szegmens amiben fut a program.
DS - adat
(data) szegmensregiszter
Ez
a szegmens tartalmazza a program adatait.
SS - verem
(stack) szegmensregiszter
Ez
a szegmens a vermet.
ES -
extra szegmensregiszter
Ez
pedig általában szintén adatszegmensre mutat.
A FELTÉTELBITEK (FLAG REGISTER, nem "F")
Az
ún. flag regiszter, aminek nem egyben, hanem bitenként van jelentősége, az
aritmetikai műveletek során módosulnak a feltételbitek, amiket például
feltételes ugrásokhoz használhatunk.
XX |
XX |
XX |
XX |
OF |
DF |
IF |
TF |
SF |
ZF |
XX |
AF |
XX |
PF |
XX |
CF |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
XX:
Nem kihasznált
CF
átvitel (carry), a művelet során az eredmény ábrázolási tartományából (byte
vagy szó) kilépő bit
PF
paritás (parity) = 1, ha az eredmény alsó byte-jában az 1-es bitek száma páros
AF
közbenső ( 3. -> 4. bit ) átvitel ( auxiliary carry )
ZF
zérus ( zero ) = 1, ha az eredmény 0
SF
előjel ( sign ) = 1, ha az eredmény negatív
OF =
1, ha túlcsordulás (owerflow) lépett fel
DF =
1, ha a sztringműveletek csökkenő indexek irányába ( direction) végződnek
IF =
1, ha a megszakítások ( interrupt ) engedélyezve vannak
TF
lépésenkénti nyomkövetésnél használatos; ha TF = 1, minden utasítást követően
INT 1 megszakítás keletkezik
// kis szummazas
sem artana, meg elkoszones, h lesz-e folytatas vagy vmi ilyesmi :)…
A
szerző ismeretlen - A leírások java része őt illeti
Átdolgozta.:
Gebei János – harkon@coder.hu