Az assembly nyelv alapelemei és az utasításstruktúra. Az assembly nyelvi parancsok adatformátuma és szerkezete. A "Rendszerprogramozás" tudományágban

Bevezetés.

Azt a nyelvet, amelyen a forrásprogram meg van írva, hívjuk bejárat nyelv, és az a nyelv, amelyre a processzor végrehajtásához lefordítja szabadnapokon nyelv. A beviteli nyelv kimeneti nyelvvé alakításának folyamatát ún adás. Mivel a processzorok a programozáshoz nem használt bináris gépi nyelven is képesek programokat végrehajtani, ezért az összes forrásprogram fordítása szükséges. Ismert két út adások: összeállítás és tolmácsolás.

Nál nél összeállítás a forrásprogramot először teljesen lefordítják egy ekvivalens programra a kimeneti nyelven, ún tárgy programot, majd végrehajtjuk. Ezt a folyamatot speciális segítségével hajtják végre programok, hívott fordítóprogram. Egy olyan fordítót, amelynél a bemeneti nyelv a bináris kódok gépi (kimeneti) nyelvének szimbolikus formája, ún. szerelő.

Nál nél értelmezések A forrásprogram minden szövegsorát elemzi (értelmezi), és azonnal végrehajtja a benne megadott parancsot. Ennek a módszernek a végrehajtása rá van bízva tolmács program. Az értelmezés sokáig tart. A hatékonyság növelése érdekében az egyes sorok feldolgozása helyett a tolmács először az összeset konvertálja csapat karakterláncok (

). A generált szimbólumsorozat az eredeti programhoz rendelt funkciók végrehajtására szolgál.

Az alábbiakban tárgyalt összeállítási nyelv fordítással valósul meg.

A nyelv jellemzői.

Az összeszerelő főbb jellemzői:

● bináris kódok helyett a nyelv szimbolikus neveket használ - mnemonika. Például az összeadás parancshoz (

) mnemonikát használnak

Kivonások (

szorzás (

osztályok (

stb. A szimbolikus neveket a memóriacellák megcímzésére is használják. Az assembly nyelvű programozáshoz a bináris kódok és címek helyett csak szimbolikus neveket kell tudni, amelyeket az assembler bináris kódokká fordít le;

minden állítás megfelel egy gépparancs(kód), azaz van egy-egy megfelelés a gépi parancsok és az operátorok között egy assembly nyelvi programban;

● a nyelv hozzáférést biztosít minden tárgyraés csapatok. A magas szintű nyelvek nem rendelkeznek ezzel a képességgel. Például az assembly nyelv lehetővé teszi a jelzőregiszter biteinek ellenőrzését és a magas szintű nyelv (pl.

) nem rendelkezik ezzel a képességgel. Vegye figyelembe, hogy a rendszerprogramozási nyelvek (például C) gyakran köztes pozíciót foglalnak el. Hozzáférhetőség szempontjából közelebb állnak az assembly nyelvhez, de egy magas szintű nyelv szintaxisával rendelkeznek;

● assembly nyelv nem univerzális nyelv. A mikroprocesszorok minden egyes csoportjának saját összeszerelője van. A magas szintű nyelveknek nincs ilyen hátránya.

A magas szintű nyelvekkel ellentétben a programok assembly nyelven történő megírása és hibakeresése sok időt vesz igénybe. Ennek ellenére az assembly nyelvet megkapta széleskörű felhasználás a következő körülmények miatt:

● egy assembly nyelven írt program lényegesen kisebb méretű és sokkal gyorsabban fut, mint egy magas szintű nyelven írt program. Egyes alkalmazásoknál ezek a mutatók elsődleges szerepet játszanak, például számos rendszerprogram (beleértve a fordítókat), hitelkártya-programok, mobiltelefonok, eszközillesztőprogramok stb.;

● egyes eljárások megkövetelik teljes hozzáférés a hardverhez, ami általában lehetetlen magas szintű nyelven. Ez az eset magában foglalja a megszakításokat és megszakításkezelőket az operációs rendszerekben, valamint az eszközvezérlőket a beágyazott valós idejű rendszerekben.

A legtöbb programban a teljes kódnak csak egy kis százaléka felelős a program végrehajtási idejének nagy százalékáért. Jellemzően a program 1%-a felelős a végrehajtási idő 50%-áért, és a program 10%-a a végrehajtási idő 90%-áért. Ezért egy adott program valós körülmények közötti írásához mind az assembler, mind a magas szintű nyelvek egyikét használják.

Operátori formátum assembly nyelven.

Az assembly nyelvű program parancsok (utasítások, mondatok) listája, amelyek mindegyike külön sort foglal el, és négy mezőt tartalmaz: egy címkemezőt, egy műveleti mezőt, egy operandusmezőt és egy megjegyzésmezőt. Minden mezőnek külön oszlopa van.

Címke mező.

Az 1. oszlop a címkemezőhöz van hozzárendelve. A címke szimbolikus név vagy azonosító, címek memória. Ez szükséges ahhoz, hogy:

● feltételes vagy feltétel nélküli áttérés a parancsra;

● hozzáférhet az adatok tárolási helyéhez.

Az ilyen nyilatkozatokat címkével látják el. A név jelzésére az angol ábécé (nagy) betűit és számokat használjuk. A név elején betűnek, a végén kettőspont elválasztónak kell lennie. A kettőspont címke külön sorba, a műveleti kód pedig a 2. oszlop következő sorába írható, ami leegyszerűsíti a fordító munkáját. A kettőspont hiánya nem teszi lehetővé a címke és a műveleti kód megkülönböztetését, ha azok külön sorokban helyezkednek el.

Az assembly nyelv egyes verzióiban a kettőspont csak az utasításcímkék után kerül elhelyezésre, az adatcímkék után nem, és a címke hossza 6 vagy 8 karakterre korlátozódhat.

A címkemezőben nem lehetnek azonos nevek, mivel a címke parancscímekhez van társítva. Ha a program végrehajtása során nem kell parancsot vagy adatot hívni a memóriából, akkor a címkemező üresen marad.

Műveleti kód mező.

Ez a mező egy parancs vagy pszeudo-parancs emlékeztető kódját tartalmazza (lásd alább). A parancs mnemonikus kódját a nyelvfejlesztők választják ki. Assembly nyelven

A mnemonika van kiválasztva egy regiszter memóriából való betöltéséhez

), és a regiszter tartalmának a memóriába mentéséhez - egy emlékeztető

). assembly nyelveken

mindkét művelethez használhatja ugyanazt a nevet, ill

Ha a mnemonikus nevek kiválasztása tetszőleges lehet, akkor a két gépi utasítás használatának szükségességét a processzor architektúrája határozza meg

A regiszterek mnemonikája az assembler verziótól is függ (5.2.1. táblázat).

Operandus mező.

Itt található további információ, szükséges a művelet elvégzéséhez. Az ugrásparancsok operandusmezőjében megjelenik az a cím, amelyre az ugrást végrehajtani kell, valamint azok a címek és regiszterek, amelyek a gépi parancs operandusai. Példaként 8 bites processzorokhoz használható operandusokat adunk

● számszerű adatok,

különböző számrendszerekben mutatják be. A használt számrendszer jelzésére a konstanst az egyik latin betű követi: B,

Ennek megfelelően bináris, oktális, hexadecimális, decimális számrendszerek (

nem kell leírnod). Ha egy hexadecimális szám első számjegye A, B, C,

Ezután egy jelentéktelen 0-t (nulla) adunk hozzá;

● belső mikroprocesszor-regiszterek és memóriacellák kódjai

M (információs források vagy fogadók) A, B, C betűk formájában,

M vagy címük bármilyen számrendszerben (például 10B - nyilvántartási cím

bináris rendszerben);

● azonosítók,

repülőgép-nyilvántartási párok esetében,

Az első betűk B,

N; egy pár akkumulátorhoz és jellemző regiszterhez -

; a programszámlálóhoz -

;a veremmutatóhoz -

● címkék, amelyek az operandusok címét vagy a következő utasításokat jelzik a feltételes feltételben

(ha a feltétel teljesül) és feltétlen átmenetek. Például az M1 operandus a parancsban

a parancsra való feltétel nélküli átállás szükségességét jelenti, amelynek címe a címkemezőben M1 azonosítóval van jelölve;

● kifejezések,

amelyeket a fent tárgyalt adatok összekapcsolásával aritmetikai és logikai operátorok segítségével szerkesztünk. Vegye figyelembe, hogy az adatterület lefoglalásának módja a nyelvi verziótól függ. Assembly nyelvi fejlesztők számára

Határozza meg a szót), majd később írja be Alternatív lehetőség.

amely a kezdetektől fogva a processzorok nyelvén volt

Nyelvi változatban

használt

Állandó meghatározása).

A processzorok különböző hosszúságú operandusokat dolgoznak fel. Ennek meghatározásához az assembler fejlesztők különböző döntéseket hoztak, például:

A különböző hosszúságú II regiszterek különböző nevekkel rendelkeznek: EAX - 32 bites operandusok elhelyezésére (típus

); AX - 16 biteshez (típus

és AN - 8 biteshez (típus

● processzorokhoz

Minden műveleti kódhoz utótagok kerülnek: utótag

A típushoz

; ".B" utótag a típushoz

különböző műveleti kódokat használnak a különböző hosszúságú operandusokhoz, például egy bájt, félszó (

) és a szavakat egy 64 bites regiszterbe opkódok segítségével

illetőleg.

Megjegyzés mező.

Ez a mező magyarázatokat ad a program műveleteiről. A megjegyzések nem befolyásolják a program működését, és embereknek szólnak. Szükség lehet rájuk egy program módosításához, ami ilyen megjegyzések nélkül még a tapasztalt programozók számára is teljesen érthetetlen lehet. A megjegyzés szimbólummal kezdődik, és a programok magyarázatára és dokumentálására szolgál. A megjegyzés kezdő karaktere lehet:

● pontosvessző (;) a vállalat feldolgozóinak nyelvein

Felkiáltójel(!) nyelveken for

Minden külön megjegyzéssort egy vezető karakter előz meg.

Pszeudo-parancsok (irányelvek).

Az assembly nyelvben a parancsoknak két fő típusa van:

alapvető utasításokat, amelyek megfelelnek a processzor gépi kódjának. Ezek a parancsok végrehajtják a program által tervezett összes feldolgozást;

álparancsok vagy irányelvek, A program kódkombinációs nyelvre történő fordítási folyamatának kiszolgálására készült. Példaként a táblázatban. Az 5.2.2 néhány pszeudo-parancsot mutat be az assemblertől

a családnak

.

A programozás során vannak olyan helyzetek, amikor az algoritmus szerint ugyanazt a parancsláncot kell sokszor megismételni. A helyzetből való kilépéshez a következőket teheti:

● írja be a szükséges parancssort, amikor megjelenik. Ez a megközelítés a program volumenének növekedéséhez vezet;

● rendezze ezt a szekvenciát eljárásba (szubrutinba), és szükség esetén hívja meg. Ennek a kimenetnek megvannak a hátrányai: minden alkalommal, amikor egy speciális eljáráshívás parancsot és egy return parancsot kell végrehajtani, amelyek rövid és gyakran használt szekvencia esetén nagymértékben csökkenthetik a program sebességét.

A legegyszerűbb és hatékony módszer egy parancslánc ismételt megismétlése abból áll, hogy használjuk makró, amely egy pszeudo-parancsként ábrázolható, amely egy programban gyakran megtalálható parancscsoport újrafordítására szolgál.

A makrót vagy makroparancsot három szempont jellemzi: makrodefiníció, makroinverzió és makrokiterjesztés.

Makró definíció

Ez a programparancsok ismétlődő sorozatának megjelölése, amelyet a program szövegében található hivatkozásokhoz használnak.

A makródefiníció a következő szerkezettel rendelkezik:

Kifejezések listája; Makró definíció

A makrodefiníció adott szerkezetében három rész különíthető el:

● cím

makró, beleértve a nevet

Pszeudo-parancs

és egy sor paramétert;

● pontokkal jelölve test makró;

● csapat

érettségi

makró definíciók.

A makródefiníciós paraméterkészlet tartalmazza a kiválasztott utasításcsoport operandusmezőjében megadott összes paraméter listáját. Ha ezeket a paramétereket korábban megadtuk a programban, akkor ezeket nem kell feltüntetni a makródefiníciós fejlécben.

A kiválasztott parancscsoport összeállításához a névből álló fellebbezést használjuk

makróparancsok és a paraméterek listája más értékekkel.

Amikor az assembler makródefinícióval találkozik a fordítási folyamat során, eltárolja azt a makródefiníciós táblában. A név későbbi megjelenésekor a programban (

) egy makró esetében, az assembler lecseréli a makró törzsére.

A makrónév műveleti kódként történő használata meghívásra kerül makro-visszafordítás(makróhívás), és lecserélve a makró törzsére - makro bővítés.

Ha egy program karaktersorozatként van ábrázolva (betűk, számok, szóközök, írásjelek és kocsivisszalépések, hogy új sorba lépjen), akkor a makróbővítés abból áll, hogy ebből a sorozatból néhány láncot más láncokkal helyettesít.

A makró bővítése az összeállítási folyamat során történik, nem a program végrehajtása során. A karakterláncok manipulálására szolgáló módszerek hozzá vannak rendelve makró azt jelenti.

Az összeszerelési folyamat megtörténik két menetben:

● Az első lépésben minden makródefiníció megmarad, és a makróhívások kibővülnek. Ebben az esetben az eredeti programot beolvassa és olyan programmá alakítja, amelyben az összes makródefiníciót eltávolítják, és minden makróhívást a makró törzsével helyettesítenek;

● a második lépés makrók nélkül dolgozza fel az eredményül kapott programot.

Makrók paraméterekkel.

Az ismétlődő parancssorozatokkal való munkához, amelyek paraméterei különböző értékeket vehetnek fel, makródefiníciók állnak rendelkezésre:

● -val tényleges paraméterek, amelyek a makróhívás operandusmezőjébe kerülnek;

● -val hivatalos paramétereket. A makróbővítés során minden, a makró törzsében megjelenő formális paramétert a megfelelő aktuális paraméterrel helyettesítünk.

makrók használata paraméterekkel.

Az 1. program két hasonló parancssorozatot tartalmaz, amelyek abban különböznek, hogy az első felcseréli a P és a parancsokat

És a második

A 2. program tartalmaz egy makrót két formális P1 és P2 paraméterrel. A makróbővítés során a makrótörzsben minden P1 karaktert az első aktuális paraméterrel (P,

), és a P2 szimbólum helyére a második aktuális paraméter (

) az 1. számú programból. A makróhívásban

a 2. program jelölése: P,

Az első tényleges paraméter,

Második tényleges paraméter.

1. program

2. program

MOV EBX,Q MOV EAX,Pl

MOV Q,EAX MOV EBX,P2

MOV P,EBX MOV P2,EAX

Bővített képességek.

Nézzünk meg néhány speciális nyelvi funkciót

Ha egy feltételes ugrásparancsot és egy ugrandó címkét tartalmazó makrót kétszer vagy többször hívnak meg, akkor a címke megkettőződik (címke duplikálási probléma), ami hibát okoz. Ezért minden hívás külön címkét rendel paraméterként (a programozó által). A nyelvben

a címke helyinek minősül (

) és a fejlett képességeknek köszönhetően az assembler automatikusan más címkét generál a makró minden egyes kibontásakor.

lehetővé teszi makrók meghatározását más makrókon belül. Ez a speciális funkció nagyon hasznos egy program feltételes összekapcsolásával kombinálva. Mérlegeljük

IF WORDSIZE GT 16 M2 MAKRO

Az M2 makró az utasítás mindkét részében definiálható

A meghatározás azonban attól függ, hogy a program melyik processzorra van összeállítva: 16 bites vagy 32 bites. Ha az M1 nem kerül meghívásra, akkor az M2 makró egyáltalán nem lesz meghatározva.

Egy másik fejlett funkció, hogy a makrók más makrókat is hívhatnak, beleértve önmagukat is. rekurzív hívás. Ez utóbbi esetben a végtelen ciklus elkerülése érdekében a makrónak át kell adnia magának egy paramétert, amely minden bővítéssel változik, és jelölje be ezt a paramétert, és akkor fejezze be a rekurziót, amikor a paraméter elér egy bizonyos értéket.

A makró eszközök használatáról az assemblerben.

Makró használatakor az assemblernek képesnek kell lennie két funkció végrehajtására: mentse a makródefiníciókatÉs kiterjeszteni a makro kihívásokat.

Makródefiníciók mentése.

Minden makrónév egy táblázatban tárolódik. Minden névhez tartozik egy mutató a megfelelő makróra, hogy szükség esetén hívható legyen. Egyes assemblerek külön táblázattal rendelkeznek a makrónevek számára, másoknak van egy általános táblája, amelyben a makrónevek mellett minden géputasítás és direktíva található.

Ha összeállítás közben makróval találkozik létrehozva:

új táblázatelem a makró nevével, a paraméterek számával és egy másik makródefiníciós táblára mutató mutatóval, ahol a makró törzse kerül tárolásra;

● lista hivatalos paramétereket.

A makró törzsét, amely egyszerűen egy karaktersorozat, a rendszer ezután beolvassa és a makródefiníciós táblázatban tárolja. A ciklus törzsében előforduló formális paraméterek meg vannak jelölve különleges karakter.

Egy makró belső ábrázolása

a fenti példából a 2. programhoz (244. oldal) a következő:

MOV EAX, MOV EBX, MOV MOV &

ahol a pontosvesszőt kocsivisszaadási karakterként, az & jelet pedig formális paraméterkarakterként használják.

Makróhívások kiterjesztése.

Ha az összeállítás során makródefinícióval találkozunk, az a makrótáblában tárolódik. Makró meghívásakor az assembler ideiglenesen leállítja a bemeneti adatok beolvasását a beviteli eszközről, és elkezdi olvasni a tárolt makró törzsét. A makrótörzsből kinyert formális paramétereket tényleges paraméterek váltják fel, és a hívás biztosítja. Az "és" és az előtte paraméterek lehetővé teszik az összeszerelő számára, hogy felismerje őket.

Annak ellenére, hogy az assemblernek számos változata létezik, az összeszerelési folyamatok közös jellemzőkkel rendelkeznek, és sok tekintetben hasonlóak. A két menetes assembler működését az alábbiakban tárgyaljuk.

Kétmenetes szerelő.

Egy program több utasításból áll. Ezért úgy tűnik, hogy összeszereléskor a következő műveletsort használhatja:

● lefordítani gépi nyelvre;

● az így kapott gépi kódot egy fájlba, a lista megfelelő részét pedig egy másik fájlba vigye át;

● ismételje meg a felsorolt ​​eljárásokat, amíg a teljes programot le nem fordítja.

Ez a megközelítés azonban nem hatékony. Példa erre az úgynevezett probléma továbbító link. Ha az első utasítás egy ugrás a P utasításra, amely a program legvégén található, akkor az assembler nem tudja lefordítani. Először meg kell határoznia a P operátor címét, és ehhez be kell olvasnia a teljes programot. A forrásprogram minden teljes olvasása meghívásra kerül átjáró, átkelés. Mutatjuk, hogyan oldhatja meg az előretekintő link problémát két lépéssel:

az első menetben kellene gyűjtés tárolja az összes szimbólumdefiníciót (beleértve a címkéket is) a táblázatban, majd a második lépésben olvassa el és állítsa össze az egyes operátorokat. Ez a módszer viszonylag egyszerű, de az eredeti programon való második áthaladás több időt igényel az I/O műveletekkel;

● az első menetben kell alakítani a programot egy köztes formába és mentse el egy táblázatba, a második lépést pedig ne az eredeti program, hanem a táblázat szerint hajtsa végre. Ezzel az összeállítási módszerrel időt takaríthat meg, mivel a második lépés nem hajt végre I/O műveleteket.

Első lépés.

Első passz gól- szimbólumtáblázat készítése. Ahogy fentebb megjegyeztük, az első lépés másik célja az összes makródefiníció megőrzése és a hívások megjelenése szerinti kiterjesztése. Következésképpen a szimbólumdefiníció és a makróbővítés is egy lépésben történik. A szimbólum bármelyik lehet címke, vagy jelentése, amelyhez egy adott név van hozzárendelve a -you direktívával:

;Érték - puffer mérete

Azzal, hogy a parancscímke mezőben jelentést rendel a szimbolikus nevekhez, az assembler lényegében meghatározza azokat a címeket, amelyekkel minden parancs rendelkezni fog a program végrehajtása során. Ebből a célból az összeszerelő az összeszerelési folyamat során tárolja utasítás címszámláló(

) speciális változóként. Az első lépés elején a speciális változó értéke 0-ra van állítva, és minden egyes feldolgozott parancs után a parancs hosszával növekszik. Példaként a táblázatban. Az 5.2.3 egy programrészletet mutat, amely a parancsok hosszát és a számlálóértékeket jelzi. Az első lépésben táblázatok generálódnak szimbolikus nevek, direktívákÉs működési kódok,és ha szükséges szó szerinti asztal. A literál olyan állandó, amelyre az assembler automatikusan memóriát foglal le. Azonnal jegyezzük meg, hogy a modern processzorok közvetlen címmel ellátott utasításokat tartalmaznak, így összeszerelőik nem támogatják a literálokat.

Szimbólumnév táblázat

minden névhez egy elemet tartalmaz (5.2.4. táblázat). A szimbolikus névtáblázat minden eleme tartalmazza magát a nevet (vagy egy rámutatót), annak számértékét, és néha további információkat, amelyek magukban foglalhatják:

● a szimbólumhoz tartozó adatmező hossza;

● memória újraelosztási bitek (amelyek jelzik, hogy megváltozik-e egy szimbólum értéke, ha a program az assembler által tervezetttől eltérő címre kerül betöltésre);

● információ arról, hogy a szimbólum elérhető-e az eljáráson kívülről.

A szimbolikus nevek címkék. Operátorokkal adhatók meg (pl.

Irányelv táblázat.

Ez a táblázat felsorolja az összes direktívát vagy pszeudo-parancsot, amelyekkel egy program összeállításakor találkozhatunk.

Műveleti kód táblázat.

Minden műveleti kódhoz a táblázat külön oszlopokkal rendelkezik: műveleti kód megnevezése, 1. operandus, 2. operandus, a műveleti kód hexadecimális értéke, a parancs hossza és típusa (5.2.5. táblázat). A műveleti kódok az operandusok számától és típusától függően csoportokra vannak osztva. A parancs típusa határozza meg a csoport számát, és meghatározza a csoport összes parancsának feldolgozásához meghívott eljárást.

Második menet.

A második passz gólja- objektumprogram létrehozása és szükség esetén az assembly protokoll kinyomtatása; olyan kimeneti információkat, amelyek szükségesek ahhoz, hogy a linker a különböző időpontokban összeállított eljárásokat egyetlen végrehajtható fájlba kapcsolhassa.

A második lépésben (mint az elsőben) egyenként beolvassák és feldolgozzák az utasításokat tartalmazó sorokat. Az eredeti operátor és a kimeneti operátor hexadecimálisan származtatott belőle tárgy A kód kinyomtatható vagy pufferbe helyezhető későbbi nyomtatás céljából. A parancscímszámláló nullázása után a parancs meghívásra kerül következő kijelentés.

A forrásprogram hibákat tartalmazhat, például:

az adott szimbólum nincs, vagy többször van definiálva;

● a műveleti kódot érvénytelen név írja le (elírási hiba miatt), nincs elég operandusa, vagy túl sok operandusa van;

● nincs kezelő

Egyes összeszerelők észlelhetnek egy nem definiált szimbólumot, és kicserélhetik azt. Azonban a legtöbb esetben, amikor hibaüzenettel találkozik, az összeszerelő hibaüzenetet jelenít meg a képernyőn, és megpróbálja folytatni az összeállítási folyamatot.

Az assembly nyelvnek szentelt cikkek.

ÜZBEKisztáni NEMZETI EGYETEM MIRZO ULUGBEK NEVE

SZÁMÍTÁSTECHNOLÓGIAI KAR

A témában: EXE fájl szemantikai elemzése.

Elkészült:

Taskent 2003.

Előszó.

Assembly nyelv és parancsstruktúra.

EXE fájlszerkezet (szemantikus elemzés).

COM fájl szerkezet.

A cselekvés elve és a vírus terjedése.

Szétszerelő.

Programok.

Előszó

A programozói szakma csodálatos és egyedülálló. Manapság lehetetlen elképzelni a tudományt és az életet a legújabb technológia nélkül. Minden, ami az emberi tevékenységgel kapcsolatos, nem nélkülözhető számítógépes technológia. Ez pedig hozzájárul magas szintű fejlődéséhez és tökéletesítéséhez. Bár a személyi számítógépek fejlesztése nem olyan régen kezdődött, ez idő alatt óriási lépések történtek a szoftvertermékekben, és ezeket a termékeket még sokáig széles körben használják majd. A számítógéppel kapcsolatos tudás területe robbanásszerűen megnőtt, csakúgy, mint a megfelelő technológia. Ha nem vesszük figyelembe a kereskedelmi oldalt, akkor azt mondhatjuk, hogy a szakmai tevékenység ezen a területén nincsenek idegenek. Sokan nem haszonból vagy bevételből fejlesztenek programokat, hanem szabad akaratukból, szenvedélyből. Ez persze nem befolyásolhatja a program minőségét, és ebben az üzletágban úgymond verseny és igény van a minőségi kivitelezésre, a stabil munkavégzésre és a minden modern követelménynek való megfelelésre. Itt érdemes megjegyezni a mikroprocesszorok megjelenését is a 60-as években, amelyek nagyszámú lámpakészletet váltottak fel. Vannak olyan típusú mikroprocesszorok, amelyek nagyon különböznek egymástól. Ezek a mikroprocesszorok bitmélységükben és beépített rendszerparancsaikban különböznek egymástól. A leggyakoribbak: Intel, IBM, Celeron, AMD stb. Mindezek a processzorok az Intel processzorok fejlett architektúrájához kapcsolódnak. A mikroszámítógépek elterjedése két fő okból idézte elő az assembly nyelvvel kapcsolatos attitűdök újragondolását. Először is, az assembly nyelven írt programok lényegesen kevesebb memóriát és végrehajtási időt igényelnek. Másodszor, az assembly nyelv ismerete és az ebből származó gépi kód ismerete lehetővé teszi a gép architektúrájának megértését, ami nem valószínű, hogy magas szintű nyelven dolgozik. Bár a legtöbb szoftveres szakember olyan magas szintű nyelveken fejleszt, mint a Pascal, C vagy Delphi, ami könnyebb programíráskor, a legerősebb és leghatékonyabb szoftver részben vagy egészben assembly nyelven íródott. A magas szintű nyelveket úgy alakították ki, hogy elkerüljék a speciális műszaki jellemzők konkrét számítógépek. Az assembly nyelvet pedig a processzor sajátosságaihoz tervezték. Ezért ahhoz, hogy egy assembly nyelvű programot írhasson egy adott számítógépre, ismernie kell annak architektúráját. Ezekben a napokban a kilátás a fő szoftver termék egy EXE fájl. Figyelembe véve pozitív oldalai Ez azt jelenti, hogy a program szerzője biztos lehet a sértetlenségében. De gyakran ez messze nem így van. Van egy szétszerelő is. Disassembler segítségével megtudhatja a megszakításokat és a programkódokat. Az assemblerben jártas embernek nem lesz nehéz az egész programot ízlése szerint átdolgozni. Talán itt merül fel a leginkább megoldhatatlan probléma - a vírus. Miért írnak az emberek vírust? Van aki meglepődve, van aki haraggal teszi fel ezt a kérdést, de ennek ellenére továbbra is vannak, akiket ez a feladat nem a károkozás, hanem a rendszerprogramozás szempontjából érdekel. A vírusokat írta különböző okok. Vannak, akik szeretik a rendszerhívásokat, mások fejlesztik az assembler ismereteiket. Megpróbálom mindezt elmagyarázni magamban tanfolyami munka. Nemcsak az EXE fájl szerkezetéről szól, hanem az assembly nyelvről is.

^ Assembly Language.

Érdekes követni az első számítógépek megjelenésétől napjainkig a programozók assembly nyelvről alkotott elképzeléseinek átalakulását.

Valamikor régen az assembly olyan nyelv volt, amely nélkül a számítógépet semmi hasznosra nem lehetett rávenni. Fokozatosan változott a helyzet. Megjelentek a számítógéppel való kommunikáció kényelmesebb módjai. De más nyelvekkel ellentétben az assembler nem halt meg, sőt elvileg nem tudta ezt megtenni. Miért? A választ keresve próbáljuk megérteni, mi is az assembly nyelv általában.

Röviden, az assembly nyelv a gépi nyelv szimbolikus reprezentációja. A gépben a legalacsonyabb hardverszinten lévő összes folyamatot csak gépi nyelvi parancsok (utasítások) hajtják végre. Ebből jól látszik, hogy a közönséges név ellenére az assembly nyelv minden számítógéptípusnál más és más. Ez is érvényes kinézet assembly nyelven írt programok és ötletek, amelyeket ez a nyelv tükröz.

A hardverrel kapcsolatos (sőt, hardverfüggő, pl. a program sebességének növelése) problémákat az assembler ismerete nélkül nem lehet igazán megoldani.

Egy programozó vagy bármely más felhasználó bármilyen magas szintű eszközt használhat, még a virtuális világok felépítésére szolgáló programokat is, és talán nem is sejti, hogy a számítógép valójában nem a programja nyelvének parancsait hajtja végre, hanem azok átalakított reprezentációját. unalmas és unalmas parancssorozatok formájában egy teljesen más nyelvből - gépi nyelvből. Most képzeljük el, hogy egy ilyen felhasználónak nem szabványos problémája van, vagy valami egyszerűen nem működik. Például programjának valamilyen szokatlan eszközzel kell működnie, vagy más műveleteket kell végrehajtania, amelyek a számítógépes hardver működési elveinek ismeretét igénylik. Bármilyen okos is a programozó, bármilyen jó nyelven írta csodálatos programját, nem nélkülözheti az assembler ismereteit. És nem véletlen, hogy szinte minden magas szintű nyelvi fordító tartalmaz olyan eszközöket, amelyek moduljait az assembler modulokkal összekapcsolják, vagy támogatják a programozás összeállítási szintjéhez való hozzáférést.

Természetesen a számítógépes generalisták ideje már elmúlt. Ahogy mondani szokták, nem lehet elfogadni a mérhetetlenséget. De van valami közös, egyfajta alap, amire minden komoly számítógépes oktatás épül. Ez a számítógép működésének alapelveiről, architektúrájáról és assembly nyelvéről szóló ismeret, amely ennek a tudásnak a tükröződése és megtestesülése.

Egy tipikus modern számítógép (i486 vagy Pentium alapú) a következő összetevőkből áll (1. ábra).

Rizs. 1. Számítógép és perifériák

Rizs. 2. Blokkdiagram személyi számítógép

Az ábrából (1. ábra) jól látható, hogy a számítógép több fizikai eszközből áll, amelyek mindegyike egy egységhez, az úgynevezett rendszeregységhez csatlakozik. Ha logikusan gondolkodunk, akkor egyértelmű, hogy valamiféle koordináló eszköz szerepét tölti be. Nézzünk a rendszeregység belsejébe (nem kell megpróbálni bejutni a monitorba - nincs ott semmi érdekes, ráadásul veszélyes is): nyissa ki a házat, és nézzen meg néhány táblát, blokkot, csatlakozó vezetékeket. Funkcionális céljuk megértéséhez nézzük meg egy tipikus számítógép blokkvázlatát (2. ábra). Nem tart igényt az abszolút pontosságra, és csak egy modern személyi számítógép céljának, összekapcsolásának és elemeinek tipikus összetételének bemutatására szolgál.

Vizsgáljuk meg az ábrán látható diagramot. 2 kissé szokatlan stílusban.
Gyakran előfordul, hogy az ember, amikor valami újjal találkozik, olyan asszociációkat keres, amelyek segíthetnek megérteni az ismeretlent. Milyen asszociációkat vált ki a számítógép? Például egy számítógépet gyakran magával az emberrel társítok. Miért?

Amikor az ember megalkotott egy számítógépet, valahol mélyen magában azt hitte, hogy valami hasonlót hoz létre önmagában. A számítógép rendelkezik a külvilág információinak fogadására szolgáló szervekkel - billentyűzettel, egérrel és mágneses lemezmeghajtókkal. ábrán. 2 ezek a szervek a rendszerbuszoktól jobbra találhatók. A számítógépnek vannak olyan szervei, amelyek „megemésztik” a kapott információkat – ezek CPUés RAM. És végül a számítógép beszédszervekkel rendelkezik, amelyek a feldolgozás eredményeit produkálják. Ez is néhány eszköz a jobb oldalon.

Modern számítógépek persze távol áll az emberitől. Azokhoz a lényekhez hasonlíthatók, amelyek a feltétel nélküli reflexek nagy, de korlátozott halmazának szintjén lépnek kapcsolatba a külvilággal.
Ez a reflexkészlet gépi parancsok rendszerét alkotja. Nem számít, milyen magas szinten kommunikál a számítógéppel, ez végül a gépi parancsok unalmas és monoton sorozata lesz.
Minden gépi parancs egyfajta inger egyik vagy másik feltétlen reflex gerjesztésére. Az erre az ingerre adott reakció mindig egyértelmű és „bekötve” a mikroparancsblokkban mikroprogram formájában. Ez a mikroprogram műveleteket hajt végre egy gépi parancs végrehajtására, de bizonyos jelek szintjén logika számítógépet, ezáltal vezérelve a számítógép különféle alrendszereit. Ez az úgynevezett mikroprogram-vezérlés elve.

Folytatva az analógiát egy személlyel, megjegyezzük: ahhoz, hogy a számítógép megfelelően étkezzen, számos operációs rendszert, fordítóprogramot több száz programozási nyelvhez stb. ételt (programokat) bizonyos szabályok szerint szállítanak ki.gyomor (számítógép). Csak a számítógép gyomra szereti a diétát, a monoton ételeket – adjon neki strukturált információkat, szigorúan szervezett nullák és egyesek sorozatai formájában, amelyek kombinációi alkotják a gépi nyelvet.

Így, bár külsőleg poliglott, a számítógép csak egy nyelvet ért - a gépi utasítások nyelvét. Természetesen a számítógéppel való kommunikációhoz és munkához nem szükséges ismerni ezt a nyelvet, de szinte minden profi programozó előbb-utóbb szembesül azzal, hogy el kell tanulnia. Szerencsére a programozónak nem kell megpróbálnia megérteni a bináris számok különféle kombinációinak jelentését, mivel az 50-es években a programozók a gépi nyelv szimbolikus analógját kezdték használni a programozáshoz, amelyet assembly nyelvnek neveztek. Ez a nyelv pontosan tükrözi a gépi nyelv összes jellemzőjét. Ez az oka annak, hogy a magas szintű nyelvekkel ellentétben az assembly nyelv minden számítógéptípusnál más és más.

A fentiekből arra a következtetésre juthatunk, hogy mivel az assembly nyelv „natív” a számítógép számára, a leghatékonyabb program csak ebben írható meg (feltéve, hogy azt szakképzett programozó írja). Van itt egy apró „de”: ez egy nagyon munkaigényes folyamat, amely sok odafigyelést és gyakorlati tapasztalatot igényel. Ezért a valóságban főleg assemblerben írnak programokat, amiket biztosítani kell eredményes munka hardverrel. Néha a végrehajtási idő vagy a memóriafelhasználás szempontjából kritikus programrészek az assemblerben íródnak. Ezt követően szubrutinok formájában formalizálják, és magas szintű nyelven kombinálják a kóddal.

Bármely számítógép assembly nyelvének tanulását célszerű csak akkor kezdeni, ha megtudja, hogy a számítógép mely része maradt látható és hozzáférhető programozáshoz ezen a nyelven. Ez az ún. számítógépes programmodell, melynek része a mikroprocesszoros programmodell, amely bizonyos fokig 32 regisztert tartalmaz, és a programozó rendelkezésére áll.

Ezek a regiszterek két nagy csoportra oszthatók:

^ 16 felhasználói regisztráció;

16 rendszerregiszter.

Az Assembly nyelvi programok nagyon intenzíven használják a regisztereket. A legtöbb regiszternek meghatározott funkcionális célja van.

Ahogy a neve is sugallja, a felhasználói regisztereket felhasználói regisztereknek nevezzük, mert a programozó ezeket használhatja programjai írásakor. Ezek a regiszterek a következőket tartalmazzák (3. ábra):

Nyolc 32 bites regiszter, amelyeket a programozók használhatnak adatok és címek tárolására (más néven általános célú regiszterek (GPR)):

hat szegmensregiszter: cs, ds, ss, es, fs, gs;

állapot- és ellenőrzési nyilvántartások:

Flags regisztrálja a zászlókat/zászlókat;

Parancsmutató regiszter eip/ip.

Rizs. 3. Az i486 és Pentium mikroprocesszorok felhasználói regiszterei

Miért jelenik meg sok ilyen regiszter perjelekkel? Nem, ezek nem különböző regiszterek – egy nagy, 32 bites regiszter részei. A programban külön objektumként használhatók. Ez azért történt, hogy biztosítsák az Intel mikroprocesszorok fiatalabb, 16 bites modelljeihez írt programok működőképességét, kezdve az i8086-tól. Az i486 és Pentium mikroprocesszorok többnyire 32 bites regiszterekkel rendelkeznek. Számuk a szegmensregiszterek kivételével megegyezik az i8086-éval, de a méretük nagyobb, ami a megnevezésükben is megmutatkozik -
e előtag (Bővített).

^ Általános célú nyilvántartások
Ebben a csoportban minden regiszter lehetővé teszi az „alsó” részekhez való hozzáférést (lásd 3. ábra). Ezt az ábrát tekintve vegye figyelembe, hogy ezeknek a regisztereknek csak az alsó 16 és 8 bites része használható öncímzésre. Ezeknek a regisztereknek a felső 16 bitje nem érhető el független objektumként. Ezt az Intel mikroprocesszorok fiatalabb, 16 bites modelljeivel való kompatibilitás érdekében tették, amint azt fentebb megjegyeztük.

Soroljuk fel az általános célú regiszterek csoportjába tartozó regisztereket. Mivel ezek a regiszterek fizikailag a mikroprocesszorban, egy aritmetikai logikai egységben (ALU) találhatók, ALU regisztereknek is nevezik őket:

eax/ax/ah/al (Akkumulátor regiszter) - elem.
Köztes adatok tárolására szolgál. Egyes parancsok megkövetelik ennek a regiszternek a használatát;

ebx/bx/bh/bl (Alapregiszter) - alapregiszter.
Valamely objektum alapcímének tárolására szolgál a memóriában;

ecx/cx/ch/cl (Count register) - számlálóregiszter.
Olyan csapatokban használják, amelyek ismétlődő műveleteket hajtanak végre. Használata gyakran implicit és rejtett a megfelelő parancs algoritmusában.
Például a hurokhurok szervezésére szolgáló parancs amellett, hogy a vezérlést átadja egy bizonyos címen található parancsnak, elemzi és eggyel csökkenti az ecx/cx regiszter értékét;

edx/dx/dh/dl (Adatregiszter) - adatregiszter.
Csakúgy, mint az eax/ax/ah/al regiszter, közbenső adatokat tárol. Egyes parancsokban a használata kötelező; Egyes parancsoknál ez implicit módon történik.

A következő két regiszter az úgynevezett láncműveletek támogatására szolgál, vagyis olyan műveletek, amelyek szekvenciálisan feldolgozzák az elemek láncait, amelyek mindegyike 32, 16 vagy 8 bites lehet:

esi/si (Source Index register) - forrásindex.
Ez a láncolt műveletek regisztere tartalmazza a forráslánc elemének aktuális címét;

edi/di (Cél Index regiszter) - a vevő (címzett) indexe.
Ez a láncolt műveletek regisztere tartalmazza a céllánc aktuális címét.

A mikroprocesszoros architektúrában egy adatstruktúra, például egy verem támogatott hardver és szoftver szinten. A veremmel való munkához speciális parancsok vannak a mikroprocesszoros utasításrendszerben, és a mikroprocesszoros szoftvermodellben speciális regiszterek vannak erre:

esp/sp (Stack Pointer register) - veremmutató regiszter.
Az aktuális veremszegmensben lévő verem tetejére mutató mutatót tartalmaz.

ebp/bp (Base Pointer register) - verem keret alapmutató regiszter.
A veremben lévő adatok véletlenszerű elérésének megszervezésére tervezték.

A verem egy programterület tetszőleges adatok ideiglenes tárolására. Természetesen adatszegmensben is tárolhatók adatok, de ebben az esetben minden ideiglenesen tárolt adathoz külön elnevezett memóriacellát kell létrehozni, ami növeli a program méretét és a felhasznált nevek számát. A verem kényelme abban rejlik, hogy a területe újrafelhasználható, a veremben lévő adatok tárolása és onnan történő visszakeresése a hatékony push és pop parancsok segítségével történik, nevek megadása nélkül.
A verem hagyományosan például a program által használt regiszterek tartalmának elmentésére szolgál egy szubrutin hívása előtt, amely viszont a processzor regisztereit "saját céljaira" használja. A regiszterek eredeti tartalma a szubrutin visszatérése után kiugrik a veremből. Egy másik gyakori technika a szükséges paraméterek átadása egy szubrutinnak a veremen keresztül. A szubrutin, tudva, hogy a paraméterek milyen sorrendben kerülnek a verembe, onnan átveheti és felhasználhatja azokat a végrehajtása során. Megkülönböztető tulajdonság A verem egy egyedi sorrend, amelyben a benne lévő adatok lekérése: adott időpontban csak a legfelső elem érhető el a veremen, azaz. a legutóbb a verembe tolt elem. A legfelső elem kiemelése a veremből elérhetővé teszi a következő elemet. A veremelemek a verem számára lefoglalt memóriaterületen helyezkednek el, a verem aljától (vagyis a maximális címétől) kezdve a szekvenciálisan csökkenő címeken. A legfelső, elérhető elem címét az SP veremmutató regiszter tárolja. A programmemória bármely más területéhez hasonlóan a veremnek valamilyen szegmens részét kell képeznie, vagy külön szegmenst kell alkotnia. Mindkét esetben ennek a szegmensnek a szegmenscíme az SS szegmensveremregiszterbe kerül. Így az SS:SP regiszterpár egy hozzáférhető veremcella címét írja le: az SS a verem szegmenscímét, az SP pedig a veremben tárolt utolsó adatok eltolását tárolja (4. ábra, a). Vegye figyelembe, hogy a kezdeti állapotban az SP veremmutató egy olyan cellára mutat, amely a verem alja alatt található, és nem szerepel benne.

4. ábra Verem felépítése: a - kezdeti állapot, b - egy elem betöltése után (ebben a példában az AX regiszter tartalma), c - a második elem betöltése után (a DS regiszter tartalma), d - egy elem kirakása után elem, e - miután kirakott két elemet, és visszatér az eredeti állapotába.

A verembe való betöltés egy speciális paranccsal történik a köteggel való munkához (push). Ez az utasítás először 2-vel csökkenti a veremmutató tartalmát, majd az operandust az SP-ben lévő címre helyezi. Ha például ideiglenesen szeretnénk tárolni az AX regiszter tartalmát a veremben, akkor futtassuk le a parancsot.

A köteg az ábrán látható állapotba kerül. 1.10, b. Látható, hogy a veremmutató két bájttal feljebb tolódik (alacsonyabb címek felé), és erre a címre íródik a push parancsban megadott operandus. A következő verembetöltési parancs pl.

ábrán látható állapotba helyezi a köteget. 1.10, c. A verem most két elemet fog tárolni, és csak a legfelső, amelyre a veremmutató SP mutat, lesz elérhető. Ha egy idő után vissza kell állítani a veremben tárolt regiszterek eredeti tartalmát, akkor a veremből való eltávolításhoz a pop (push) parancsokat kell végrehajtanunk:

pop DS
pop AX

Mekkora legyen a köteg? Attól függ, hogy milyen intenzíven használják a programban. Ha például egy 10 000 bájtos tömböt szeretne tárolni a veremben, akkor a veremnek legalább ekkora méretűnek kell lennie. Nem szabad megfeledkezni arról, hogy bizonyos esetekben a rendszer automatikusan használja a veremet, különösen az int 21h megszakítási parancs végrehajtásakor. Ezzel a paranccsal a processzor először a visszatérési címet tolja a verembe, majd a DOS a regiszterek tartalmát és a megszakított programmal kapcsolatos egyéb információkat a verembe. Ezért még akkor is, ha egy program egyáltalán nem használ veremet, akkor is jelen kell lennie a programban, és legalább több tucat szó méretűnek kell lennie. Első példánkban 128 szót rendeltünk a veremhez, ami biztosan elég.

^ Az assembler program felépítése

Az assembly nyelvű program memóriablokkok, úgynevezett memóriaszegmensek gyűjteménye. Egy program egy vagy több ilyen blokkszegmensből állhat. Minden szegmens nyelvi mondatok gyűjteményét tartalmazza, amelyek mindegyike külön programkódsort foglal el.

Az assembler utasításoknak négy típusa van:

parancsok vagy utasítások, amelyek a gépi parancsok szimbolikus analógjai. A fordítási folyamat során az assembler utasításokat a mikroprocesszor utasításkészletének megfelelő parancsaivá alakítják;

makroparancsok - a műsorszöveg bizonyos módon formázott mondatai, amelyeket adás közben más mondatok helyettesítenek;

direktívák, amelyek utasítások az assembler fordítónak bizonyos műveletek végrehajtására. Az irányelveknek nincs megfelelőjük a gépi ábrázolásban;

bármilyen karaktert tartalmazó megjegyzéssorok, beleértve az orosz ábécé betűit is. A megjegyzéseket a fordító figyelmen kívül hagyja.

^ Összeállítás szintaxisa

A programot alkotó mondatok lehetnek parancsnak, makrónak, direktívának vagy megjegyzésnek megfelelő szintaktikai konstrukciók. Ahhoz, hogy az assembler fordító felismerje őket, bizonyos szintaktikai szabályok szerint kell őket kialakítani. Ehhez a legjobb a nyelv szintaxisának formális leírását használni, például a nyelvtani szabályokat. A programozási nyelvek ilyen módon történő leírásának leggyakoribb módjai a szintaktikai diagramok és a kiterjesztett Backus-Naur űrlapok. Mert gyakorlati használat a szintaktikai diagramok kényelmesebbek. Például az assembly nyelvi utasítások szintaxisa leírható a következő ábrákon látható szintaxisdiagramok segítségével.

Rizs. 5. Összeállítási mondatformátum

Rizs. 6. Az irányelv formátuma

Rizs. 7. Parancsok és makrók formátuma

Ezeken a képeken:

címkenév - egy azonosító, amelynek értéke a program forráskódjában szereplő mondat első bájtjának címe, amelyet megjelöl;

name – egy azonosító, amely megkülönbözteti ezt az irányelvet más, azonos nevű direktíváktól. Egy adott direktíva összeállító általi feldolgozásának eredményeként bizonyos jellemzők hozzárendelhetők ehhez a névhez;

egy műveleti kód (OPC) és egy direktíva a megfelelő gépi utasítás, makróutasítás vagy fordítói utasítás emlékező szimbólumai;

Az operandusok egy parancs, makró vagy assembler direktíva részei, amelyek kijelölik azokat az objektumokat, amelyeken a műveletek végrehajtásra kerülnek. Az összeszerelő nyelvi operandusokat numerikus és szöveges konstansokat, címkéket és változóazonosítókat tartalmazó kifejezések írják le operátorjeleket és néhány fenntartott szót használva.

^ Hogyan kell használni a szintaktikai diagramokat? Nagyon egyszerű: nem kell mást tennie, mint megkeresni, majd követni az utat a diagram bemenetétől (bal oldalt) a kimenetéig (jobb oldalon). Ha létezik ilyen út, akkor a mondat vagy szerkezet szintaktikailag helyes. Ha nincs ilyen útvonal, akkor a fordító nem fogadja el ezt a konstrukciót. A szintaktikai diagramokkal való munka során ügyeljen a nyilakkal jelzett bejárás irányára, mivel az utak között lehetnek olyanok, amelyek jobbról balra követhetők. A szintaktikai diagramok lényegében a fordító működésének logikáját tükrözik a program bemeneti mondatainak elemzésekor.

A programszöveg írásakor elfogadható karakterek:

Minden leveleket: A-Z, a-z. Ebben az esetben a nagy- és kisbetűket egyenértékűnek tekintjük;

Számok 0-tól 9-ig;

?, @, $, _, &;

Elválasztók, . ()< > { } + / * % ! " " ? \ = # ^.

Az összeszerelő nyelvi mondatok lexémákból jönnek létre, amelyek szintaktikailag elválaszthatatlan, a fordító számára értelmes nyelvi szimbólumok sorozatai.

A lexémák a következők:

Az azonosítók érvényes karaktersorozatok, amelyek programobjektumok, például műveleti kódok, változónevek és címkenevek kijelölésére szolgálnak. Az azonosítók írásának szabálya a következő: egy azonosító egy vagy több karakterből állhat. Szimbólumként használhatja a latin ábécé betűit, számokat és néhány speciális karaktert - _, ?, $, @. Az azonosító nem kezdődhet számjegy karakterrel. Az azonosító hossza legfeljebb 255 karakter lehet, bár a fordító csak az első 32 karaktert fogadja el, a többit figyelmen kívül hagyja. Az opció segítségével beállíthatja a lehetséges azonosítók hosszát parancs sor mv. Ezen kívül lehetőség van arra, hogy a fordító utasítsa a kis- és nagybetűk megkülönböztetését, vagy figyelmen kívül hagyja azok különbségét (ami alapértelmezés szerint megtörténik).

^Assembler parancsok.

Az Assembler parancsok felfedik a követelményeknek a számítógépre való átvitelének képességét, egy olyan mechanizmust, amely a program vezérlését (ciklusok és átmenetek) átadja a logikai összehasonlítások és a programszervezés érdekében. A programozható feladatok azonban ritkán ilyen egyszerűek. A legtöbb program ciklusok sorozatát tartalmazza, amelyekben több parancs ismétlődik, amíg el nem ér egy bizonyos követelményt, és különféle ellenőrzéseket, amelyek meghatározzák, hogy a műveletek közül melyiket kell végrehajtani. Egyes utasítások átadhatják a vezérlést a normál lépéssorozat megváltoztatásával az utasításmutatóban lévő eltolás értékének közvetlen módosításával. Mint korábban említettük, különböző parancsok léteznek a különböző processzorokhoz, de megvizsgálunk néhány parancsot a 80186, 80286 és 80386 processzorokhoz.

A zászlók állapotának leírásához egy bizonyos parancs végrehajtása után a zászlók jelzőregiszterének szerkezetét tükröző táblázatból származó válogatást használunk:

A táblázat alsó sora a jelzők értékeit mutatja a parancs végrehajtása után. A következő jelöléseket használják:

1 - a parancs végrehajtása után a zászló be van állítva (egyenlő 1-gyel);

0 - a parancs végrehajtása után a zászló visszaáll (0-val egyenlő);

r - a zászló értéke a parancs eredményétől függ;

A parancs végrehajtása után a zászló nincs megadva;

szóköz - a parancs végrehajtása után a zászló nem változik;

A következő jelölést használják az operandusok ábrázolására szintaktikai diagramokban:

r8, r16, r32 - operandus az egyik bájtméret, szó vagy duplaszó regiszterében;

m8, m16, m32, m48 - memória operandus mérete byte, szó, dupla szó vagy 48 bit;

i8, i16, i32 - azonnali operandusméret byte, szó vagy dupla szó;

a8, a16, a32 - relatív cím (eltolás) a kódszegmensben.

Parancsok (ábécé sorrendben):

*Ezek a parancsok részletesen le vannak írva.

HOZZÁAD
(Kiegészítés)

Kiegészítés

^ Parancs diagram:

rendeltetési hely, forrás hozzáadása

Cél: két bájt, szó vagy dupla szó méretű forrás és cél operandus hozzáadása.

Munka algoritmus:

adja hozzá a forrás és a cél operandust;

írja be az összeadás eredményét a vevőbe;

állítsa be a zászlókat.

A zászlók állapota a parancs végrehajtása után:

Alkalmazás:
Az add parancs két egész operandus hozzáadására szolgál. Az összeadás eredménye az első operandus címére kerül. Ha az összeadás eredménye túlmegy a vevő operandus határain (túlcsordulás történik), akkor ezt a helyzetet figyelembe kell venni a cf jelző és az adc parancs későbbi lehetséges használatának elemzésével. Például adjuk hozzá az ax regiszterben és a ch memóriaterületben lévő értékeket. Hozzáadáskor vegye figyelembe a túlcsordulás lehetőségét.

Regisztráció plusz regiszter vagy memória:

|000000dw|modregr/rm|

AX regiszter (AL) plusz azonnali érték:

|0000010w|--data--|adat, ha w=1|

Regiszter vagy memória plusz azonnali érték:

|100000sw|mod000r/m|--data--|adat, ha BW=01|

HÍVÁS
(HÍVÁS)

Eljárás vagy feladat hívása

^ Parancs diagram:

Célja:

a vezérlés átadása egy közeli vagy távoli eljárásra a visszatérési pont címének a veremben való tárolásával;

feladatok váltása.

Munka algoritmus:
az operandus típusa határozza meg:

Címke közelében - az eip/ip parancsmutató tartalma a verembe kerül, és a címkének megfelelő új címérték betöltődik ugyanabba a regiszterbe;

Távoli címke – az eip/ip és a cs parancsmutató tartalma a verembe kerül. Ezután a távoli címkének megfelelő új címértékek betöltődnek ugyanazokba a regiszterekbe;

R16, 32 vagy m16, 32 - definiáljon egy regisztert vagy memóriacellát, amely eltolásokat tartalmaz az aktuális utasításszegmensben, amelyre a vezérlés átkerül. A vezérlés átadásakor az eip/ip parancsmutató tartalma a verembe kerül;

Memóriamutató - meghatároz egy memóriahelyet, amely egy 4 vagy 6 bájtos mutatót tartalmaz a hívott eljárásra. Egy ilyen mutató szerkezete 2+2 vagy 2+4 bájt. Az ilyen mutató értelmezése a mikroprocesszor működési módjától függ:

^ Jelzők állapota a parancs végrehajtása után (kivéve a feladatváltást):

a parancs végrehajtása nincs hatással a zászlókra

Amikor egy feladatot váltanak, a jelzőértékek az átváltott feladat TSS állapotszegmensében lévő zászlók regiszterével kapcsolatos információk szerint módosulnak.
Alkalmazás:
A call parancs lehetővé teszi a vezérlés rugalmas és többváltozatos átvitelének megszervezését egy alprogramra, miközben megőrzi a visszatérési pont címét.

Objektumkód (négy formátum):

Közvetlen címzés egy szegmensben:

|11101000|disp-low|diep-high|

Közvetett címzés egy szegmensben:

|11111111|mod010r/m|

Közvetett címzés a szegmensek között:

|11111111|mod011r/m|

Közvetlen címzés a szegmensek között:

|10011010|offset-low|offset-magas|seg-low|seg-magas|

CMP
(Hasonlítsa össze az operandusokat)

Operandus összehasonlítás

^ Parancs diagram:

cmp operandus1,operandus2

Cél: két operandus összehasonlítása.

Munka algoritmus:

kivonás végrehajtása(operandus1-operandus2);

az eredménytől függően állítsa be a flageket, ne változtasson operandus1 és operandus2 (vagyis ne emlékezzen az eredményre).

Alkalmazás:
Ezt a parancsot két operandus összehasonlítására szolgál kivonással az operandusok megváltoztatása nélkül. A parancs eredménye alapján zászlókat állítunk be. A cmp parancsot a feltételes ugrásparancsokkal és a setcc byte byte paranccsal használják.

Objektumkód (három formátum):

Regisztrálás vagy memória regiszterrel:

|001110dw|modregr/m|

Azonnali érték AX (AL) regiszterrel:

|0011110w|--data--|adat, ha w=1|

Azonnali érték regiszterrel vagy memóriával:

|100000sw|mod111r/m|--data--|adat, ha sw=0|

DECEMBER
(Az operandus csökkentése 1-gyel)

Egy operandus eggyel csökkentése

^ Parancs diagram:

dec operandus

Cél: Csökkentse egy operandus értékét a memóriában vagy a regiszterben 1-gyel.

Munka algoritmus:
a parancs kivon 1-et az operandusból. A zászlók állapota a parancs végrehajtása után:

Alkalmazás:
A dec utasítás egy bájt, szó, dupla szó értékének csökkentésére szolgál a memóriában vagy a regiszterben. Azonban vegye figyelembe, hogy a parancs nem befolyásolja a cf jelzőt.

Regisztráció: |01001reg|

^ Regiszter vagy memória: |1111111w|mod001r/m|

DIV
(Aláíratlan osztás)

Aláíratlan felosztás

Csapatvázlat:

div osztó

Cél: Osztási művelet végrehajtása két előjel nélküli bináris érték között.

^ Működési algoritmus:
A parancs megköveteli két operandus megadását - az osztó és az osztó. Az osztalékot implicit módon adjuk meg, mérete pedig a parancsban megadott osztó méretétől függ:

ha az osztó bájt méretű, akkor az osztalékot az ax regiszterben kell elhelyezni. A művelet után a hányadost al-ba, a maradékot ah-ba helyezzük;

ha az osztó szó méretű, akkor az osztaléknak a dx:ax regiszterpárban kell elhelyezkednie, az osztalék alacsony rendű részének pedig axben kell lennie. A művelet után a hányadost ax-ba, a maradékot dx-be helyezzük;

ha az osztó dupla szó nagyságú, akkor az osztaléknak az edx:eax regiszterpárban kell elhelyezkednie, az osztalék alacsony rendű részének pedig az eax-ben kell lennie. A művelet után a hányadost az eax-be, a maradékot pedig az edx-be helyezzük.

^ A zászlók állapota a parancs végrehajtása után:

Alkalmazás:
A parancs az operandusok egész számmal történő felosztását hajtja végre, előállítva az osztás eredményét a hányadosként és az osztás maradékaként. Osztási művelet végrehajtásakor kivétel előfordulhat: 0 - osztási hiba. Ez a helyzet két eset egyikében fordul elő: az osztó 0, vagy a hányados túl nagy ahhoz, hogy beleférjen az eax/ax/al regiszterbe.

Objektumkód:

|1111011w|mod110r/m|

INT
(Megszakítás)

A megszakítási szolgáltatási rutin hívása

^ Parancs diagram:

int megszakítási_szám

Cél: a megszakítási szolgáltatási rutin hívása a parancsoperandus által megadott megszakítási számmal.

^ Működési algoritmus:

tolja a zászlókat a zászlók/zászlók regisztere és a visszatérési cím a verembe. Visszatérési cím írásakor először a cs szegmensregiszter tartalma kerül kiírásra, majd az eip/ip parancsmutató tartalma;

állítsa vissza az if és tf jelzőket nullára;

adja át a vezérlést a megadott számú megszakítási szolgáltatási programnak. A vezérlés átviteli mechanizmusa a mikroprocesszor működési módjától függ.

^ A zászlók állapota a parancs végrehajtása után:

Alkalmazás:
Amint a szintaxisból látható, ennek a parancsnak két formája van:

int 3 - saját egyedi műveleti kódja 0cch, és egy bájtot foglal el. Ez a körülmény nagyon kényelmessé teszi a különféle szoftverhibakeresőkben történő használatát, hogy töréspontokat állítsanak be bármely parancs első bájtjának lecserélésével. A mikroprocesszor, ha a parancsok sorrendjében 0cch műveleti kóddal rendelkező paranccsal találkozik, meghívja a 3-as vektorszámú megszakításfeldolgozó programot, amely a szoftverhibakeresővel való kommunikációra szolgál.

A parancs második formája két bájtot foglal el, működési kódja 0cdh, és lehetővé teszi, hogy hívást kezdeményezzen egy megszakítási szolgáltatási rutinhoz, amelynek vektorszáma 0 és 255 között van. A vezérlés átvitelének jellemzői, amint megjegyeztük, a mikroprocesszor működési módjától függenek.

Objektumkód (két formátum):

Regisztráció: |01000reg|

^ Regiszter vagy memória: |1111111w|mod000r/m|

J.C.C.
JCXZ/JECXZ
(Ugrás, ha állapot)

(Ugrás, ha CX=nulla/ Ugrás, ha ECX=nulla)

Ugrás, ha a feltétel teljesül

Ugrás, ha a CX/ECX nulla

^ Parancs diagram:

jcc címkét
jcxz címke
jecxz címke

Cél: áttérés az aktuális parancsszegmensen belül bizonyos feltételektől függően.

^ Parancsalgoritmus (kivéve jcxz/jecxz):
A jelzők állapotának ellenőrzése a műveleti kódtól függően (az ellenőrzött állapotot tükrözi):

ha a tesztelt feltétel igaz, akkor lépjen az operandus által jelzett cellára;

ha az ellenőrzött feltétel hamis, akkor adja át a vezérlést a következő parancsra.

A jcxz/jecxz parancs algoritmusa:
Annak feltételének ellenőrzése, hogy az ecx/cx regiszter tartalma nulla:

ha az állapot ellenőrzés alatt áll

Parancsstruktúra assembly nyelven A gépi parancsok szintjén történő programozás az a minimális szint, amelyen számítógépes programozás lehetséges. A gépi irányítási rendszernek elegendőnek kell lennie a szükséges műveletek végrehajtásához a gépi berendezésnek adott utasításokkal. Minden gépi utasítás két részből áll: egy operatív részből, amely meghatározza, hogy „mit tegyünk”, és egy operandusból, amely meghatározza a feldolgozó objektumokat, vagyis a „mit tegyünk”. Az Assembly nyelven írt mikroprocesszoros gépi utasítás egyetlen sor, amelynek a következő formája van: címke parancs/irányító operandus(ok); megjegyzések A címkét, a parancsot/direktívát és az operandust legalább egy szóköz vagy tabulátor karakter választja el. A parancs operandusai vesszővel vannak elválasztva.

Assembly Language parancsszerkezet Az assembler parancs megmondja a fordítónak, hogy a mikroprocesszornak milyen műveletet kell végrehajtania. Az összeállítási direktívák a program szövegében megadott paraméterek, amelyek befolyásolják az összeállítási folyamatot vagy a kimeneti fájl tulajdonságait. Az operandus megadja az adatok kezdeti értékét (az adatszegmensben), vagy azokat az elemeket, amelyeken a parancsművelet végrehajtódik (a kódszegmensben). Egy utasításnak lehet egy vagy két operandusa, vagy nem is. Az operandusok számát implicit módon az utasításkód adja meg. Ha egy parancsot vagy utasítást a következő sorban kell folytatni, a fordított perjel karakter kerül felhasználásra: "" . Alapértelmezés szerint az assembler nem tesz különbséget a kis- és nagybetűk között, amikor parancsokat és direktívákat ír. Példák direktívákra és parancsokra Count db 1 ; Név, direktíva, egy operandus mov eax, 0 ; Parancs, két operandus

Az azonosítók érvényes karaktersorozatok, amelyek a változónevek és címkenevek jelölésére szolgálnak. Az azonosító egy vagy több alábbi karakterből állhat: a latin ábécé összes betűje; számok 0-tól 9-ig; speciális karakterek: _, @, $, ? . A címke első karaktereként egy pont használható. A fenntartott assembler nevek (direktívák, operátorok, parancsnevek) nem használhatók azonosítóként. Az azonosító első karakterének betűnek vagy speciális karakternek kell lennie. Maximális hossz Az azonosító 255 karakterből áll, de a fordító elfogadja az első 32 karaktert, a többit figyelmen kívül hagyja. Minden olyan címkének, amely olyan sorba íródott, amely nem tartalmaz assembler direktívát, kettősponttal ":" kell végződnie. A címkének, a parancsnak (direktívának) és az operandusnak nem kell a sorban egy adott helyen kezdődnie. A program jobb olvashatósága érdekében ajánlatos ezeket egy oszlopba írni.

Címkék Az assembler direktívát nem tartalmazó sorokra írt összes címkének kettősponttal ":" kell végződnie. A címkének, a parancsnak (direktívának) és az operandusnak nem kell a sorban egy adott helyen kezdődnie. A program jobb olvashatósága érdekében ajánlatos ezeket egy oszlopba írni.

Megjegyzések A megjegyzések használata egy programban javítja a program áttekinthetőségét, különösen akkor, ha a parancskészlet célja nem egyértelmű. A megjegyzések a forrásmodul bármely sorában pontosvesszővel (;) kezdődnek. Minden karakter a "; " a sor végén egy megjegyzés található. A megjegyzés bármilyen nyomtatható karaktert tartalmazhat, beleértve a szóközt is. A megjegyzés átívelheti a teljes sort, vagy követheti az ugyanabban a sorban lévő parancsot.

Assembly Language program felépítése Az assembly nyelven írt program több modulnak nevezett részből állhat, amelyek mindegyike egy vagy több adat-, verem- és kódszegmenst definiálhat. Minden assembly nyelvű teljes programnak tartalmaznia kell egy fő- vagy főmodult, amelyből a végrehajtás kezdődik. A modul tartalmazhat programrészletek, adatok és veremszegmensek deklarált megfelelő direktívák segítségével.

Memóriamodellek A szegmensek deklarálása előtt meg kell adni a memóriamodellt egy direktíva segítségével. MODEL módosító memória_modell, hívási_konvenció, OS_típus, verem_paraméter Az assembly nyelv alapszintű memóriamodelljei: Memóriamodell Kódcímzés Adatcímzés operációs rendszer Kód és adatok APRÓ MS-DOS KÖZELÉBEN Elfogadható KICSI MS-DOS KÖZELÉBEN, Windows nincs KÖZÉPES TOVÁBB MS-DOS KÖZELÉB, Windows nincs KOMPAKT KÖZEL MS-DOS, Windows nincs NAGY TÁVOLI MS-DOS, Windows nincs HATALMAS TOVÁBB MS-DOS, Windows Nem Windows 2000, Windows XP, Windows Elfogadható FLAT NT KÖZELÉBEN,

Memóriamodellek Az apró modell csak 16 bites MS-DOS alkalmazásokban működik. Ebben a modellben minden adat és kód egy fizikai szegmensben található. A programfájl mérete ebben az esetben nem haladja meg a 64 KB-ot. A kis modell egy kódszegmenst és egy adatszegmenst támogat. Ennek a modellnek a használatakor az adatok és a kód címzettjei a közelben vannak. A médiummodell több kódszegmenst és egy adatszegmenst támogat, a kódszegmensekben lévő összes hivatkozást alapértelmezés szerint távolinak, az adatszegmensek hivatkozásait pedig közelnek tekinti. A kompakt modell több olyan adatszegmenst támogat, amelyek távoli adatcímzést (far) használnak, és egy kódszegmenst, amely közeli címzést (közeli) használ. A nagy modell több kódszegmenst és több adatszegmenst is támogat. Alapértelmezés szerint minden kódra és adatra való hivatkozás távolinak számít. A hatalmas modell szinte egyenértékű a nagy memóriás modellel.

Memóriamodellek A lapos modell szegmentálatlan programkonfigurációt feltételez, és csak 32 bites operációs rendszerekben használatos. Ez a modell abban hasonlít az apró modellhez, hogy az adatok és a kód egyetlen szegmensben találhatók, de ez 32 bites. A direktíva előtti lapos modell programjának kidolgozása. lakásmodellnek el kell helyeznie az egyik direktívát: . 386, . 486, . 586 ill. 686. A processzorválasztó direktíva megválasztása határozza meg a programok írásakor elérhető utasítások halmazát. A processzorválasztási direktíva utáni p betű védett üzemmódot jelent. Az adat- és kódcímzés közel van, minden cím és mutató 32 bites.

Memória modellek. MODEL módosító memória_modell, hívási_konvenció, OS_típus, verem_paraméter A módosító paraméter a szegmenstípusok meghatározására szolgál, és a következő értékeket veheti fel: use 16 (a kiválasztott modell szegmensei 16 bitesként kerülnek felhasználásra) use 32 (a kiválasztott modell szegmensei használatosak 32 bitesként). A calling_convention paramétert a paraméterek átadásának módjának meghatározására használják, amikor egy eljárást más nyelvekről hívnak meg, beleértve a magas szintű nyelveket (C++, Pascal). A paraméter a következő értékeket veheti fel: C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

Memória modellek. MODEL módosító memória_modell, calling_convention, OS_type, stack_parameter Az OS_type paraméter alapértelmezés szerint OS_DOS, és be van kapcsolva Ebben a pillanatban ez az egyetlen támogatott érték ehhez a paraméterhez. A stack_parameter paraméter beállítása: NEARSTACK (az SS regiszter egyenlő a DS-szel, az adatok és a veremterületek ugyanabban a fizikai szegmensben vannak lefoglalva) FARSTACK (az SS regiszter nem egyenlő a DS-szel, az adatok és a veremterületek különböző fizikai szegmensekben vannak lefoglalva). Az alapértelmezett érték a NEARSTACK.

Példa egy olyan programra, amely nem csinál semmit. 686 P. MODELL LAKÁS, STDCALL. ADAT. KÓD START: RET END START RET - mikroprocesszor parancs. Ez biztosítja a program megfelelő leállását. A program többi része a fordító működésére vonatkozik. . 686 P - A Pentium 6 (Pentium II) védett módú parancsai megengedettek. Ez a direktíva kiválasztja a támogatott assembler utasításokat, jelezve a processzor modelljét. . MODEL FLAT, stdcall - lapos memória modell. Ezt a memóriamodellt a Windows operációs rendszer használja. stdcall – a használt eljáráshívási konvenció.

Példa egy olyan programra, amely nem csinál semmit. 686 P. MODELL LAKÁS, STDCALL. ADAT. KÓD START: RET END START. A DATA egy adatokat tartalmazó programszegmens. Ez a program nem használja a veremet, tehát a szegmenst. A STACK hiányzik. . A CODE egy kódot tartalmazó programszegmens. START - címke. END START - a program vége és egy üzenet a fordítónak, hogy a program végrehajtását a START címkével kell kezdeni. Minden programnak tartalmaznia kell egy END direktívát a vég megjelölésére forráskód programokat. Az END direktívát követő összes sort figyelmen kívül hagyja.Az END direktíva után megadott címke közli a fordítóval annak a fő modulnak a nevét, amelytől a program végrehajtása kezdődik. Ha a program egy modult tartalmaz, akkor az END direktíva utáni címke elhagyható.

Assembly nyelvi fordítók Fordító - program ill technikai eszközökkel, amely az egyik programozási nyelven megjelenített programot a célnyelv programjává, úgynevezett objektumkódká alakítja. A gépi utasítás-mnemonika támogatása mellett minden fordító rendelkezik saját direktívákkal és makróeszközökkel, amelyek gyakran semmi mással nem kompatibilisek. Az assembly nyelvi fordítók fő típusai: MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler) - egy szabadon terjesztett többmenetes assembler, amelyet Tomasz Gryshtar (lengyel) írt, NASM (Netwide Assembler) - egy ingyenes Az Intel x Architecture 86 összeszerelőjét Simon Tatham hozta létre Julian Hallal, és jelenleg a Source egy kis fejlesztői csapata fejleszti. Kohó. háló.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="Program fordítása a Microsoft Visual Studio 2005-ben 1) Hozzon létre egy projektet a Fájl->Új- >Projekt menü És"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В дополнительных опциях мастера проекта указать “Empty Project”.!}

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="A program fordítása Microsoft Visual Studio 2005-ben 2) A projektfában (View->Solution Explorer) add hozzá"> Трансляция программы в Microsoft Visual Studio 2005 2) В дереве проекта (View->Solution Explorer) добавить файл, в котором будет содержаться текст программы: Source. Files->Add->New. Item.!}

A program lefordítása Microsoft Visual Studio 2005-be 3) Válassza ki a Code C++ fájltípust, de adja meg a nevet kiterjesztéssel. asm:

A program lefordítása Microsoft Visual Studio 2005-be 5) Állítsa be a fordító paramétereit. Kattintson a jobb gombbal az Egyéni összeépítési szabályok menüre a projektfájlban...

Fordítsa le a programot Microsoft Visual Studio 2005-be, és a megjelenő ablakban válassza a Microsoft Macro Assembler lehetőséget.

A program fordítása a Microsoft Visual Studio 2005-ben Ellenőrizze a hello fájl jobb gombjával. asm projektfáját a Tulajdonságok menüben, és telepítse az Általános->Eszköz: Microsoft Macro Assembler programot.

Src="https://present5.com/presentation/-29367016_63610977/image-22.jpg" alt="A program fordítása a Microsoft Visual Studio 2005-ben 6) Fordítsa le a fájlt a Build->Build hello kiválasztásával. prj."> Трансляция программы в Microsoft Visual Studio 2005 6) Откомпилировать файл, выбрав Build->Build hello. prj. 7) Запустить программу, нажав F 5 или выбрав меню Debug->Start Debugging.!}

Programozás Windows operációs rendszerben A Windows operációs rendszer programozása API-függvények (Application Program Interface, azaz szoftveralkalmazási felület) használatán alapul. Számuk eléri a 2000-et. A Windows program nagyrészt ilyen hívásokból áll. Minden interakció vele külső eszközökés az operációs rendszer erőforrásai általában az ilyen funkciókon keresztül jelentkeznek. Műtőszoba Windows rendszer lapos memória modellt használ. Bármely memóriacella címét egy 32 bites regiszter tartalma határozza meg. A Windowshoz 3 féle programstruktúra létezik: dialógus (a főablak dialógus), konzolos vagy ablak nélküli struktúra, klasszikus struktúra (ablakos, keret).

Hívás Windows funkciók API A súgófájlban bármely API függvény függvénynév típusként jelenik meg (FA 1, FA 2, FA 3) Típus – visszatérési érték típusa; FAx – a formális argumentumok listája a megjelenésük sorrendjében, például int Message. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Ez a funkcióüzenetet és kilépési gombot (vagy gombokat) tartalmazó ablakot jelenít meg. A paraméterek jelentése: h. A Wnd annak az ablaknak a leírója, amelyben az üzenetablak megjelenik, lp. Szöveg – az ablakban megjelenő szöveg, lp. Felirat - szöveg az ablak címében, u. Típus - ablak típusa; különösen a kilépési gombok számát határozhatja meg.

A Windows API int Message függvények meghívása. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Szinte minden API függvényparaméter valójában 32 bites egész szám: a HWND egy 32 bites egész szám, az LPCTSTR egy karakterlánc 32 bites mutatója, az UINT pedig egy 32 bites egész szám. Az "A" utótag gyakran hozzáadódik a függvény nevéhez, hogy a függvény újabb verzióira lépjen.

A Windows API int Message függvények meghívása. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); MASM használatakor @N N karaktert kell hozzáadnia a név végéhez – ez az a bájtok száma, amelyet az átadott argumentumok a veremben foglalnak el. A Win 32 API-függvényeknél ez a szám az n argumentumok számának 4-gyel szorozva (bájt minden argumentumban): N=4*n. Egy függvény meghívásához használja az assembler CALL utasítást. Ebben az esetben az összes függvényargumentum átadásra kerül a veremen keresztül (PUSH parancs). Az argumentumok átadási iránya: BALRA JOBBRA - LENTről FEL. Először az u argumentum kerül a verembe. Típus. A megadott függvény hívása így fog kinézni: HÍVÁS Üzenet. Doboz. A@16

A Windows API int Message függvények meghívása. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Type); Bármely API-függvény végrehajtásának eredménye általában egy egész szám, amelyet az EAX regiszterben ad vissza. Az OFFSET direktíva egy "eltolódást egy szegmensben", vagy magas szintű nyelvi kifejezésekre lefordítva egy "mutatót" egy sor elejére. Az EQU direktíva, mint a #define az SI-ben, egy állandót határoz meg. Az EXTERN direktíva közli a fordítóval, hogy a függvény vagy az azonosító kívül esik ezen a modulon.

Példa a „Helló mindenkinek!” programra . 686 P. MODELL LAKÁS, STDCALL. STACK 4096. DATA MB_OK EQU 0 STR 1 DB "Az első programom", 0 STR 2 DB "Helló mindenkinek!", 0 HW DD ? KÜLSŐ Üzenet. Doboz. A@16: KÖZEL. KÓD START: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Üzenet. Doboz. A@16 RET END START

Az INVOKE direktíva A MASM nyelvi fordító lehetővé teszi a függvényhívások egyszerűsítését is egy makróeszköz segítségével - az INVOKE direktíva: INVOKE függvény, paraméter1, paraméter2, ... Nem kell @16-ot hozzáadni a függvényhíváshoz; A paraméterek pontosan abban a sorrendben vannak felírva, ahogyan a függvényleírásban szerepelnek. A fordító makró segítségével a paraméterek a verembe kerülnek. Az INVOKE direktíva használatához rendelkeznie kell a PROTO direktívát használó függvény prototípusának leírásával a következő formában: Üzenet. Doboz. A PROTO: DWORD, : DWORD Ha egy program sok Win 32 API függvényt használ, akkor célszerű az include direktíva használata C: masm 32includeuser 32. inc

2.5 témakör A processzorprogramozás alapjai

A program hosszának növekedésével egyre nehezebb megjegyezni a különféle műveletek kódjait. A mnemonika nyújt némi segítséget ebben a tekintetben.

A szimbolikus parancskódoló nyelvet hívják szerelő.

Assembly nyelv egy olyan nyelv, amelyben minden megnyilatkozás pontosan egy gépi parancsnak felel meg.

Szerelés program konvertálása assembly nyelvről, azaz program gépi nyelven történő elkészítése a műveletek szimbolikus neveinek gépi kódokkal, a szimbolikus címek abszolút vagy relatív számokkal való helyettesítésével, valamint könyvtári programok beépítése és szimbolikus utasítássorozatok generálása meghatározott paraméterek megadásával. mikrocsapatokban. Ez a program általában a ROM-ban található, vagy valamilyen külső adathordozóról kerül a RAM-ba.

Az Assembly nyelvnek számos jellemzője van, amelyek megkülönböztetik a magas szintű nyelvektől:

1. Ez egy-egy megfeleltetés az assembly nyelvi utasítások és a gépi utasítások között.

2. Az assembly nyelvű programozó hozzáfér a célgépen található összes objektumhoz és utasításhoz.

A programozás alapjainak megértése géporientált nyelveken hasznos:



A PC-architektúra jobb megértése és a számítógépek kompetensebb használata;

Alkalmazott problémák megoldására szolgáló programok algoritmusainak racionálisabb struktúráinak kidolgozása;

Lehetőség a .exe és .com kiterjesztésű, bármely magas szintű nyelvről lefordított futtatható programok megtekintésére és javítására a forrásprogramok elvesztése esetén (a DEBUG program hibakeresőjében a megadott programok meghívásával és a megjelenítés összeállításban történő visszafordításával nyelv);

Programok összeállítása a legkritikusabb problémák megoldására (a géporientált nyelven írt program általában hatékonyabb - a magas szintű nyelvekről fordítás eredményeként kapott programok 30-60 százalékával rövidebb és gyorsabb)

A főprogramban szereplő eljárások külön töredékek formájában való megvalósítása abban az esetben, ha nem hajthatók végre sem a használt magas szintű nyelven, sem az operációs rendszer szolgáltatási eljárásaival.

Egy assembly nyelvű program csak egy számítógépcsaládon futhat, míg egy magas szintű nyelven írt program különböző gépeken futhat.

Az assembly nyelv ábécéje ASCII karakterekből áll.

A számok csak egész számok. Vannak:

A bináris számok B betűvel végződnek;

D betűvel végződő decimális számok;

A hexadecimális számok H betűvel végződnek.

RAM, nyilvántartások, adatszolgáltatás

Egy bizonyos MP-sorozathoz egyedi programozási nyelvet használnak - assembly nyelvet.

Az Assembly nyelv egy köztes helyet foglal el a gépi kódok és a magas szintű nyelvek között. Ezen a nyelven egyszerűbb a programozás. Egy assembly nyelvű program hatékonyabban használja ki egy adott gép (pontosabban egy MP) képességeit, mint egy magas szintű nyelvű program (ami programozónak egyszerűbb, mint assemblernek). Nézzük meg a géporientált nyelvek programozásának alapelveit az MP KR580VM80 assembly nyelvének példáján. A nyelven való programozáshoz általános módszertant használnak. A programok rögzítésének speciális technikai technikái a cél MP architektúrájának és parancsrendszerének jellemzőihez kapcsolódnak.

Szoftver modell MP KR580VM80 alapú mikroprocesszoros rendszer

Az MPS szoftvermodellje az 1. ábra szerint

MP portok memória

S Z A.C. P C

1. kép

A programozó szemszögéből nézve az MP KR580VM80 a következő, program által elérhető regiszterekkel rendelkezik.

A– 8 bites akkumulátor regiszter. Ez az MP fő nyilvántartása. Az ALU-ban végrehajtott bármely művelet magában foglalja a feldolgozandó operandusok egyikének az akkumulátorba helyezését. Az ALU-ban végzett műveletek eredményét általában az A-ban tárolják.

B, C, D, E, H, L– 8 bites általános célú regiszterek (GPR). Belső memória MP. A feldolgozott információk, valamint a művelet eredményeinek tárolására szolgál. A 16 bites szavak feldolgozása során a regiszterek BC, DE, HL párokat alkotnak, és a kettős regisztert az első betűnek nevezik - B, D, H. Egy regiszterpárban a legmagasabb az első regiszter. A H és L regiszterek egy speciális tulajdonsággal rendelkeznek, mind az adatok tárolására, mind a RAM cellák 16 bites címeinek tárolására szolgálnak.

FL– zászlóregiszter (jelregiszter) 8 bites regiszter, amelyben az MP-ben végzett aritmetikai és logikai műveletek eredményének öt előjele van tárolva. FL formátum a kép szerint

C bit (CY - carry) - átvitel, 1-re állítva, ha a bájt magas sorrendjéből átvitel történt az aritmetikai műveletek végrehajtásakor.

Bit P (paritás) – paritás, 1-re állítva, ha az eredmény bitjeiben az egyesek száma páros.

Az AC számjegy egy további átvitel, amelyet arra terveztek, hogy az eredmény alacsony rendű tetradjából származó átviteli értéket tárolja.

Z bit (nulla) – állítsa 1-re, ha a művelet eredménye 0.

S bit (előjel) – 1-re van állítva, ha az eredmény negatív, és 0-ra, ha az eredmény pozitív.

SP– veremmutató, egy 16 bites regiszter, amely annak a memóriacellának a címét tárolja, ahová a verembe utoljára beillesztett bájtot írták.

RS– programszámláló (programszámláló), egy 16 bites regiszter, amely a következő végrehajtandó utasítás címének tárolására szolgál. A programszámláló tartalma automatikusan 1-gyel növekszik közvetlenül a következő utasításbyte lekérése után.

A 0000Н – 07FF cím kezdeti memóriaterületén van vezérlő programés bemutató programok. Ez a ROM terület.

0800 – 0AFF - címterület a vizsgált műsorok rögzítéséhez. (RAM).

0В00 – 0ВВ0 - címterület adatíráshoz. (RAM).

0ВВ0 – a verem kezdőcíme. (RAM).

A verem a RAM egy speciálisan szervezett területe, amely adatok vagy címek ideiglenes tárolására szolgál. A verembe utoljára írt szám jelenik meg először. A veremmutató az utolsó veremcella címét tárolja, amelybe az információ került. Egy szubrutin meghívásakor a főprogram visszatérési címe automatikusan eltárolódik a veremben. Általános szabály, hogy minden szubrutin elején a végrehajtásában részt vevő összes regiszter tartalma a verembe kerül, az alprogram végén pedig visszaáll a veremből.

Az assembly nyelv adatformátuma és parancsszerkezete

Az MP KR580VM80 memóriája egy bájtoknak nevezett 8 bites szavakból álló tömb, minden bájtnak saját 16 bites címe van, amely meghatározza a memóriacellák sorrendjében elfoglalt helyét. Az MP 65536 bájt memóriát tud megcímezni, ami a ROM-ban és a RAM-ban is megtalálható.

Adatformátum

Az adatok a memóriában 8 bites szavakként tárolódnak:

D7 D6 D5 D4 D3 D2 D1 D0

A legkisebb jelentőségű bit a 0, a legjelentősebb bit a 7. bit.

Egy parancsot a formátuma, azaz a számára lefoglalt bitek száma jellemzi, amelyek bájtonként vannak felosztva bizonyos funkcionális mezőkre.

Parancs formátum

Az MP KR580VM80 parancsok egy, két vagy három bájtos formátumúak. A többbájtos parancsokat szomszédos nyelveken kell elhelyezni. A parancs formátuma a végrehajtott művelet sajátosságaitól függ.

A parancs első bájtja a műveleti kódot tartalmazza mnemonikus formában.

Meghatározza a parancsformátumot és azokat a műveleteket, amelyeket az MP-nek végre kell hajtania az adatokon annak végrehajtása során, valamint a címzési módot, valamint információkat tartalmazhat az adatok helyéről is.

A második és harmadik bájt tartalmazhat adatokat, amelyeken műveleteket hajtanak végre, vagy címeket, amelyek jelzik az adatok helyét. Azokat az adatokat, amelyeken a műveleteket végrehajtják, operandusoknak nevezzük.

Egybájtos parancsformátum a 2. ábra szerint

4. ábra

Az assembly nyelvi parancsokban a műveleti kódnak van egy lerövidített formája az angol szavak írására - ez egy mnemonikus jelölés. A mnemonika (a görög mnemonikus szóból - a memorizálás művészete) megkönnyíti a parancsok emlékezését funkcionális céljuk alapján.

A végrehajtás előtt a forrásprogramot egy assembler nevű fordítóprogrammal lefordítják a kódkombinációk nyelvére - gépi nyelvre, ebben a formában az MP memóriájába kerül, majd a parancs végrehajtása során kerül felhasználásra.


Megszólítási módszerek

Minden operandus kódot (bemeneti és kimeneti) el kell helyezni valahol. Elhelyezhetők az MP belső regisztereiben (a legkényelmesebb és gyors opció). A rendszermemóriában találhatók (a leggyakoribb lehetőség). Végül az I/O eszközökben is elhelyezhetők (a legritkább eset). Az operandusok helyét az utasításkód határozza meg. Létezik különböző módszerek, amellyel az utasításkód meg tudja határozni, hogy hova vegyük a bemeneti operandust és hova helyezzük a kimeneti operandust. Ezeket a módszereket címzési módszereknek nevezzük.

Az MP KR580VM80 esetében a következő címzési módszerek léteznek:

Közvetlen;

Regisztráció;

Közvetett;

Halmozott.

Közvetlen A címzés feltételezi, hogy a (bemeneti) operandus közvetlenül az utasításkód után található a memóriában. Az operandus általában egy állandó, amelyet el kell küldeni valahova, hozzá kell adni valamihez stb. az adatok a parancs második vagy második és harmadik bájtjában találhatók, az adatok alsó bájtja pedig a parancs második bájtjában, és a magas bájt a harmadik parancsbájtban.

Egyenes (más néven abszolút) címzés feltételezi, hogy az operandus (bemenet vagy kimenet) azon a címen található a memóriában, amelynek kódja közvetlenül az utasításkód után található a programon belül. Három bájtos parancsokban használatos.

Regisztráció A címzés feltételezi, hogy az operandus (bemenet vagy kimenet) az MP belső regiszterében van. Egybájtos parancsokban használatos

Közvetett Az (implicit) címzés azt feltételezi, hogy az MP belső regisztere nem magát az operandust, hanem a címét tartalmazza a memóriában.

Kazal A címzés feltételezi, hogy a parancs nem tartalmaz címet. Memóriacellák címzése a 16 bites SP regiszter (veremmutató) tartalmával.

Parancsrendszer

Az MP parancsrendszer azon elemi műveletek teljes listája, amelyeket az MP képes végrehajtani. Az ezekkel a parancsokkal vezérelt MP egyszerű műveleteket hajt végre, például elemi aritmetikai és logikai műveleteket, adatátvitelt, két érték összehasonlítását stb. Az MP KR580VM80 parancsainak száma 78 (244 módosítást figyelembe véve).

A következő parancscsoportokat különböztetjük meg:

Adatátvitel;

Számtan;

Összerakós játékaik;

Ugrás parancsok;

Bemeneti/kimeneti, vezérlési és verem parancsok.


Parancsok leírásánál és programok összeállításánál használt szimbólumok és rövidítések

Szimbólum Csökkentés
CÍM 16 bites cím
ADAT 8 bites adat
ADATOK 16 16 bites adat
KIKÖTŐ 8 bites I/O eszköz címe
BYTE 2 A parancs második bájtja
Bájt 3 A parancs harmadik bájtja
R, R1, R2 Az egyik regiszter: A, B, C, D, E, H, L
R.P. Az egyik regiszterpár: B - a BC párt adja meg; D - egy DE párt határoz meg; H – a HL-párt határozza meg
RH A pár első regisztrációja
R.L. A pár második regisztere
Λ Logikai szorzás
V Logikus kiegészítés
Kiegészítés modulo two
M Memóriacella, amelynek címe a HL regiszterpár tartalmát határozza meg, azaz M = (HL)



Top