Kako podesiti pametne telefone i računare. Informativni portal
  • Dom
  • Windows 10
  • Razmišljanja o programiranju na asemblerskom jeziku. Zaroniti u asembler

Razmišljanja o programiranju na asemblerskom jeziku. Zaroniti u asembler

Danas postoji ogroman broj programskih jezika visokog nivoa. S obzirom na njihovu pozadinu, programiranje na jeziku niskog nivoa - asembleru - može na prvi pogled izgledati kao nešto zastarjelo i iracionalno. Međutim, samo se čini da jeste. Treba priznati da je asembler zapravo jezik procesora, što znači da se od njega ne može izostati sve dok procesori postoje. Glavne prednosti programiranja u asemblerskom jeziku su maksimalna brzina i minimalna veličina rezultirajućih programa.

Nedostaci su često samo zbog tendencije modernog tržišta da preferira količinu nad kvalitetom. Moderni računari mogu lako da se nose sa zbrkom komandi funkcija visokog nivoa, a ako nije lako - nadogradite hardver svoje mašine! Ovo je zakon komercijalnog programiranja. Ako je riječ o programiranju za dušu, onda će kompaktan i okretan program napisan na asembleru ostaviti mnogo ugodniji utisak od visokorazvijenog gromada, opterećenog gomilom nepotrebnih operacija. Postoji mišljenje da samo nekolicina odabranih može programirati na asembleru. To nije istina. Naravno, talentovani asemblerski programeri se mogu računati na jednu ruku, ali to je slučaj u gotovo svim oblastima ljudske aktivnosti. Nema toliko asova vozača, ali će svi moći da nauče da voze auto - postojala bi želja. Nakon čitanja ove serije članaka, nećete postati jaki hakeri. Međutim, dobićete pregled i naučiti jednostavne načine programiranja u asemblerskom jeziku za Windows koristeći njegove ugrađene funkcije i makro instrukcije kompajlera. Naravno, da biste savladali Windows programiranje, morate imati Windows vještine i iskustvo. U početku nećete mnogo razumjeti, ali nemojte se obeshrabriti zbog toga i čitajte dalje: vremenom će sve doći na svoje mjesto.

Dakle, da bismo započeli programiranje, trebat će nam barem kompajler. Kompajler je program koji prevodi izvorni kod koji je napisao programer u mašinski kod koji može izvršiti procesor. Većina tutorijala na asembleru fokusira se na korištenje paketa MASM32 (Microsoft Macro Assembler). Ali ja ću vas, u obliku raznolikosti i iz niza drugih razloga, upoznati sa mladim kompajlerom koji brzo stiče popularnost FASM (Flat Assembler). Ovaj kompajler je prilično jednostavan za instalaciju i korištenje, kompaktan je i brz, ima bogatu i prostranu makro sintaksu koja vam omogućava automatizaciju mnogih rutinskih zadataka. Njegovu najnoviju verziju možete preuzeti sa web stranice odabirom flat asemblera za Windows. Da biste instalirali FASM, kreirajte folder, na primjer "D: \ FASM" i u njega raspakujte sadržaj preuzete zip arhive. Pokrenite FASMW.EXE i zatvorite bez ikakvih promjena. Usput, ako koristite standardni istraživač, a ekstenzija datoteke nije prikazana (na primjer, .EXE), preporučujem da pokrenete Alati -> Opcije mape -> Prikaži i poništite izbor u polju za potvrdu Sakrij ekstenzije za registrovane tipove datoteka. Nakon prvog pokretanja kompajlera, u našoj fascikli bi se trebala pojaviti konfiguracijska datoteka - FASMW.INI. Otvorite ga standardnom notesom i dodajte 3 reda na samom dnu:

Fasminc = D: \ FASM \ INCLUDE
Uključi = D: \ FASM \ INCLUDE

Ako ste raspakirali FASM na drugu lokaciju, zamijenite "D: \ FASM \" svojom vlastitom putanjom. Sačuvajte i zatvorite FASMW.INI. Gledajući unaprijed, ukratko ću objasniti kako ćemo koristiti kompajler:
1. Napišemo tekst programa, ili otvorimo prethodno napisani tekst sačuvan u .asm datoteci, ili kombinacijom zalijepimo tekst programa iz međuspremnika.
2. Pritisnite F9 za kompajliranje i pokretanje programa ili Ctrl + F9 samo za kompajliranje. Ako tekst programa još nije sačuvan, kompajler će od vas tražiti da ga sačuvate pre kompilacije.
3. Ako je program pokrenut, testiramo ga na ispravan rad, ako nije, tražimo greške od kojih će nam najgrublje kompajler ukazati ili suptilno nagovijestiti.
E, sada možemo započeti dugo očekivanu praksu. Pokrećemo naš FASMW.EXE i u njega ukucavamo kod našeg prvog programa:

Uključite "% fasminc% / win32ax.inc"

Podaci
Natpis db "Moj prvi program.", 0
Tekst db "Zdravo svima!", 0

Kod
početak:

pozovite ExitProcess, 0

Kliknite na Run -> Run ili F9 na tastaturi. U prozoru za spremanje navedite naziv datoteke i folder za spremanje. Preporučljivo je da se naviknete na spremanje svakog programa u posebnu mapu kako se ne biste zbunili u budućnosti, kada svaki program može imati gomilu datoteka: slike, ikone, muziku itd. Ako kompajler generiše grešku, pažljivo proverite red koji je naveo - možda ste propustili zarez ili razmak. Također morate biti svjesni da je kompajler osjetljiv na velika i mala slova, tako da se podaci i podaci tretiraju kao dvije različite instrukcije. Ako ste sve uradili ispravno, rezultat će biti najjednostavniji MessageBox (slika 1). Hajde sada da shvatimo šta smo napisali u tekstu programa. U prvom redu, sa direktivom uključivanja, uključili smo veliki tekst iz nekoliko datoteka u naš program. Sjećate se, prilikom instalacije smo napisali 3 reda u FASM ini-datoteci? Sada% fasminc% u tekstu programa znači D: \ FASM \ INCLUDE ili putanju koju ste naveli. Direktiva uključivanja, takoreći, ubacuje tekst iz druge datoteke na navedenu lokaciju. Otvorite datoteku WIN32AX.INC u folderu include koristeći notepad ili u samoj fasmi i uvjerite se da smo automatski uključili (prikačili) u naš program tekst iz win32a.inc, macro / if.inc, hrpa nerazumljivog (još ) makro instrukcije i uobičajeni skup biblioteka Windows funkcija. Zauzvrat, svaka od uključenih datoteka može sadržavati još nekoliko uključenih datoteka, a ovaj lanac može ići izvan horizonta. Uz pomoć uključenih fajlova organizujemo neku vrstu jezika visokog nivoa: kako bismo izbegli rutinu ručnog opisivanja svake funkcije, povezujemo čitave biblioteke za opisivanje standardnih Windows funkcija. Da li je sve ovo zaista potrebno za tako mali program? Ne, ovo je nešto kao "džentlmenski set za sve prilike". Pravi hakeri, naravno, ne povezuju sve, ali mi samo učimo, pa je ovo prvi put oprostivo.

Zatim smo odredili odjeljak podataka - .data. U ovoj sekciji deklariramo dvije varijable - Caption i Text. Ovo nisu posebne naredbe, tako da se njihova imena mogu mijenjati kako želite, čak i ako su a i b, samo bez razmaka, a ne na ruskom. Pa, ne možete pozvati varijable sa rezerviranim riječima, na primjer, kod ili podaci, ali možete kodirati_ ili data1. Naredba db znači "definiraj bajt". Naravno, sav ovaj tekst neće stati u jedan bajt, jer svaki pojedinačni znak zauzima cijeli bajt. Ali u ovom slučaju, ovom naredbom definiramo samo varijablu pokazivača. Sadržat će adresu na kojoj je pohranjen prvi znak niza. Tekst niza je naveden u navodnicima, a navodnici se, po želji, mogu postaviti i "takav" i "takav" - samo ako je početni navodnik isti kao krajnji. Nula iza zareza dodaje nulti bajt na kraj niza, koji označava kraj niza (null-terminator). Pokušajte da uklonite ovu nulu zajedno sa zarezom u prvom redu i vidite šta ćete dobiti. U drugom redu u ovom konkretnom primjeru možete učiniti bez nule (uklanjamo je zajedno sa zarezom - inače će kompajler ukazati na grešku), ali to će funkcionirati samo zato što u našem primjeru sljedeći odjeljak počinje odmah nakon drugog liniju, a kompajler će automatski uneti gomilu nula koje poravnavaju prethodni odeljak. Općenito, nule na kraju redova teksta su obavezne! Sljedeći odjeljak je dio izvršnog programskog koda - .code. Na početku sekcije nalazi se početak: oznaka. To znači da će sa ovog mjesta naš program početi da se izvršava. Prva naredba je pozivanje makroinstrukcije. Poziva Windows ugrađeni MessageBox API. API funkcije (interfejs za programiranje aplikacije) uvelike pojednostavljuju rad u operativnom sistemu. Nekako tražimo od operativnog sistema da izvrši neku standardnu ​​radnju, a on izvrši i po završetku nam vrati rezultat obavljenog posla. Nakon imena funkcije slijede njeni parametri, odvojeni zarezima. Funkcija MessageBox ima sljedeće parametre:

1. parametar mora sadržavati ručku prozora vlasnika. Ručica je nešto poput ličnog broja koji operativni sistem izdaje svakom objektu (procesu, prozoru, itd.). 0 u našem primjeru znači da prozor nema vlasnika, on je sam po sebi i ne ovisi o drugim prozorima.
2. parametar je pokazivač na adresu prvog slova teksta poruke, koji se završava gore navedenim nultim terminatorom. Da bismo jasno razumjeli da je ovo samo adresa, pomaknimo ovu adresu za 2 bajta desno u pozivu funkcije: pozovite MessageBox, 0, Text + 2, Caption, MB_OK i uvjerite se da će sada tekst biti prikazan bez prva dva slova .
3. - adresni pokazivač prvog slova zaglavlja poruke.
4. - stil poruke. Listu ovih stilova možete pronaći, na primjer, u INCLUDE \ EQUATES \ USER32.INC. Da biste to učinili, bolje je da koristite pretragu u Notepadu da brzo pronađete MB_OK i ostalo. Tu, nažalost, nema opisa, ali iz naziva stila obično se može pogoditi njegova svrha. Inače, svi ovi stilovi se mogu zamijeniti brojem koji označava jedan stil ili njihovu kombinaciju, na primjer: MB_OK + MB_ICONEXCLAMATION. USER32.INC sadrži heksadecimalne vrijednosti. Možete ih koristiti u ovom obliku ili ih pretvoriti u decimale u inženjerskom modu standardnog Windows kalkulatora. Ako niste upoznati sa brojevnim sistemima i ne znate po čemu se decimalni razlikuje od heksadecimalnog, onda imate 2 izlaza: ili da se upoznate s ovom materijom na internetu / u udžbeniku / pitate prijatelja, ili ostavite ovaj poduhvat dok ne bude bolje puta i pokušajte bez ovih informacija. Ovdje neću davati čak ni kratke informacije o brojevnim sistemima s obzirom na to da je i bez mene o njima napisan ogroman broj članaka i stranica bilo kojeg zamislivog nivoa.

Vratimo se našim ovnovima. Neki stilovi se ne mogu koristiti istovremeno - na primjer, MB_OKCANCEL i MB_YESNO. Razlog je taj što će zbir njihovih numeričkih vrijednosti (1 + 4 = 5) odgovarati vrijednosti drugog stila - MB_RETRYCANCEL. Sada eksperimentirajte s parametrima funkcije kako biste materijal učinili praktičnijim i idemo dalje. Funkcija MessageBox pauzira izvršavanje programa i čeka na radnju korisnika. Po završetku, funkcija vraća rezultat radnje korisnika u program, a program nastavlja da radi. Poziv funkcije ExitProcess završava proces našeg programa. Ova funkcija ima samo jedan parametar, izlazni kod. Obično, ako program izlazi normalno, ovaj kod je nula. Da biste bolje razumjeli zadnji red našeg koda - .end start - pažljivo proučite ekvivalentni kod: format PE GUI 4.0

uključiti "% fasminc% / win32a.inc"

odjeljak ".data" podaci čitljivi i pisani

Natpis db "Naš prvi program.", 0
Tekst db "FASM asembler je lak!", 0

odjeljak ".code" kod čitljiv izvršni
početak:
pozovite MessageBox, 0, Text, Caption, MB_OK
pozovite ExitProcess, 0

odjeljak ".idata" uvoz podataka čitljiv za pisanje
biblioteka KERNEL32, "KERNEL32.DLL", \
USER32, "USER32.DLL"

uvoz KERNEL32, \
ExitProcess, "ExitProcess"

uvoz USER32, \
MessageBox, "MessageBoxA"

Za kompajler je gotovo identičan prethodnom primjeru, ali za nas ovaj tekst izgleda kao drugačiji program. Posebno sam citirao ovaj drugi primjer kako biste na samom početku dobili ideju o korištenju makroinstrukcija i od sada, prelazeći s jedne povezane datoteke na drugu, samostalno došli do pravog koda programa skrivenog pod velom makroa. Pokušajmo otkriti razlike. Prva stvar, ne baš upadljiva, ali vrijedna posebne pažnje, jeste da se na tekst programa povezujemo ne win32ax, već samo win32a. Napustili smo veliki skup i ograničili se na mali. Pokušaćemo da ne povezujemo sve po redu sa win32ax, iako nam je za sada još potrebno nešto od toga. Stoga, prema makroima iz win32ax, ručno pišemo neke definicije. Na primjer, makro iz win32ax datoteke:
makro .data (odjeljak ".data" podaci čitljivi i pisani)

u vrijeme kompajliranja, automatski zamjenjuje.data sa odjeljkom ".data" podaci čitljivi i pisani. Pošto ovaj makro nismo uključili u tekst programa, moramo sami napisati detaljnu definiciju sekcije. Analogno, u drugom primjeru možete pronaći razloge za ostale izmjene u tekstu programa. Makroi vam pomažu da izbjegnete gnjavažu oko pisanja velikih programa. Stoga se samo treba odmah naviknuti na njih, a zavoleti ćete ih tek kasnije =). Pokušajte sami otkriti razlike između prvog i drugog primjera, koristeći tekst makroa koji se koriste u win32ax. Reći ću samo da u navodnicima možete navesti bilo koje drugo ime za sekciju podataka ili kod - na primjer: odjeljak "virus" kod čitljiv izvršni. Ovo je samo naziv odjeljka i nije naredba ili operator. Ako sve shvatite, onda već možete napisati svoj vlastiti virus. Vjerujte mi, vrlo je lako. Samo promijenite naslov i tijelo posta:
Naslov db "Opasni virus.", 0

Tekst db "Zdravo, ja sam posebno opasan trojanski virus i širim se internetom.", 13, \
"Pošto moj autor ne može pisati štetne viruse, morate mi pomoći." 13, \
"Učinite sljedeće:", 13, \
"1.Obriši direktorije C: \ Windows i C: \ Programske datoteke na vašem disku", 13, \
"2.Pošalji ovaj fajl svima koje poznaješ", 13, \
"Unaprijed hvala.", 0

Broj 13 je kod za povratni karakter za Microsoft sisteme. Znak \ se koristi u FASM sintaksi za kombinovanje više redova u jedan, bez njega bi bio predugačak red koji ide od ivice ekrana. Na primjer, možemo napisati start:, ili možemo napisati st \
ar \
t:

Kompajler neće primijetiti razliku između prve i druge opcije.
Pa, da povećate hrabrost u našem "virusu", možete zamijeniti MB_OK sa MB_ICONHAND ili jednostavno brojem 16. U ovom slučaju, prozor će imati stil poruke o grešci i proizvesti će impresivniji učinak na žrtvu " infekcija" (slika 2).

To je sve za danas. Želim vam uspjeh i vidimo se uskoro!
Svi navedeni primjeri su testirani da ispravno rade na Windows XP-u i najvjerovatnije će raditi na drugim verzijama Windowsa, međutim ne garantujem da će ispravno raditi na vašem računaru. Izvorne kodove programa možete pronaći na forumu.

Programiranje na asemblerskom jeziku

Ovaj dio kursa pokriva osnove programiranja asemblerskog jezika za Win32 arhitekturu.

Svi procesi u mašini na najnižem, hardverskom nivou pokreću se samo naredbama (uputstvima) mašinskog jezika. Asemblerski jezik je simbolički prikaz mašinskog jezika... Asembler vam omogućava da pišete kratke i brze programe. Međutim, ovaj proces je izuzetno dugotrajan. Da biste napisali najefikasniji program, potrebno vam je dobro poznavanje karakteristika komandi asemblerskog jezika, pažnja i tačnost. Dakle, u stvarnosti se uglavnom programi pišu na asembleru, što bi trebalo da obezbedi efikasan rad sa hardverom. Također, dijelovi programa koji su kritični u smislu vremena izvršavanja ili potrošnje memorije napisani su u asemblerskom jeziku. Nakon toga, oni se formatiraju kao potprogrami i kombinuju sa kodom jezika visokog nivoa.

1. Registri

Registri su posebne memorijske lokacije koje se nalaze direktno u procesoru. Rad sa registrima je mnogo brži od rada sa memorijskim ćelijama; stoga se registri aktivno koriste i u programima asemblerskog jezika i od strane kompajlera jezika visokog nivoa.

Registri se mogu podijeliti na opšti registri,komandni pokazivač,registar zastavica i registre segmenta.

1.1. Registri opšte namjene

TO Registri opšte namene su grupa od 8 registara koji se mogu koristiti u programu asemblerskog jezika. Svi registri su veličine 32 bita i mogu se podijeliti na 2 ili više dijelova.

Kao što možete vidjeti sa slike, ESI, EDI, ESP i EBP registri vam omogućavaju pristup nižim 16 bitova po nazivima SI, DI, SP i BP, redom, dok vam registri EAX, EBX, ECX i EDX omogućavaju za pristup nižim 16 bitova (po imenima AX , BX, CX i DX) i dva najmanje značajna bajta odvojeno (po imenima AH / AL, BH / BL, CH / CL i

Nazivi registara potiču od njihove namjene:

EAX / AX / AH / AL (akumulatorski registar) - akumulator;

EBX / BX / BH / BL (bazni registar) - bazni registar;

ECX / CX / CH / CL (registar brojača) - brojač;

EDX / DX / DH / DL (registar podataka) - registar podataka;

ESI / SI (registar izvornog indeksa) - izvorni indeks;

EDI / DI (destination index register) - indeks prijemnika (receiver);

ESP / SP (stack pointer register) - registar pokazivača steka;

EBP / BP (registar baznog pokazivača) - registar osnovnog pokazivača okvira steka.

Uprkos postojećoj specijalizaciji, svi registri se mogu koristiti u bilo kojoj operaciji mašine. Međutim, treba uzeti u obzir činjenicu da neke komande rade samo sa određenim registrima. Na primjer, upute za množenje i dijeljenje koriste EAX i EDX registre za pohranjivanje originalnih podataka i rezultata operacije. Instrukcije za kontrolu ciklusa koriste ECX registar kao brojač ciklusa.

Još jedna nijansa je korištenje registara kao baze, tj. adrese skladištenja RAM-a. Kao osnovni registri mogu se koristiti bilo koji registri, ali je poželjno koristiti EBX, ESI, EDI ili EBP registre. U ovom slučaju, veličina mašinske instrukcije je obično manja.

Nažalost, broj registara je katastrofalno mali, i često je teško pronaći najbolji način za njihovo korištenje.

1.2. Komandni pokazivač

EIP registar ( komandni pokazivač) sadrži pomak sljedeće naredbe koja će se izvršiti. Ovaj registar nije direktno dostupan programatoru, ali se učitavanje i mijenjanje njegove vrijednosti vrši raznim kontrolnim naredbama koje uključuju naredbe za uslovne i bezuslovne skokove, pozive procedura i povratak iz procedura.

1.3. Registar zastave

Zastavica je bit koji uzima vrijednost 1 ("zastava je postavljena") ako je određeni uslov ispunjen, i vrijednost 0 ("zastava je obrisana") u suprotnom. Procesor ima registar zastavica koji sadrži skup zastavica koje odražavaju trenutno stanje procesora.

Oznaka

Ime

Prenesena zastava

Rezervirano

Zastava pariteta

Rezervirano

Pomoćna zastava za nošenje

Helper

Rezervirano

Zero flag

Sign flag

Tracer flag

Oznaka za omogućavanje prekida

Resolution flag

Zastava je usmjerena

Repo flag

I/O nivo privilegija

Nivo na

Zastava ugniježđena

Rezervirano

Zastava oživljena

Virtual-8086 Mode

Virtuelni način rada

Provjerite vas

Zastava virtuelnog prekida

Virtuelno

Virtualni prekid na čekanju

Na čekanju

Provjeravam

Rezervirano

Zastavice CF, DF i IF mogu se mijenjati direktno u registru zastavica korištenjem posebnih instrukcija (na primjer, CLD da obrišete zastavicu smjera), ali ne postoje instrukcije koje vam omogućavaju da pristupite registru zastavica kao običnom registru. Međutim, možete uštedjeti

registruju zastavice na stog ili AH registar i vraćaju registar zastavice iz njih koristeći instrukcije LAHF, SAHF, PUSHF, PUSHFD, POPF i POPFD.

1.3.1. Statusne zastavice

Statusne zastavice (bitovi 0, 2, 4, 6, 7 i 11) odražavaju rezultat izvršavanja aritmetičkih instrukcija kao što su ADD, SUB, MUL, DIV.

Oznaka za nošenje CF se postavlja pri prijenosu iz MSB-a/posuđivanja u MSB i ukazuje na prisustvo preljeva u neoznačenoj cjelobrojnoj aritmetici. Također se koristi u dugoj aritmetici.

Oznaka parnosti PF se postavlja ako najmanji značajan bajt rezultata sadrži paran broj bitova od jednog. U početku je ova zastavica bila namijenjena za korištenje u komunikacijskim programima: prilikom prijenosa podataka preko komunikacijskih linija, paritetni bit se mogao prenijeti i za kontrolu, a upute za provjeru zastavice parnosti olakšavale su provjeru integriteta podataka.

Pomoćnik nosi zastavu AF je postavljen na izvođenje bita 3rd rezultat / pozajmica u 3rd rezultat bit. Ova zastava je namijenjena za upotrebu u binarni decimalni (binarni decimalni, BCD) aritmetika.

ZF nula zastavica se postavlja ako je rezultat nula.

Oznaka predznaka SF jednaka je vrijednosti najznačajnijeg bita rezultata, a to je bit predznaka u aritmetici sa predznakom.

Overflow flag OF se postavlja ako je cjelobrojni rezultat predugačak da stane u ciljni operand (registar ili memorijska lokacija). Ova zastavica označava prisustvo prelivanja u aritmetici cijelih brojeva sa predznakom.

Od navedenih zastavica, samo se CF zastavica može promijeniti direktno korištenjem STC, CLC i CMC instrukcija.

Statusne zastavice dozvoljavaju istoj aritmetičkoj instrukciji da proizvede tri različita tipa rezultata: neoznačeni, predpisani i binarno-decimalni (BCD) cijeli broj. Ako se rezultat smatra nepotpisanim brojem, tada CF zastavica ukazuje na uvjet prelivanja (prenesite ili posudite), za potpisani rezultat prijenos ili posudba prikazuje OF zastavicu, a za BCD rezultat prijenos/posuđivanje pokazuje AF zastava. SF zastavica odražava znak potpisanog rezultata, ZF zastavica odražava i nepotpisani i potpisani nulti rezultat.

U dugoj cjelobrojnoj aritmetici, CF zastavica se koristi zajedno sa instrukcijama za sabiranje i prenošenje (ADC) i oduzimanje i pozajmljivanje (SBB) za propagiranje prijenosa ili posuđivanja od jednog izračunatog bita dugog broja na drugi.

Instrukcije

uslovno

tranzicija Jcc (prijelaz

stanje cc), SETcc (set

značenje

rezultat bajta

zavisnosti

pojmovi cc), LOOPcc (organizacija

i CMOVcc (uslovno

kopija)

koristiti

jedan ili više

statusne zastavice za provjeru stanja. Na primjer, JLE (skok ako je manji ili jednak) skok instrukcija testira uvjet “ZF = 1 ili SF ≠ OF”.

PF zastavica je uvedena radi kompatibilnosti sa drugim arhitekturama mikroprocesora i rijetko se koristi za namjeravanu svrhu. Češće se koristi u kombinaciji sa drugim statusnim zastavicama u aritmetici s pokretnim zarezom: instrukcije za poređenje (FCOM, FCOMP, itd.) u matematičkom koprocesoru postavljaju zastavice uslova C0, C1, C2 i C3 u njemu, a ove zastavice može se kopirati u registar zastava. Da biste to učinili, preporučuje se korištenje FSTSW AX instrukcije za spremanje riječi statusa koprocesora u AX registru i SAHF instrukcije za naknadno kopiranje sadržaja AH registra u donjih 8 bitova registra zastavica, sa C0 unos zastavice CF, C2 u PF i C3 u ZF. Oznaka C2 se postavlja, na primjer, u slučaju neuporedivih argumenata (NaN ili nepodržani format) u FUCOM naredbi za poređenje.

1.3.2. Kontrolna zastavica

Zastava smjera DF (bit 10 u registru zastavice) kontroliše niz instrukcija (MOVS, CMPS, SCAS, LODS i STOS) - postavljanje zastavice prisiljava adrese na smanjenje (procesne linije sa visokih adresa na niske), nuliranje uzrokuje povećanje adresa. STD i CLD izjave postavljaju i brišu DF zastavicu, respektivno.

1.3.3. Sistemske zastavice i IOPL polje

Sistemske zastavice i IOPL polje kontroliraju operativno okruženje i nisu namijenjeni za korištenje od strane aplikacijskih programa.

Oznaka za omogućavanje prekida IF - Brisanje ove zastavice onemogućava odgovaranje na maskirane zahtjeve za prekid.

Trace flag TF - postavljanje ove zastavice omogućava otklanjanje grešaka korak po korak, kada se nakon svakog izvršenja

instrukcije, program se prekida i poziva se poseban rukovalac prekida.

IOPL polje označava nivo I/O prioriteta izvršnog programa ili zadatka: da bi program ili zadatak izvršio I/O instrukcije ili promijenio IF zastavicu, njegov trenutni nivo prioriteta (CPL) mora biti ≤ IOPL.

Zastavica ugniježđenja zadataka NT - Ova zastavica se postavlja kada je trenutni zadatak "ugniježđen" u drugi, prekinuti zadatak, a segment stanja TSS-a trenutnog zadatka daje povratnu informaciju TSS-u prethodnog zadatka. NT zastavicu provjerava IRET instrukcija kako bi se utvrdilo da li je tip povratka među-zadatak ili intra-zadatak.

Zastavica za nastavak RF se koristi za maskiranje grešaka u otklanjanju grešaka.

VM - postavljanje ove zastavice u zaštićeni način uzrokuje prelazak na virtuelni 8086 način rada.

Zastavica za provjeru poravnanja AC - postavljanje ove zastavice zajedno sa AM bitom u CR0 registru omogućava kontrolu poravnanja operanda tokom pristupa memoriji: pristup neusklađenom operandu izaziva izuzetak.

VIF - virtuelna kopija IF zastave; koristi se zajedno sa VIP zastavom.

VIP - postavljeno da ukaže na prisustvo prekida na čekanju.

ID - mogućnost programske promjene ove zastavice u registru zastavice ukazuje na podršku za CPUID instrukciju.

1.4. Segmentni registri

Procesor ima 6 takozvanih segmentnih registara: CS, DS, SS, ES, FS i GS. Njihovo postojanje je zbog specifičnosti organizacije i upotrebe RAM-a.

16-bitni registri su mogli adresirati samo 64 KB RAM-a, što očigledno nije dovoljno za manje-više pristojan program. Stoga je memorija dodijeljena programu u obliku nekoliko segmenata, veličine 64 KB. U ovom slučaju, apsolutne adrese su bile 20-bitne, što je omogućilo adresiranje već 1 MB RAM-a. Postavlja se pitanje - kako pohraniti 20-bitne adrese sa 16-bitnim registrima? Da bi se riješio ovaj problem, adresa je prekinuta na osnovu ofseta. Baza je adresa početka segmenta, a pomak je broj bajta unutar segmenta. Ograničenje je nametnuto na adresu početka segmenta - morala je biti višekratnik od 16. U ovom slučaju, posljednja 4 bita bila su jednaka 0 i nisu pohranjena, već implicirana. Tako su dobijena dva 16-bitna dijela adrese. Za dobijanje

apsolutne adrese, četiri nula bita su dodana bazi, a rezultirajuća vrijednost je dodana sa pomakom.

Segmentni registri su korišteni za pohranjivanje adrese početka kodnog segmenta (CS - segment koda), segmenta podataka (DS - segment podataka) i segmenta steka (SS - segment steka). ES, FS i GS registri su dodati kasnije. Postojalo je nekoliko memorijskih modela, od kojih je svaki podrazumijevao dodjelu jednog ili više segmenata koda i jednog ili više segmenata podataka programu: mali, mali, srednji, kompaktni, veliki i ogromni. Postojale su određene konvencije za instrukcije asemblerskog jezika: adrese za skokove su segmentirane pomoću CS registra, pristupi podacima segmentirani su DS registrom, a pozivi steka segmentirani su pomoću SS registra. Ako je programu dodijeljeno nekoliko segmenata za kod ili podatke, tada su vrijednosti u CS i DS registrima morale biti promijenjene da bi se pristupilo drugom segmentu. Postojali su takozvani "bliski" i "daleki" prelazi. Ako je komanda, na koju je trebalo izvršiti skok, bila u istom segmentu, tada je za skok bilo dovoljno promijeniti samo vrijednost IP registra. Takva tranzicija nazvana je "bliska". Ako je naredba na koju je trebalo izvršiti skok bila u drugom segmentu, tada je za skok bilo potrebno promijeniti i vrijednost CS registra i vrijednost IP registra. Ova tranzicija se zvala daljinski i trajala je duže.

32-bitni registri vam omogućavaju adresiranje 4 GB memorije, što je već dovoljno za bilo koji program. Windows pokreće svaki Win32 program u zasebnom virtuelnom prostoru. To znači da će svaki Win32 program imati 4 GB adresnog prostora, ali to ne znači da svaki program ima 4 GB fizičke memorije, već samo da program može pristupiti bilo kojoj adresi unutar ovog raspona. A Windows će učiniti sve što je potrebno da memorija kojoj program pristupa "postoji". Naravno, program se mora pridržavati utvrđenih pravila

Windows, u suprotnom dolazi do greške General Protection Fault.

Pod Win32 arhitekturom, nije bilo potrebe za razdvajanjem adrese na baznu i ofsetnu, kao ni za memorijskim modelima. u 32-

se koriste drugačije1. Ranije je bilo potrebno povezati pojedine dijelove programa sa jednim ili drugim segmentnim registrom i sačuvati/vratiti DS registar pri prelasku u drugi segment podataka, ili eksplicitno segmentirati podatke u drugom registru. Sa 32-bitnom arhitekturom to više nije potrebno, au najjednostavnijem slučaju možete zaboraviti na segmentne registre.

1.5. Korištenje steka

Svaki program ima područje memorije koje se zove stek. Stog se koristi za prosljeđivanje parametara procedurama i pohranjivanje lokalnih podataka za procedure. Kao što znate, stek je područje memorije, pri radu s kojim se moraju poštovati određena pravila, a to su: podaci koji su prvi ušli u stog, odatle se zadnji preuzimaju. S druge strane, ako je malo memorije dodijeljeno programu, onda nema fizičkih ograničenja za čitanje i pisanje. Kako se ova dva sukobljena principa uklapaju zajedno?

Pretpostavimo da imamo funkciju f1 koja poziva funkciju f2, a funkcija f2, zauzvrat, poziva funkciju f3. Kada se pozove funkcija f1, dodjeljuje joj se određeno mjesto na stogu za lokalne podatke. Ovaj prostor se dodjeljuje oduzimanjem od ESP registra vrijednosti jednake veličini potrebne memorije. Minimalna veličina dodijeljene memorije je 4 bajta, tj. čak i ako je proceduri potreban 1 bajt, trebalo bi da zauzme 4 bajta.

Funkcija f1 izvodi neke radnje i zatim poziva

funkcija f2 poziva funkciju f3, koja također dodjeljuje prostor na steku. Funkcija f3 ne poziva nijednu drugu funkciju i po završetku svog rada mora osloboditi prostor na steku dodavanjem u ESP registar vrijednost koja je oduzeta kada je funkcija pozvana. Ako funkcija f3 ne vrati vrijednost ESP registra, tada funkcija f2, nastavljajući s radom, neće pristupiti svojim podacima, jer Ona traži

što je bilo prije nego što je pozvana.

Dakle, na nivou procedura potrebno je poštovati pravila za rad sa stekom – procedura koja je zadnja zauzela prostor na steku mora prvo da ga oslobodi. Ako se ovo pravilo ne poštuje, program neće raditi ispravno. Ali svaka procedura može pristupiti svom vlastitom području steka na proizvoljan način. Ako bismo bili primorani da poštujemo pravila za rad sa stekom unutar svake procedure, morali bismo da prenosimo podatke iz steka u drugu memorijsku oblast, a to bi bilo izuzetno nezgodno i izuzetno bi usporilo izvršavanje programa.

Svaki program ima područje podataka u kojem se nalaze globalne varijable. Zašto se lokalni podaci pohranjuju na stog? Ovo se radi kako bi se smanjila količina memorije koju zauzima program. Ako je program dosljedno poziva nekoliko procedura, tada će u svakom trenutku vremena prostor biti dodijeljen samo za podatke jedne procedure, budući da stek je zauzet i otpušten. Područje podataka postoji sve vrijeme dok se program izvodi. Ako bi se lokalni podaci nalazili u području podataka, bilo bi potrebno dodijeliti prostor za lokalne podatke za sve programske procedure.

Lokalni podaci se ne inicijaliziraju automatski. Ako u gornjem primjeru funkcija f2 nakon funkcije f3 pozove funkciju f4, tada će funkcija f4 zauzeti mjesto na steku koje je prethodno zauzimala funkcija f3, tako da će funkcija f4 naslijediti funkciju f3. Stoga, svaka procedura mora voditi računa o inicijalizaciji svojih lokalnih podataka.

2. Osnovni koncepti asemblerskog jezika

2.1. Identifikatori

Koncept identifikatora u asemblerskom jeziku se ne razlikuje od koncepta identifikatora u drugim jezicima. Možete koristiti latinična slova, brojeve i znakove _. ? @ $, gdje tačka može biti samo prvi znak identifikatora. Velika i mala slova se smatraju ekvivalentnim.

2.2. Cijeli brojevi

V U programima asemblerskog jezika, cijeli brojevi se mogu pisati u binarnim, oktalnim, decimalnim i heksadecimalnim sistemima. Za postavljanje brojnog sistema na kraju broja

Nakon mnogo godina što sam radila nešto a da to nisam pogodila, odlučila sam da se vratim osnovama. Za programiranje. Opet, s obzirom na mnoštvo "modernih napretka" u ovoj oblasti, bilo je teško odrediti šta zapravo nedostaje, šta poduzeti da bude i ugodno i korisno. Probavši po malo mnogo toga, odlučio sam da se vratim na mjesto gdje sam bio vučen od prvih dana poznanstva sa kompjuterom (čak i sa kopijom kreacije Sir Sinclair-a) - do programiranja na asembleru. Naime, svojevremeno sam prilično dobro poznavao Assembler (u ovom slučaju govorim o x86), ali skoro 15 godina nisam ništa napisao u njemu. Dakle, ovo je svojevrsni povratak "razmetnog sina".
Ali ovdje je čekalo prvo razočarenje. Knjige, priručnici i druge referentne knjige o asembleru koje se nalaze na internetu, na moju veliku žalost, sadrže minimum informacija o tome kako programirati na asembleru, zašto je to tako i šta daje.

Primjer iz drugog kraja

Ako uzmemo boks kao primjer, onda svi takvi priručnici uče kako se izvodi udarac, kreće se stojeći na podu, ali ono što boks radi je apsolutno odsutno - boks, a ne "legalno udaranje". Odnosno, kombinirani rad, posebnosti korištenja prstena, obrambene akcije, taktička struktura bitke i, štoviše, strategija bitke uopće se ne razmatraju. Naučili su čovjeka da pogodi "krušku" i odmah u ring. Ovo je fundamentalno pogrešno. Ali tako su strukturirani gotovo svi "udžbenici" i "priručnici" o programiranju u asembleru.


Međutim, normalne knjige bi trebalo da budu, najverovatnije ispod planine "šljake" jednostavno ih nisam našao. Stoga, prije nego što dopunimo znanje globalnim opisom arhitekture, mnemotehnikom i svim vrstama trikova "kako zaslijepiti figu iz dva prsta", pristupimo pitanju programiranja u asembleru sa "ideološke" tačke gledišta.

Idila?

Mala napomena, dalje u tekstu će se koristiti klasifikacija koja se razlikuje od trenutno raširene. Međutim, to nije razlog za "sporove o boji istine", već je u ovom obliku lakše objasniti autorsko stajalište o programiranju.

Dakle, danas je, čini se, nastupila era sreće za programere. Ogroman izbor sredstava za sve prilike i želje. Postoje milioni "okvira" / "šablona" / "šablona" / "biblioteka" i hiljade alata za "olakšavanje" programiranja, stotine jezika i dijalekata, desetine metodologija i različitih pristupa programiranju. Uzmi - ne želim. Ali nije "uzeto". I nije poenta u religioznim uvjerenjima, već u činjenici da sve to izgleda kao pokušaj da se pojede nešto neukusno. Uz želju i marljivost, možete se tome prilagoditi, naravno. Ali, vraćajući se programiranju, u većini predloženog, tehnička ljepota nije vidljiva - vidljivo je samo puno "štaka". Kao rezultat toga, kada se koriste ova “dostignuća”, umjesto fascinantnih pejzaža, umjesto fascinantnih pejzaža, ispod “kista umjetnika” izbija čvrsta “apstrakcija” ili popularni printovi – ako imate sreće. Da li su većina programera takvi mediokriteti, neznalice i imaju problema na nivou genetike? Ne, ne mislim tako. Pa šta je razlog?
Danas postoji mnogo ideja i načina programiranja. Hajde da razmotrimo "najmodernije" od njih.

  • Imperativno programiranje – u ovom pristupu programer postavlja redoslijed radnji koje vode do rješenja problema. Zasniva se na podjeli programa na dijelove koji izvode logički nezavisne operacije (moduli, funkcije, procedure). Ali za razliku od kucanog pristupa (vidi dolje), ovdje postoji važna karakteristika - odsustvo varijabli "kucanja". Drugim riječima, koncept "tip varijable" je odsutan; umjesto toga, koristi se razumijevanje da vrijednosti iste varijable mogu imati drugačiji tip. Živopisni predstavnici ovog pristupa su Basic, REXX, MUMPS.
  • Tipizirano programiranje je modifikacija imperativnog programiranja, kada programer i sistem ograničavaju moguće vrijednosti varijabli. Najpoznatiji jezici su Pascal, C.
  • Funkcionalno programiranje je više matematički način rješavanja problema, kada se rješenje sastoji u "konstruiranju" hijerarhije funkcija (i, shodno tome, kreiranju onih koje nedostaju), što dovodi do rješenja problema. Kao primjeri: Lisp, Forth.
  • Automatsko programiranje je pristup u kojem programer gradi model/mrežu koja se sastoji od objekata/izvršnih elemenata koji razmjenjuju poruke, i mijenjaju/čuvaju svoje unutrašnje "stanje" i sposobni su za interakciju sa vanjskim svijetom. Drugim riječima, ovo je ono što se obično naziva "objektno programiranje" (ne objektno orijentirano). Ova metoda programiranja uvedena je u Smalltalk.
Ali šta je sa mnogim drugim jezicima? Po pravilu, to su već "mutanti". Na primjer, mješavina kucanog i automatskog pristupa dovela je do "programiranja usmjerenog na objekte".

Kao što vidite, svaki od pristupa (čak i bez uzimanja u obzir ograničenja specifičnih implementacija) nameće svoja ograničenja na samu tehniku ​​programiranja. Ali drugačije ne može biti. Nažalost, ova ograničenja su često umjetno stvorena kako bi "ideja ostala čista". Kao rezultat toga, programer mora "pervertirati" prvobitno pronađeno rješenje u formu koja na neki način odgovara ideologiji jezika koji se koristi ili korištenog "šablona". Ovo čak i bez uzimanja u obzir novonastalih tehnika i metoda dizajna i razvoja.

Čini se da smo dok programiramo na asembleru, slobodni da radimo sve kako želimo i kako nam hardver dozvoljava. Ali čim poželimo da koristimo „generički drajver“ za bilo koju vrstu opreme, prinuđeni smo da promenimo slobodu „kreativnosti“ za propisane (standardizovane) pristupe i načine korišćenja drajvera. Čim nam je bila potrebna prilika da iskoristimo razvoj drugih kolega ili im damo priliku da isto urade sa plodovima našeg rada, primorani smo da promenimo slobodu izbora interakcije između delova programa za neke dogovorene/ standardizovane načine.

Dakle, "sloboda" zbog koje ljudi često žure na asembleru često se pokaže kao "mit". I tome (razumijevanju ograničenja i načina njihovog organiziranja), po mom mišljenju, treba posvetiti veću pažnju. Programer mora razumjeti razlog za uvedena ograničenja i, što asembler razlikuje od mnogih jezika visokog nivoa, biti u mogućnosti da ih promijeni ako se ukaže potreba. Međutim, sada je programer asemblera primoran da trpi ograničenja koja nameću jezici visokog nivoa, jer u njima nema "šargarepe" koja je dostupna programerima. S jedne strane, operativni sistemi pružaju mnoge već implementirane funkcije, postoje gotove biblioteke i još mnogo toga. Ali načini njihovog korištenja su, takoreći, implementirani bez uzimanja u obzir njihovog pozivanja iz programa napisanih na asembleru, ili čak općenito suprotno logici programiranja za x86 arhitekturu. Kao rezultat toga, danas je programiranje u asembleru sa pozivima funkcijama OS-a ili vanjskim bibliotekama jezika visokog nivoa "strah" i "horor".

Što dalje u šumu, to je gušće

Dakle, shvatili smo da iako je asembler vrlo jednostavan, morate biti u mogućnosti da ga koristite. A glavna konzistentnost je potreba za interakcijom sa runtime okruženjem u kojem je naš program pokrenut. Ako programeri na jezicima visokog nivoa već imaju pristup potrebnim bibliotekama, funkcijama, potprogramima u mnogim prilikama i imaju pristup načinima interakcije sa vanjskim svijetom, u obliku koji je u skladu s idejom jezika, onda asemblerski programer mora da gazi kroz gustiš svih vrsta prepreka postavljenih na praznom prostoru. Kada pogledate šta jezici visokog nivoa generišu tokom kompilacije, stiče se utisak da oni koji su pisali kompajlere ili nemaju pojma kako radi procesor sa x86 arhitekturom, "ili jedan od dva" (q).

Pa počnimo redom. Programiranje je, prije svega, inženjersko, odnosno naučno stvaralaštvo usmjereno na efikasno (u smislu pouzdanosti, korištenja raspoloživih resursa, vremena implementacije i lakoće upotrebe) rješavanja praktičnih problema. A u srcu svakog inženjerstva je sistemski pristup. Odnosno, nijedno rješenje se ne može smatrati nekom vrstom "nerazdvojive" crne kutije, koja funkcionira u potpunom i idealnom vakuumu.

Još jedan primjer iz drugog područja

Proizvodnja kamiona u Sjedinjenim Državama može se navesti kao živopisan primjer sistematskog pristupa. U ovom slučaju, proizvođač kamiona je jednostavno proizvođač rama i kabine + montažer konstruktora. Sve ostalo (motor, mjenjač, ​​ovjes, električna oprema itd.) preuzimamo prema želji kupca. Jedan kupac je htio sebi nabaviti Kenworth sa motorom od Detroit Diesel, Fuller manuelnim mjenjačem, lisnatim ovjesom od neke Dana - molim. Prijatelju ovog kupca je bio potreban isti model Kenworth, ali sa matičnim Paccar motorom, Allison automatskim mjenjačem i zračnim ovjesom drugog proizvođača - lako! A to rade svi proizvođači kamiona u SAD-u. Odnosno, kamion je sistem u kojem se svaki modul može zamijeniti drugim iste namjene i besprijekorno spojiti sa postojećim. Štoviše, način povezivanja modula napravljen je s maksimalnom dostupnom svestranošću i praktičnošću daljeg proširenja funkcionalnosti. To je ono čemu inženjer treba da teži.

Nažalost, moraćemo da živimo sa onim što imamo, ali u budućnosti to treba izbegavati. Dakle, program je, u stvari, skup modula (nije bitno kako se zovu i kako se "ponašaju"), sastavljanjem kojih postižemo rješenje zadatka. Radi efikasnosti, veoma je poželjno da se ovi moduli mogu ponovo koristiti. I ne samo da ga koristite po svaku cijenu, već ga koristite na zgodan način. I tu nas čeka još jedno neprijatno "iznenađenje". Većina jezika visokog nivoa radi na takvim strukturnim jedinicama kao što su "funkcija" i "procedura". I, kao način rješavanja njih, koristi se "prenošenje parametara". Ovo je sasvim logično i tu se ne postavljaju pitanja. Ali kao i uvijek, „nije važno šta se radi – važno je kako se radi“ (c). I tu počinje ono najneshvatljivije. Danas postoje 3 uobičajena načina organizacije prijenosa parametara: cdecl, stdcall, fastcall... Dakle, nijedna od ovih metoda nije "nativna" za x86. Štaviše, svi su manjkavi sa stanovišta proširenja funkcionalnosti pozvanih potprograma. Odnosno, povećanjem broja proslijeđenih parametara, primorani smo promijeniti sve pozivne točke ove funkcije/potprograma, ili proizvesti novi potprogram sa sličnom funkcionalnošću, koji će biti pozvan na malo drugačiji način.

Gore navedene metode prosljeđivanja parametara funkcionišu relativno dobro na procesorima sa 2 odvojena steka (stek podataka i adresni/kontrolni stog) i naprednim instrukcijama za manipulaciju stekom (barem pristup indeksu elementima steka). Ali kada programirate na x86, prvo morate biti izopačeni prilikom prosljeđivanja / primanja parametara, a zatim zapamtiti da ih "strukturno" uklonite iz steka. Usput pokušavam pogoditi / izračunati maksimalnu dubinu steka. Podsjetimo da je x86 (16/32 bitni način rada) procesor koji ima:

  • specijalizovani registri (RON-ovi su registri opšte namene - kao takvi nedostaju: to jest, ne možemo pomnožiti sadržaj GS registra sa vrednošću iz EDI jednom komandom i dobiti rezultat u paru EDX: ECX, ili podeliti vrednost iz EDI: ESI registarski par u registar sadržaja EAX);
  • nekoliko registara;
  • jedan stog;
  • memorijska lokacija ne daje nikakve informacije o vrsti vrijednosti koja je tamo pohranjena.
Drugim riječima, tehnike programiranja koje se koriste za procesore s velikim registarskim fajlom, podršku za više nezavisnih stekova, itd. uglavnom nije primjenjivo na x86 programiranje.

Sljedeća karakteristika interakcije sa gotovim modulima napisanim na "jezicima visokog nivoa" je "borba" sa "tipovima varijabli". S jedne strane, razlog za pojavu tipova varijabli je jasan - programer zna koje vrijednosti se koriste unutar njegovog potprograma / modula. Na osnovu ovoga, čini se sasvim logičnim da postavljanjem tipa vrijednosti varijable možemo "pojednostaviti" pisanje programa postavljanjem kontrole tipova/ograničenja vrijednosti na jezički prevodilac. Ali čak i tada je beba izbačena sa vodom. Jer bilo koji program nije napisan za generiranje sfernih konja u vakuumu, već za praktičan rad s korisničkim podacima. Odnosno, očigledno kršenje sistemskog pristupa - kao da su programeri jezika visokog nivoa razmatrali svoje sisteme bez uzimanja u obzir interakcije sa vanjskim svijetom. Kao rezultat toga, kada programira na kucanom jeziku, programer mora predvidjeti sve moguće tipove "netačnih" ulaznih podataka i tražiti načine da zaobiđe nejasnoće. I tu na scenu stupaju monstruozni sistemi za podršku regularnih izraza, rukovanje izuzecima, potpisi metoda/procedura za različite tipove vrijednosti i druge generacije štaka.

Kao što je gore spomenuto, za arhitekturu x86, sama vrijednost pohranjena na memorijskoj lokaciji nema nikakav tip. Programer asemblerskog jezika je privilegovan i odgovornost za određivanje načina na koji se postupa s ovom vrijednošću. A kako odrediti vrstu vrijednosti i kako je obraditi - postoji mnogo opcija koje možete izabrati. Ali, da još jednom naglasimo, svi se tiču ​​samo vrijednosti koje dobija od korisnika. Kao što su programeri kucanih jezika ispravno primijetili, tipovi vrijednosti internih i servisnih varijabli gotovo su uvijek unaprijed poznati.

Čini se da je ovaj razlog (izopačeno prosljeđivanje parametara modulima napisanim na jezicima visokog nivoa i potreba za striktnim praćenjem tipova parametara proslijeđenih istim modulima) glavni, zbog čega je programiranje u asembleru nerazumno teško . A većina radije razumije džunglu "jezika visokog nivoa" da bi iskoristila ono što su drugi već razvili, nego da pati, ubacujem iste "standardne" štake da ispravim ono što nisu uradili. A rijetki asemblerski prevodilac nekako "istovaruje" programera iz ove rutine.

šta da radim?

Preliminarni zaključci, uzimajući u obzir 15-let break u programiranju asemblera.
Prvo, o modulima ili dijelovima programa. U opštem slučaju, vredi istaći dve vrste izvršnih jedinica programa u asemblerskom jeziku - "operacija" i "potprogram".
  • “Operacija” je modul koji izvodi “atomsku” akciju i ne zahtijeva mnogo parametara za njeno izvođenje (na primjer, operacija brisanja cijelog ekrana ili operacija izračunavanja medijane niza brojeva, itd.) .
  • "Podrutina" je funkcionalni modul koji zahtijeva puno ulaznih parametara (više od 2x-3x) za ispravno funkcioniranje.
I ovdje vrijedi procijeniti iskustvo imperativnih i funkcionalnih jezika. Dali su nam 2 vrijedna alata koja vrijedi koristiti: "strukturu podataka" (ili, na primjer, REXX - kompozitne / proširene varijable) i "promjenjivost podataka".

Također je korisno slijediti pravilo nepromjenjivosti – odnosno nepromjenjivosti proslijeđenih parametara. Potprogram ne može (ne bi trebao) mijenjati vrijednosti u strukturi koja mu je proslijeđena i rezultat se vraća ili u registrima (ne više od 2x-3x parametara), ili također u novoj, kreiranoj strukturi. Time smo oslobođeni potrebe da pravimo kopije struktura u slučaju "zaboravljene" promjene podataka od strane potprograma, te možemo koristiti već kreiranu strukturu u cijelosti ili njen glavni dio za pozivanje nekoliko potprograma koji rade sa istim/sličnim skup parametara. Štaviše, praktično „automatski“ dolazimo do sledećeg „funkcionalnog“ pravila – unutrašnje kontekstne nezavisnosti potprograma i operacija. Drugim riječima, do odvajanja stanja/podataka od metode/podrutine njihove obrade (za razliku od automatskog modela). U slučajevima paralelnog programiranja, kao i zajedničkog korišćenja jednog potprograma, oslobađamo se kako potrebe da se proizvede mnogo izvršnih konteksta i nadgleda njihovo „nepresecanje“, tako i stvaranja velikog broja instanci jednog potprograma sa različitim „stanjima“. “, u slučaju višestrukih poziva.

Što se tiče "vrsta" podataka, onda možete ili ostaviti "sve kako je", ili ne možete ponovo izmisliti točak i iskoristiti ono što programeri prevodilaca imperativnih jezika već dugo koriste - "identifikator tipa vrijednosti". Odnosno, analiziraju se svi podaci koji dolaze iz vanjskog svijeta i svakoj primljenoj vrijednosti dodjeljuje se identifikator obrađenog tipa (cijeli broj, plutajući zarez, upakovani BCD, kod karaktera, itd.) i veličina polja/vrijednosti. Posjedujući ove informacije, programer, s jedne strane, ne tjera korisnika u nepotrebno uzak okvir „pravila“ za unos vrijednosti, a s druge strane ima mogućnost izbora najefikasnijeg načina obrade korisničkih podataka. u procesu. Ali, ponoviću još jednom, ovo se odnosi samo na rad sa korisničkim podacima.

Ovo su bila opšta razmatranja za programiranje u asemblerskom jeziku, a ne vezana za dizajn, otklanjanje grešaka i rukovanje greškama. Nadam se da će OS programeri koji ih pišu od nule (a još više na asembleru) imati o čemu razmišljati i da će izabrati (čak i ako nisu gore opisani, ali bilo koje druge) načine da programiranje na asembleru učine sistematiziranijim, praktičnijim i prijatno, i neće slepo kopirati tuđe, često beznadežno "krive" opcije.

Assembler (Assembly) je programski jezik čiji koncepti odražavaju arhitekturu elektronskog računara. Asemblerski jezik je simbolički oblik pisanja mašinskog koda, čija upotreba pojednostavljuje pisanje mašinskih programa. Za isti računar mogu se razviti različiti asemblerski jezici. Za razliku od jezika visokog nivoa apstrakcije, u kojima su mnogi problemi implementacije algoritama skriveni od programera, asemblerski jezik je usko povezan sa skupom instrukcija mikroprocesora. Za idealan mikroprocesor čiji skup instrukcija tačno odgovara programskom jeziku, asembler generiše jedan mašinski kod za svaku naredbu u jeziku. U praksi, pravi mikroprocesori mogu zahtevati više mašinskih instrukcija da implementiraju jednu naredbu u jeziku.

Asemblerski jezik omogućava pristup registrima, specificirajući metode adresiranja i opisujući operacije u smislu instrukcija procesora. Asemblerski jezik može sadržati sredstva višeg nivoa apstrakcije: ugrađene i definisane makroe koji odgovaraju nekoliko mašinskih instrukcija, automatski izbor komandi u zavisnosti od tipa operanda, sredstva za opisivanje struktura podataka. Glavna prednost asemblerskog jezika je "blizina" procesoru koji je osnova računara koji koristi programer, a glavni nedostatak je premala podjela tipičnih operacija, što većina korisnika teško percipira. Međutim, asemblerski jezik je mnogo više odraz samog funkcionisanja računara nego bilo koji drugi jezik.

I iako su drajveri i operativni sistemi sada napisani na C, C je, sa svim svojim prednostima, jezik apstrakcije visokog nivoa koji skriva od programera razne suptilnosti i nijanse hardvera, a asembler je jezik apstrakcije niskog nivoa koji direktno odražava sve ove suptilnosti i nijanse.

Za uspješno korištenje asemblera potrebne su tri stvari:

  • poznavanje sintakse asemblerskog prevoditelja koji se koristi (na primjer, sintaksa MASM, FASM i GAS je različita), namjene direktiva asemblerskog jezika (operatori koje prevodilac obrađuje tokom prevođenja izvornog koda programa) ;
  • razumijevanje mašinskih instrukcija koje izvršava procesor dok program radi;
  • sposobnost rada sa uslugama koje pruža operativni sistem - u ovom slučaju to znači poznavanje Win32 API funkcija. Kada radi sa jezicima visokog nivoa, programer se često ne poziva direktno na sistemski API; on možda nije ni svjestan njegovog postojanja, budući da biblioteka jezika krije od programera specifične sistemske detalje. Na primjer, u Linuxu, Windowsu i bilo kojem drugom sistemu u C / C ++ programu, možete izbaciti niz na konzolu pomoću funkcije printf () ili cout streama, odnosno nema razlike za programera koji koristi ovih alata, pod kojim sistemom je program napravljen, iako će implementacija ovih funkcija biti različita u različitim sistemima, jer je API sistema veoma različit. Ali ako osoba piše na asembleru, više nema gotove funkcije kao što je printf (), u kojima je smislio kako da "komunicira" sa sistemom umjesto njega, i mora to sam učiniti.
Kao rezultat toga, ispostavlja se da pisanje čak i jednostavnog programa na asembleru zahtijeva vrlo veliku količinu predznanja - "prag ulaska" je ovdje mnogo veći nego za jezike visokog nivoa.

Optimalno možete smisliti program koji radi ispravno, što je brže moguće i koji zauzima što manje memorije. Štaviše, lako se čita i razume; lako se menja; njegovo stvaranje zahtijeva malo vremena i niske troškove. U idealnom slučaju, asemblerski jezik bi trebao imati skup karakteristika koje bi vam omogućile da dobijete programe koji zadovoljavaju što je više moguće od ovih kvaliteta.

Programi ili njihovi fragmenti su napisani na asemblerskom jeziku u slučajevima kada su kritično važni:

  • količina korišćene memorije (programi za učitavanje, ugrađeni softver, programi za mikrokontrolere i procesore sa ograničenim resursima, virusi, softverske zaštite itd.);
  • brzina (programi napisani na asembleru rade mnogo brže od analognih programa napisanih u programskim jezicima visokog nivoa apstrakcije. kao rezultat, program počinje da radi brže, ali gubi prenosivost i svestranost).
Osim toga, poznavanje asemblerskog jezika olakšava razumijevanje arhitekture računara i rada njegovog hardvera, nešto što znanje ne može dati jezici apstrakcije visokog nivoa(JAVU). Trenutno, većina programera razvija programe u okruženja brzog dizajna(Rapid Application Development) kada se svi potrebni elementi dizajna i upravljanja kreiraju pomoću gotovih vizuelnih komponenti. Ovo uvelike pojednostavljuje proces programiranja. Međutim, često se moramo suočiti sa situacijama kada je najmoćnije i najefikasnije funkcionisanje pojedinačnih softverskih modula moguće samo ako su napisani u asemblerskom jeziku (assembler inserti). Konkretno, u bilo kojem programu povezanom s izvršavanjem ponavljajućih cikličkih procedura, bilo da se radi o ciklusima matematičkih proračuna ili izlazu grafičkih slika, preporučljivo je grupirati operacije koje zahtijevaju najviše vremena u podmodule programirane u asemblerskom jeziku. Svi paketi savremenih programskih jezika visokog nivoa apstrakcije to dozvoljavaju, a rezultat je uvek značajno povećanje performansi programa.

Programski jezici visokog nivoa apstrakcije razvijeni su sa ciljem da se način pisanja programa što više približi uobičajenim oblicima pisanja za korisnike računara, posebno matematičkim izrazima, a takođe i da se ne uzimaju u obzir specifične tehničke karakteristike pojedinačnih računara u programima. Asemblerski jezik je razvijen uzimajući u obzir specifičnosti procesora, stoga, da biste ispravno napisali program na asemblerskom jeziku, općenito morate znati arhitekturu procesora korištenog računala. Međutim, imajući u vidu preovlađujuću distribuciju personalnih računara kompatibilnih sa PC i gotovih softverskih paketa za njih, ne treba razmišljati o tome, jer takve brige preuzimaju kompanije-programeri specijalizovanog i univerzalnog softvera.

2. O kompajlerima

Koji asembler je bolji?

Za x86-x64 procesor, postoji preko desetak različitih asemblerskih kompajlera dostupnih. Razlikuju se po različitim skupovima funkcija i sintaksi. Neki prevodioci su pogodniji za početnike, drugi za napredne programere. Neki kompajleri su prilično dobro dokumentovani, drugi nemaju nikakvu dokumentaciju. Za neke kompajlere razvijeni su mnogi primjeri programiranja. Postoje tutorijali i knjige napisane za neke asemblere koji detaljno ulaze u sintaksu, drugi nemaju ništa. Koji asembler je bolji?

S obzirom na brojne dijalekte asemblera za x86-x64 i ograničenu količinu vremena za njihovo proučavanje, ograničićemo se na kratak pregled sljedećih kompajlera: MASM, TASM, NASM, FASM, GoASM, Gas, RosAsm, HLA.

Koji operativni sistem biste željeli koristiti?

Ovo je prvo pitanje na koje biste trebali odgovoriti. Najbogatiji asembler neće vam pomoći ako nije dizajniran da radi sa operativnim sistemom koji planirate da koristite.
Windows DOS Linux BSD QNX MacOS radi na
Intel / AMD procesor
FASM x x x x
GAS x x x x x x
GoAsm x
HLA x x
MASM x x
NASM x x x x x x
RosAsm x
TASM x x

16-bitna podrška

Ako asembler podržava DOS, onda podržava i 16-bitne instrukcije. Svi asembleri pružaju mogućnost pisanja koda koji koristi 16-bitne operande. 16-bitna podrška znači da možete kreirati kod koji radi na 16-bitnom modelu razdijeljene memorije (nasuprot 32-bitnom modelu ravne memorije koji koristi većina modernih operativnih sistema).

64-bitna podrška

Sa izuzetkom TASM-a, za koji je Borland izgubio interesovanje sredinom 2000-ih, a koji ne podržava u potpunosti čak ni 32-bitne programe, svi ostali dijalekti podržavaju razvoj 64-bitnih aplikacija.

Prenosivost programa

Očigledno, nećete pisati x86-x64 asemblerski kod koji radi na nekom drugom procesoru. Međutim, čak i na jednom procesoru možete naići na probleme prenosivosti. Na primjer, ako namjeravate kompajlirati i koristiti svoje programe asemblerskog jezika pod različitim operativnim sistemima. NASM i FASM se mogu koristiti na operativnim sistemima koje podržavaju.

Da li namjeravate da napišete aplikaciju na asembleru, a zatim prenesete tu aplikaciju s jednog OS na drugi sa "rekompajliranim" izvornim kodom? Ovu funkciju podržava HLA dijalekt. Očekujete li da ćete moći kreirati Windows i Linux aplikacije u asembleru uz minimalan napor da to učinite? Iako, ako radite s jednim operativnim sistemom i apsolutno ne planirate raditi u bilo kojem drugom OS, onda vas ovaj problem ne brine.

Podrška za jezičke konstrukcije visokog nivoa

Neki asembleri obezbeđuju proširenu sintaksu koja obezbeđuje kontrolne strukture visokog nivoa specifične za jezik (kao što su IF, WHILE, FOR i tako dalje). Takve konstrukcije mogu olakšati učenje asemblera i pomoći vam da napišete čitljiviji kod. Neki asembleri imaju ugrađene "konstrukcije visokog nivoa" sa ograničenim mogućnostima. Drugi pružaju konstrukcije na makro nivou visokog nivoa.

Nijedan asembler vas ne prisiljava da koristite kontrolne strukture visokog nivoa ili tipove podataka ako više volite da radite na nivou kodiranja mašinskih instrukcija. Konstrukcije visokog nivoa su produžetak osnovnog mašinskog jezika koji možete koristiti ako vam odgovara.

Kvalitet dokumentacije

Upotrebljivost asemblera je direktno povezana sa kvalitetom njegove dokumentacije. S obzirom na količinu posla koji je utrošen na kreiranje asemblerskog dijalekta, autori kompajlera se gotovo ne trude da kreiraju dokumentaciju za ovaj dijalekt. Autori, proširujući svoj jezik, zaboravljaju da dokumentuju ova proširenja.

Sljedeća tabela opisuje kvalitet referentnog priručnika za asembler koji dolazi s proizvodom:

Dokumentacija Komentari (1)
FASM Dobro Autor većinu svog slobodnog vremena posvećuje razvoju inovativnog FASMG-a. Ipak, autor s vremena na vrijeme pruža podršku za FASM, ažurira priručnike i opisuje nove funkcije na vlastitom forumu. Dokumentacija je prilično dobra. Web stranica za dokumentaciju.
Gas
Loše
je slabo dokumentirana i dokumentacija je prilično "općenita". gas je asembler koji je dizajniran da olakša pisanje koda za različite procesore. Dokumentacija koja postoji uglavnom opisuje pseudo kodove i asemblerske direktive. U načinu rada "intel_syntax" praktično nema dokumentacije. Knjige koje koriste AT&T sintaksu: Programiranje od nule Jonathona Bartleta i Professional Assembly Language Richarda Bluma, Konstantina Boldysheva.
GoAsm
Slabo
Većina sintakse je pokrivena u priručniku, a iskusan korisnik će pronaći ono što traži. Mnogo tutorijala i objavljenih na sajtu (http://www.godevtool.com/). Nekoliko GoAsm tutorijala:
  • Patrick Ruiz priručnik
HLA
Čišćenje
HLA ima referentni priručnik od 500 stranica. Stranica sadrži desetine HLA članaka i dokumentacije.
MASM
Dobro
Microsoft je napisao značajnu količinu dokumentacije za MASM, postoji veliki broj referentnih knjiga napisanih za ovaj dijalekt.
NASM
Dobro
NASM autori pišu više softvera za ovaj dijalekt, ostavljajući ručno pisanje za kasnije. NASM postoji dugo, pa je nekoliko autora napisalo priručnik za NASM Jeffa Duntemanna „Jezik asemblera korak po korak: Programiranje sa Linuxom“, Jonathana Letoa „Pisanje korisnog programa sa NASM-om“, na ruskom postoji knjiga autora Stolyarov (web stranica A.V. Stolyarova).
RosAsm
Slabo
ne baš zanimljivi "online tutorijali".
TASM
Dobro
Borland je svojevremeno proizveo odlične referentne vodiče, a referentne vodiče su za TASM napisali entuzijasti autori koji nisu povezani s Borlandom. Ali Borland više ne podržava TASM, tako da je veći dio dokumentacije za TASM neštampan i postaje sve teže pronaći.

Udžbenici i nastavni materijali

Dokumentacija asemblerskog jezika je naravno veoma važna. Od još većeg interesa za početnike i druge koji uče asemblerski jezik (ili napredne karakteristike datog asemblerskog jezika) je dostupnost dokumentacije izvan referentnog priručnika za jezik. Većina ljudi želi vodič koji objašnjava kako programirati u asembleru koji čini više od samo obezbjeđivanja sintakse mašinskih instrukcija i očekuju da će čitaocu biti rečeno kako da kombinuje ove instrukcije za rešavanje problema u stvarnom svetu.

MASM je lider među ogromnom količinom knjiga koje opisuju kako programirati na ovom dijalektu. Postoje desetine knjiga koje koriste MASM kao asembler za podučavanje asemblera.

Većina MASM/TASM asemblerskih udžbenika i dalje podučava MS-DOS programiranje. Iako se postepeno pojavljuju tutorijali koji podučavaju programiranje u Windowsima i Linuxu.

Komentari (1)
FASM Nekoliko tutorijala koji opisuju FASM programiranje:
  • S.A. Norseev "Razvoj prozorskih aplikacija na FASM-u"
  • Ruslan Ablyazov "Programiranje u asembleru na platformi x86-64"
Gas
Vodič za korištenje AT&T sintakse
Vodič za Linux asembler za C programere
HLA
32-bitna verzija "The Art of Assembly Language Programming" (postoji u elektronskom i štampanom obliku), programiranje za Windows ili Linux
MASM
veliki broj knjiga o podučavanju DOS programiranja. Nema mnogo knjiga o Win32/64 programiranju Pirogov, Yurov, Zubkov, Flinov
NASM
mnoge knjige posvećene programiranju u DOS-u, Linuxu, Windows-u. Knjiga Jeffa Duntemana Assembly Language Step-by-Step: Programiranje sa Linuxom koristi NASM za Linux i DOS. Tutorijal Paula Cartera koristi NASM (DOS, Linux).
TASM
Kao i za MASM, veliki broj knjiga zasnovanih na DOS-u je napisan za TASM. Ali pošto Borland više ne podržava ovaj proizvod, prestali su pisati knjige o korištenju TASM-a. Tom Swann je napisao tutorijal o TASM-u sa nekoliko poglavlja o Windows programiranju.

3. Literatura i web resursi

Početnici

  1. Abel P. Jezik asemblera za IBM PC i programiranje. - M.: Viša škola, 1992.-- 447 str.
  2. Bradley D. Programiranje na asemblerskom jeziku za personalne računare iz IBM-a - M.: Radio i komunikacija, 1988. - 448 str.
  3. Galiseev G.V. Asembler IBM PC. Knjiga za samoučenje.: - M.: Izdavačka kuća "Williams", 2004. - 304 str.: ilustr.
  4. Dao L. Programiranje mikroprocesora 8088 .-- M.: Mir, 1988.-- 357 str.
  5. Žukov A.V., Avdjuhin A.A. Asembler. - SPb.: BHV-Peterburg, 2003.-- 448 str.: ilustr.
  6. Zubkov S.V., asembler za DOS, Windows i UNIX. - M.: DMK Press, 2000.-- 608 str.: ilustr. (Serija "Za programere").
  7. Irwin K. Asemblerski jezik za Intel procesore, 4. izdanje .: trans. sa engleskog - M.: Izdavačka kuća "Williams", 2005. - 912 str.: ilustr. - Paralelno. tit. engleski (vidi i najnovije 7. izdanje u originalu)
  8. Norton P., Souhe D. Asemblerski jezik za IBM PC - M.: Computer, 1992. - 352 str.
  9. Pil'shchikov V.N. Programiranje u IBM PC asemblerskom jeziku - M.: DIALOG-MEPhI, 1994–2014 288 str.
  10. Sklyarov I.S. Učenje asemblera za 7 dana www.sklyaroff.ru

Napredno

  1. Kaspersky K. Osnove hakovanja. Umetnost rastavljanja. - M.: SOLON-Press, 2004.448 str. - (Serija "Kodokopatel")
  2. Kaspersky K. Tehnika za otklanjanje grešaka u programima bez izvornih kodova. - SPb.: BHV-Peterburg, 2005.-- 832 str.: ilustr.
  3. Kaspersky K. Računarski virusi iznutra i spolja. - SPb.: Peter, 2006.-- 527 str.: ilustr.
  4. Kaspersky K. Bilješke istraživača kompjuterskih virusa. - SPb.: Peter, 2006.-- 316 str.: ilustr.
  5. Knut D. Umjetnost programiranja, tom 3. Sortiranje i pretraživanje, 2. izdanje: trans. sa engleskog - M.: Izdavačka kuća "Williams", 2003. - 832 str.: ilustr. - Paralelno. tit. engleski
  6. Kolisničenko D.N. Rootkiti za Windows. Teorija i praksa programiranja "nevidljivih kapa", omogućavajući sakrivanje podataka, procesa, mrežnih veza od sistema. - SPb.: Nauka i tehnika, 2006.-- 320 str.: ilustr.
  7. Lyamin L.V. Makro asembler MASM.– M.: Radio i komunikacija, 1994.– 320 str.: ilustr.
  8. Magda Y. Asembler za Intel Pentium procesore. - SPb.: Peter, 2006.-- 410 str.: ilustr.
  9. Mayko G.V. Asembler za IBM PC - M.: Biznis-Inform, Sirin, 1997. - 212 str.
  10. Warren G. Algoritamski trikovi za programere, 2. izdanje: trans. sa engleskog - M.: Izdavačka kuća "Williams", 2004. - 512 str.: ilustr. - Paralelno. tit. engleski
  11. Sklyarov I.S. Umijeće zaštite i hakovanja informacija. - SPb.: BHV-Peterburg, 2004.-- 288 str.: ilustr.
  12. Weatherrell C. Studije za programere: Per. sa engleskog - M.: Mir, 1982.-- 288 str., Il.
  13. Elektronska biblioteka braće Frolov www.frolov-lib.ru
  14. A.A. Čekatov Korištenje Turbo Assemblera u razvoju softvera - Kijev: Dijalektika, 1995. - 288 str.
  15. Yurov V. Assembler: posebna referentna knjiga.- SPb.: Peter, 2001.- 496 str.: ilustr.
  16. Yurov V. Assembler. Radionica. 2nd ed. - SPb.: Peter, 2006.-- 399 str.: ilustr.
  17. Yurov V. Assembler. Udžbenik za univerzitete. 2nd ed. - SPb.: Petar, 2007.-- 637 str.: ilustr.
  18. Pirogov V. Kurs za asembler. 2001 Znanje
  19. Pirogov V. ASSEMBLER kurs obuke 2003 Znanje-BHV
  20. V. Pirogov Asembler za prozore
    1. izdanje - M.: Izdavačka kuća Molgachev S.V., 2002.
    2. izdanje - SPb.:. BHV-Peterburg, 2003. - 684 str.: ilustr.
    3. izdanje - SPb.:. BHV-Peterburg, 2005. - 864 str.: ilustr.
    4. izdanje - SPb.:. BHV-Peterburg, 2012. - 896 str.: ilustr.
  21. V. Pirogov Assembler na primjerima. - SPb.:. BHV-Peterburg, 2012. - 416 str.: ilustr.
  22. V. Pirogov MONTAŽA i demontaža. - SPb.:. BHV-Peterburg, 2006.-- 464 str.: ilustr.
  23. Pirogov V. rad na knjizi "64-bitno programiranje u asemblerskom jeziku (Windows, Unix)". Knjiga pokriva programiranje sa fasmom na 64-bitnim Windowsima i Unixima
  24. Yurov V., Khoroshenko S. Assembler: tečaj obuke.- SPb.: Peter, 1999. - 672 str.
  25. Yu-Zheng Liu, Gibson G. 8086/8088 Mikroprocesori. Arhitektura, programiranje i dizajn mikroračunarskih sistema - M.: Radio i komunikacija, 1987. - 512 str.
  26. Agner Fog: Resursi za optimizaciju softvera (sastavljanje / c ++) 1996 - 2017.

Poljakov Andrej Valerijevič

http://info-master.su

[email protected]

av-inf.blogspot.ru

U kontaktu sa:

vk.com/id185471101

facebook.com/100008480927503

Stranica knjige:

http://av-assembler.ru/asm/afd/assembler-for-dummy.htm

PAŽNJA!

Sva prava na ovu knjigu pripadaju Andreju V. Poljakovu. Nijedan dio ove knjige ne može se reproducirati u bilo kojem obliku bez pristanka autora.

Informacije sadržane u ovoj knjizi dobijene su iz izvora koje autor smatra pouzdanim. Međutim, s obzirom na moguće ljudske ili tehničke greške, autor ne može jamčiti apsolutnu tačnost i potpunost datih informacija i nije odgovoran za moguće greške i štete nastale korištenjem ovog dokumenta.

1. DOZVOLE

Dozvoljeno je korištenje knjige u informativne i obrazovne svrhe (samo za ličnu upotrebu). Dozvoljena je besplatna distribucija knjige.

2. OGRANIČENJA

Zabranjeno je korištenje knjige u komercijalne svrhe (prodaja, postavljanje na resurse sa plaćenim pristupom, itd.). Zabranjeno je mijenjati tekst knjige. Atribucija je zabranjena.

vidi takođe UGOVOR O LICENCI.

Polyakov A.V.

Asembler za lutke

Polyakov A.V. Asembler za lutke.

PREDGOVOR ................................................... ................................................... ................................................... ...........

UVOD ................................................................ ................................................... ................................................... ...................

N MNOGO O PROCESORIMA.......................................................................................................................................................

1. BRZI POČETAK ................................................ ................................................... ................................................... .......

1.1. PRVI PROGRAM ................................................................ ................................................... ................................................... .....

1.1.1. Emu8086 ................................................... ................................................... ................................................... ...........

1.1.2. Otklanjanje grešaka ................................................ ................................................... ................................................... .............

1.1.3. MASM, TASM i WASM ........................................ ................................................... ........................................

1.1.3.1. Sastavljanje u TASM-u ................................................. ................................................... ................................................

1.1.3.2. Sastavljanje u MASM-u ................................................. ................................................... ..............................................

1.1.3.3. Sastavljanje u WASM-u ................................................. ................................................... ..............................................

1.1.3.4. Izvršenje programa ................................................................ ................................................... ................................................

1.1.3.5. Korištenje BAT datoteka ................................................. ................................................. . ........................................

1.1.4. Heksadecimalni uređivač ................................................ ................................................... ...................

Sažetak................................................. ................................................... ................................................... ........................

2. UVOD U ASEMBLER ........................................ ................................................... ..............................................

2.1. TO AK IMA KOMPJUTER...............................................................................................................................................

2.1.1. Struktura procesora ................................................................ ................................................... ...................................

2.1.2. Registri procesora ................................................. ................................................... ........................................

2.1.3. Ciklus izvršenja komande ................................................................. ................................................... .................................

2.1.4. Organizacija memorije ................................................................ ................................................... ..............................................

2.1.5. Stvarni način rada ................................................ ................................................... ................................................

2.1.6. Zaštićeni način rada ................................................. ................................................... ..............................................

2.2. WITH PRORAČUNSKI SISTEMI.....................................................................................................................................................

2.2.1. Binarni sistem brojeva ................................................................. ................................................... .........................

2.2.2. Heksadecimalni sistem brojeva ................................................ ................................................... ....

2.2.3. Ostali sistemi ................................................................ ................................................... ..............................................

2.3. P UREĐIVANJE PODATAKA U MEMORIJI RAČUNARA.............................................................................................................

2.3.1. Pozitivni brojevi ................................................................ ................................................... ...................................

2.3.2. Negativni brojevi................................................................ ................................................... ...................................

2.3.3. Šta je prelivanje ................................................. ................................................... ................................

2.3.4. Registar zastave ................................................ ................................................... ................................................

2.3.5. Kodovi znakova ................................................................ ................................................... ................................................

2.3.6. Realni brojevi ................................................ ................................................... ..............................................

2.3.6.1. Prvi pokušaj................................................................ ................................................... ................................................... ..........

2.3.6.2. Snimanje normalizovanog broja ................................................. ................................................... ...................................

2.3.6.3. Pretvaranje razlomaka u binarni dio ............................................... . ................................................. . ...

2.3.6.4. Reprezentacija realnih brojeva u memoriji računara ................................................... ...................................................

2.3.6.5. Brojevi fiksnih tačaka ................................................. ................................................. . ...................................

2.3.6.6. Brojevi s pomičnim zarezom ................................................. ................................................. . ..............................................

UGOVOR O LICENCI................................................ ................................................... ................................

PREDGOVOR

Asembler je čarobna riječ koja budi programere početnike. U međusobnoj komunikaciji obavezno kažu da negdje neko ima poznatog "čoveka" koji može čitati izvorne kodove na asembleru kao tekst knjige. Istovremeno, po pravilu, asemblerski jezik se doživljava kao nešto nedostupno običnim smrtnicima.

Ovo je djelimično tačno. Možete naučiti nekoliko jednostavnih naredbi, pa čak i napisati neku vrstu programa, ali možete postati pravi guru (u svakom poslu) samo ako osoba dobro poznaje teorijske osnove i razumije šta i zašto radi.

S druge strane, iskusni programeri visokog nivoa uvjereni su da je asemblerski jezik relikt prošlosti. Da, razvojni alati su napravili veliki napredak u proteklih 20 godina. Sada možete napisati jednostavan program bez poznavanja bilo kojeg programskog jezika. Međutim, ne zaboravite na stvari kao što su mikrokontroleri. A u kompjuterskom programiranju, neke zadatke je lakše i brže riješiti korištenjem asemblerskog jezika.

Ova knjiga je namenjena onima koji već imaju veštine programiranja na visokom nivou, ali bi želeli da se približe hardveru i razumeju kako se izvršavaju instrukcije procesora, kako se dodeljuje memorija, kako se upravlja raznim hardverskim uređajima kao što su diskovi itd. .P.

Knjiga je podijeljena u nekoliko dijelova. Prvi dio je brzi početak. Vrlo ukratko opisuje osnovne principe programiranja na asembleru, same asemblere (kompajlere) i metode rada sa asemblerima. Ako se osjećate sigurni u programiranje na visokom nivou, ali biste željeli savladati osnove programiranja niskog nivoa, možda ćete morati samo da pročitate ovaj odjeljak.

Drugi dio opisuje stvari kao što su sistemi brojeva, predstavljanje podataka u memoriji računara, itd., odnosno stvari koje nisu direktno vezane za programiranje, ali bez kojih je profesionalno programiranje nemoguće. Takođe, drugi deo detaljnije razmatra opšte principe programiranja na asemblerskom jeziku.

Ostatak odjeljaka opisuje neke specifične primjere programiranja asemblerskog jezika, sadrži referentne materijale i tako dalje.

Osnove programiranja uopće nisu opisane u ovoj knjizi, tako da za početnike toplo preporučujem da se upoznate s knjigom Kako postati programer, gdje su "na prste" objašnjeni opći principi programiranja i detaljno su razmotreni primjeri kreiranja jednostavnih programa od programa za računare do programa za CNC mašine.

UVOD

Počnimo s terminologijom.

Mašinski kod je sistem instrukcija određenog računara (procesora), koji se tumači direktno od strane procesora. Instrukcija je obično cijeli broj koji se upisuje u registar procesora. Procesor čita ovaj broj i izvodi operaciju koja odgovara ovoj instrukciji. Ovo je popularno opisano u knjizi Kako postati programer.

Programski jezik niskog nivoa(programski jezik niskog nivoa) je programski jezik koji je što je moguće bliži programiranju u mašinskim kodovima. Za razliku od mašinskih kodova, u jeziku niskog nivoa, svaka komanda ne odgovara broju, već skraćenom imenu komande (mnemonički). Na primjer, ADD je skraćenica za ADITION. Stoga, upotreba jezika niskog nivoa uvelike pojednostavljuje pisanje i čitanje programa (u poređenju sa programiranjem u mašinskim kodovima). Jezik niskog nivoa je specifičan za procesor. Na primjer, ako ste napisali program niske razine za PIC procesor, možete biti sigurni da neće raditi s AVR procesorom.

Programski jezik visokog nivoa To je programski jezik koji je što je moguće bliži ljudskom jeziku (obično engleskom, ali postoje programski jezici na nacionalnim jezicima, na primjer, 1C jezik je zasnovan na ruskom). Jezik visokog nivoa praktično nije vezan za određeni procesor ili operativni sistem (osim ako se ne koriste posebne direktive).

Asemblerski jezik je programski jezik niskog nivoa na kojem pišete svoje programe. Svaki procesor ima svoj asemblerski jezik.

Asembler je poseban program koji konvertuje (sastavlja, odnosno sastavlja) izvorni kod vašeg programa napisan asemblerskim jezikom u izvršnu datoteku (datoteku sa ekstenzijom EXE ili COM). Da budemo precizni, potrebni su dodatni programi za kreiranje izvršne datoteke, a ne samo asembler. Ali o tome kasnije...

U većini slučajeva kažu "assembler", ali znače "jezik sastavljanja". Sada znate da su to različite stvari i nije sasvim ispravno to reći. Iako će vas svi programeri razumjeti.

Za razliku od jezika visokog nivoa kao što su Pascal, BASIC, itd., SVAKI ASEMBLER ima svoj VLASTITI JEZIK ASEMBLIRANJA. Ovo pravilo suštinski razlikuje asemblerski jezik od jezika visokog nivoa. Izvorni kodovi programa (ili jednostavno "izvori") napisani na jeziku visokog nivoa, u većini slučajeva možete kompajlirati sa različitim prevodiocima za različite procesore i različite operativne sisteme. Biće mnogo teže to učiniti sa asemblerskim izvorima. Naravno, ova razlika je gotovo neprimjetna za različite asemblere koji su dizajnirani za iste procesore. Ali činjenica je da za SVAKI PROCESOR postoji VLASTITI ASEMBLER i VLASTITI JEZIK ASEMBLER. U tom smislu, programiranje na jezicima visokog nivoa je mnogo lakše. Međutim, za sva zadovoljstva morate platiti. U slučaju jezika visokog nivoa, možemo naići na stvari kao što su veća veličina izvršne datoteke, lošije performanse itd.

U ovoj knjizi ćemo govoriti samo o programiranju za računare sa Intel procesorima (ili kompatibilnim). Da bi se u praksi provjerilo dato

v U knjizi primjera trebat će vam sljedeći programi (ili barem neki od njih):

1. Emu8086. Odličan program, posebno za početnike. Uključuje uređivač izvora i neke druge korisne stvari. Radi na Windows-u, iako su programi napisani pod DOS-om. Nažalost, program košta (ali vrijedi))). Pogledajte http://www.emu8086.com za detalje.

2. TASM - Turbo Assembler iz Borlanda. Možete kreirati programe i za DOS i za Windows. Takođe košta i trenutno više nije podržan (a Borland više ne postoji). Generalno, to je dobra stvar.

3. MASM - Assembler iz Microsofta (skraćeno za MACRO asembler, a ne Microsoft Assembler, kako mnogi neupućeni ljudi misle). Možda najpopularniji asembler za Intel procesore. Još uvijek je podržan. Shareware program. Odnosno, ako ga kupite zasebno, onda će koštati novac. Ali dostupan je besplatno MSDN pretplatnicima i uključen je u Microsoftov paket Visual Studio.

4. WASM - asembler iz Watcoma. Kao i svi drugi, ima prednosti i nedostatke.

5. Debug - ima skromne karakteristike, ali ima veliki plus - uključen je u standardni Windows set. Potražite ga u fascikli WINDOWS \ COMMAND ili WINDOWS \ SYSTEM32. Ako ga ne pronađete, onda u drugim fasciklama WINDOWS direktorijuma.

6. Takođe je poželjno imati bilo koji hex editor... Ne povrijedite i DOS upravitelj datoteka, na primjer Volkov Commander (VC) ili Norton Commander (NC). Mogu se koristiti i za pregled heksadecimalnih kodova datoteke, ali se ne mogu uređivati. Na internetu postoji dosta besplatnih heksadecimalnih uređivača. Evo jednog: McAfee FileInsight v2.1. Isti editor se može koristiti za rad sa izvornim kodovima programa. Međutim, volim to bolje raditi sa sljedećim uređivačem:

7. Uređivač teksta... Neophodan je za pisanje izvornog koda vaših programa. Mogu preporučiti besplatni uređivač PSPad, koji podržava mnoge programske jezike, uključujući i Assembly.

Svi programi (i uzorci programa) predstavljeni u ovoj knjizi su testirani na operativnost. I upravo se ti programi koriste za implementaciju primjera programa u ovoj knjizi.

Pa ipak - izvorni kod napisan, na primjer, za Emu8086, malo će se razlikovati od koda napisanog, na primjer, za TASM. O ovim razlikama će se raspravljati.

Većina programa u knjizi napisana je za MASM. Prvo, zato što je ovaj asembler najpopularniji i još uvijek podržan. Drugo, zato što se isporučuje sa MSDN-om i Microsoftovim paketom Visual Studio. I treće, zato što sam ponosni vlasnik licencirane kopije MASM-a.

Ako već imate bilo koji asembler koji nije uključen u gornju listu, onda ćete morati sami da shvatite njegovu sintaksu i pročitate korisnički priručnik kako biste naučili kako ispravno raditi s njim. Ali opšte preporuke date u ovoj knjizi će važiti za sve (pa, ili skoro sve) asemblere.

Malo o procesorima

Procesor je mozak kompjutera. Fizički, ovo je poseban mikro krug sa nekoliko stotina pinova koji je umetnut u matičnu ploču. Ako teško možete zamisliti o čemu se radi, preporučujem da pročitate članak Lutke o kompjuterima.

Čak iu svijetu računara postoji dosta procesora. Ali pored kompjutera, tu su i televizori, mašine za pranje veša, klima uređaji, sistemi za upravljanje motorima sa unutrašnjim sagorevanjem itd., gde su procesori (mikroprocesori, mikrokontroleri) takođe veoma rasprostranjeni.

Svaki procesor ima svoj skup registara. Registri procesora su posebne memorijske lokacije koje se nalaze direktno na procesorskom čipu. Registri se koriste u različite svrhe (više detalja o registrima biće napisano u nastavku).

Svaki procesor ima svoj skup instrukcija. Instrukcija procesora se upisuje u određeni registar, a zatim procesor izvršava ovu instrukciju. O uputstvima i registrima procesora ćemo pričati mnogo i često kroz knjigu. Za početnike preporučujem knjigu Kako postati programer, gde se najopštije rečeno, ali razumljivim jezikom, govori o principima izvršavanja programa od strane računara.

Šta je komanda u smislu procesora? To je samo broj. Međutim, moderni procesori mogu imati nekoliko stotina instrukcija. Biće teško zapamtiti sve njih. Kako onda pišete programe? Da bi se pojednostavio rad programera, izmišljen je jezik asemblera, gde svaka komanda odgovara mnemoničkom kodu. Na primjer, broj 4 odgovara mnemotehničkom ADD. Ponekad se asemblerski jezik naziva i mnemonički instrukcijski jezik.

1. BRZI START

1.1. Prvi program

Tipično, prvi primjer je program koji ispisuje string "Hello World!" Međutim, za osobu koja je tek počela da uči Assembler, takav program će biti previše komplikovan (nasmejaćete se, ali zaista jeste – pogotovo u nedostatku razumljivih informacija). Stoga će naš prvi program biti još jednostavniji - prikazat ćemo samo jedan znak - englesko slovo "A". I općenito - ako ste već odlučili postati programer - hitno postavite zadani raspored engleske tipkovnice. Štaviše, neki asembleri i kompajleri ne prihvataju ruska slova. Dakle, naš prvi program će prikazati englesko slovo "A". Zatim ćemo pogledati kreiranje takvog programa pomoću različitih asemblera.

Ako ste preuzeli i instalirali emulator 8086 procesora (pogledajte odjeljak UVOD), onda ga možete koristiti za kreiranje svojih prvih programa na asembleru. Trenutno (novembar 2011.) dostupna je verzija 4.08. Ovdje možete pronaći pomoć na ruskom: http://www.avprog.narod.ru/progs/emu8086/help.html.

Program Emu8086 se plaća. Međutim, možete ga koristiti besplatno 30 dana.

Dakle, preuzeli ste i instalirali program Emu8086 na svoj računar. Pokrenite ga i kreirajte novi fajl preko menija FILE - NEW - COM TEMPLATE (File - New - COM file template). U izvornom editoru, nakon toga, vidjet ćemo sljedeće:

Rice. 1.1. Kreiranje nove datoteke u Emu8086.

Ovdje treba napomenuti da su programi kreirani pomoću asemblera za računare koji rade pod Windowsom dva tipa: COM i EXE. Kasnije ćemo pogledati razlike između ovih datoteka, ali za sada samo trebate znati da ćemo po prvi put kreirati izvršne datoteke sa COM ekstenzijom, jer su jednostavnije.

Nakon kreiranja datoteke u Emu8086 kao što je gore opisano, u izvornom editoru ćete vidjeti red "dodajte svoj kod čujte" - "dodajte svoj kod ovdje" (slika 1.1). Brišemo ovaj red i umjesto njega ubacujemo sljedeći tekst:

Dakle, puni tekst programa će izgledati ovako:

Osim toga, u gornjem dijelu su komentari (na slici 1.1 - ovo je zeleni tekst). Komentar u asemblerskom jeziku počinje znakom; (tačka-zarez) i nastavlja se do kraja reda. Ako ne znate šta su komentari i zašto su potrebni, pogledajte knjigu Kako postati programer... Kao što sam već rekao, ovdje nećemo objašnjavati osnove programiranja, jer je knjiga koju sada čitate namijenjena ljudima koji su upoznati sa osnovama programiranja.

Također imajte na umu da asemblerski jezik nije osjetljiv na velika i mala slova. Možete napisati RET, ret ili Ret - to će biti ista komanda.

Ovu datoteku možete sačuvati negdje na disku. Ali ne morate. Da biste izvršili program, pritisnite dugme EMULATE (sa zelenim trouglom) ili taster F5. Otvoriće se dva prozora: prozor emulatora i prozor izvornog koda (slika 1.2).

V prozor emulatora prikazuje registre i dugmad za kontrolu programa. Prozor izvora prikazuje izvor vašeg programa, naglašavajući liniju koja se trenutno izvršava. Sve je to vrlo zgodno za proučavanje i otklanjanje grešaka u programima. Ali još nam ne treba.

V U prozoru emulatora možete pokrenuti svoj program za izvršenje u cijelosti (dugme RUN) ili u načinu rada korak po korak (dugme SINGLE STEP). Korak po korak način rada je zgodan za otklanjanje grešaka. Pa, sada ćemo pokrenuti program za izvršenje pomoću dugmeta RUN. Nakon toga (ako niste napravili nijednu grešku u tekstu programa), vidjet ćete poruku o završetku programa (slika 1.3). Ovdje vas obavještavamo da je program prenio kontrolu na operativni sistem, odnosno da je program uspješno završen. Kliknite OK u ovom prozoru i konačno ćete vidjeti rezultat vašeg prvog programa asemblerskog jezika (Sl.

Rice. 1.2. Emu8086 prozor emulatora.

Rice. 1.3. Poruka o završetku programa.

Rice. 1.4. Vaš prvi program je završen.

Top srodni članci