Windows.  Virus.  Bärbara datorer.  Internet.  Kontor.  Verktyg.  Förare

NATIONELLA UNIVERSITETET I UZBEKISTAN UPPGIFT EFTER MIRZO ULUGBEK

DATORTEKNISK FAKULTET

Om ämnet: Semantisk analys av en EXE-fil.

Avslutad:

Tasjkent 2003.

Förord.

Monteringsspråk och kommandostruktur.

EXE-filstruktur (semantisk analys).

COM-filstruktur.

Principen för verkan och spridning av viruset.

Demonterare.

Program.

Förord

Yrket som programmerare är fantastiskt och unikt. Nuförtiden är det omöjligt att föreställa sig vetenskapen och livet utan senaste tekniken. Allt relaterat till mänsklig aktivitet kan inte göras utan datorteknik. Och detta bidrar till dess höga utveckling och perfektion. Även om utvecklingen av persondatorer började för inte så länge sedan, har under denna tid kolossala steg tagits i mjukvaruprodukter och dessa produkter kommer att användas i stor utsträckning under lång tid. Området datorrelaterad kunskap har genomgått en explosion, liksom motsvarande teknik. Om vi ​​inte tar hänsyn till den kommersiella sidan kan vi säga att det inte finns några främlingar inom detta område av yrkesverksamhet. Många människor utvecklar program inte för vinst eller inkomst, utan av egen fri vilja, av passion. Detta ska givetvis inte påverka kvaliteten på programmet, och i den här branschen finns det så att säga konkurrens och efterfrågan på kvalitetsutförande, stabilt arbete och att uppfylla alla moderna krav. Här är det också värt att notera utseendet på mikroprocessorer på 60-talet, som kom att ersätta stor mängd set med lampor Det finns vissa typer av mikroprocessorer som skiljer sig mycket från varandra. Dessa mikroprocessorer skiljer sig från varandra i bitdjup och inbyggd systemkommandon. De vanligaste är: Intel, IBM, Celeron, AMD, etc. Alla dessa processorer är relaterade till avancerad processorarkitektur från Intel. Spridningen av mikrodatorer orsakade en omprövning av attityder till assemblerspråk av två huvudsakliga skäl. För det första kräver program skrivna i assemblerspråk betydligt mindre minne och körningstid. För det andra ger kunskap om assemblerspråk och den resulterande maskinkoden en förståelse för maskinens arkitektur, vilket är osannolikt att tillhandahållas när man arbetar på ett språk på hög nivå. Även om de flesta mjukvaruproffs utvecklar på högnivåspråk som Pascal, C eller Delphi, vilket är lättare när man skriver program, är den mest kraftfulla och effektiva programvara skrivs helt eller delvis på assemblerspråk. Språk på hög nivå utvecklades för att undvika att vara tekniskt specifika för vissa datorer. Och assemblerspråk är i sin tur designat för processorns specifika detaljer. Därför, för att kunna skriva ett program i assemblerspråk för en specifik dator, måste du känna till dess arkitektur. Dessa dagar, utsikten över de viktigaste mjukvaruproduktär en EXE-fil. Med tanke på de positiva aspekterna av detta kan författaren till programmet vara säker på dess integritet. Men ofta är detta långt ifrån fallet. Det finns även en demonteringsmaskin. Med hjälp av en disassembler kan du ta reda på avbrott och programkoder. Det kommer inte att vara svårt för en person som är väl insatt i assembler att göra om hela programmet efter sin smak. Det är kanske här det mest olösliga problemet uppstår - viruset. Varför skriver folk ett virus? Vissa ställer den här frågan med förvåning, andra med ilska, men ändå finns det fortfarande människor som är intresserade av denna uppgift, inte ur synvinkeln att orsaka skada, utan som ett intresse för systemprogrammering. Virus skrivs av olika anledningar. Vissa människor gillar systemanrop, andra förbättrar sina kunskaper om assembler. Jag ska försöka förklara allt detta i mitt kursarbete. Den säger också inte bara om strukturen för EXE-filen utan också om assemblerspråket.

^ Församlingsspråk.

Det är intressant att följa, från tiden för de första datorernas uppkomst till idag, omvandlingen av programmerares idéer om assemblerspråk.

En gång i tiden var montering ett språk utan vilket man inte kunde få en dator att göra något användbart. Gradvis förändrades situationen. Mer bekväma sätt att kommunicera med en dator dök upp. Men, till skillnad från andra språk, dog inte assembler, det kunde i princip inte göra detta. Varför? På jakt efter ett svar, låt oss försöka förstå vad assemblerspråk är i allmänhet.

Sammanfattningsvis är assemblerspråk en symbolisk representation av maskinspråk. Alla processer i en maskin på den lägsta hårdvarunivån drivs endast av maskinspråkkommandon (instruktioner). Av detta framgår att, trots det vanliga namnet, är assemblerspråket olika för varje typ av dator. Detta gäller också utseende program skrivna i assembler och idéer som detta språk är en återspegling av.

Det är omöjligt att verkligen lösa problem relaterade till hårdvara (eller till och med, dessutom beroende av hårdvara, som att öka hastigheten på ett program), utan kunskap om assembler.

En programmerare eller någon annan användare kan använda alla verktyg på hög nivå, upp till byggprogram virtuella världar och kanske inte ens misstänker att datorn faktiskt inte utför kommandona för det språk som dess program är skrivet på, utan deras transformerade representation i form av en tråkig och tråkig sekvens av kommandon för ett helt annat språk - maskin. Låt oss nu föreställa oss att en sådan användare har ett icke-standardproblem eller att något helt enkelt inte fungerar. Till exempel måste hans program fungera med någon ovanlig enhet eller utföra andra åtgärder som kräver kunskap om datorhårdvarans driftsprinciper. Oavsett hur smart programmeraren är, hur bra språk han än skrev sitt underbara program på, kan han inte klara sig utan kunskap om assembler. Och det är ingen slump att nästan alla språkkompilatorer på hög nivå innehåller sätt att koppla ihop sina moduler med assemblermoduler eller stödja åtkomst till assemblernivån för programmering.

Datageneralisternas tid är förstås redan förbi. Som de säger, du kan inte omfamna det oerhörda. Men det finns något gemensamt, en sorts grund som varje seriös datautbildning bygger på. Detta är kunskap om principerna för datordrift, dess arkitektur och assemblerspråk som en reflektion och förkroppsligande av denna kunskap.

En typisk modern dator (i486 eller Pentium-baserad) består av följande komponenter (Figur 1).

Ris. 1. Dator och kringutrustning

Ris. 2. Blockschema persondator

Av figuren (Figur 1) kan man se att datorn är uppbyggd av flera fysiska enheter som var och en är kopplad till en enhet, kallad systemenheten. Om vi ​​tänker logiskt är det tydligt att det spelar rollen som någon form av koordinerande enhet. Låt oss ta en titt inuti systemenhet(du behöver inte försöka komma in i monitorn - det finns inget intressant där, och dessutom är det farligt): öppna höljet och se några brädor, block, anslutningskablar. För att förstå deras funktionella syfte, låt oss titta på blockdiagrammet typisk dator(Fig. 2). Den gör inte anspråk på absolut noggrannhet och är endast avsedd att visa syftet, förhållandet och den typiska sammansättningen av elementen i en modern persondator.

Låt oss diskutera diagrammet i fig. 2 i en något okonventionell stil.
Det är vanligt att en person, när man möter något nytt, letar efter några associationer som kan hjälpa honom att förstå det okända. Vilka associationer väcker datorn? Jag associerar till exempel ofta en dator med personen själv. Varför?

När en person skapade en dator, någonstans djupt inne i sig själv trodde han att han skapade något som liknade honom själv. En dator har organ för att ta emot information från omvärlden - ett tangentbord, en mus, lagringsenheter. magnetiska skivor. I fig. 2 dessa organ är belägna till höger om systembussar. Datorn har organ som "smälter" den mottagna informationen - de är CPU och RAM. Och slutligen har datorn talorgan som producerar resultatet av bearbetningen. Det här är också några av enheterna till höger.

Moderna datorer, naturligtvis, är långt ifrån mänsklig. De kan jämföras med varelser som interagerar med omvärlden på nivån av en stor men begränsad uppsättning ovillkorliga reflexer.
Denna uppsättning reflexer bildar ett system av maskinkommandon. Oavsett hur hög nivå du kommunicerar med en dator, kommer allt i slutändan ner på en tråkig och monoton sekvens av maskinkommandon.
Varje maskinkommando är ett slags stimulans för att excitera en eller annan obetingad reflex. Reaktionen på denna stimulans är alltid entydig och "hardwired" i mikrokommandoblocket i form av ett mikroprogram. Detta mikroprogram implementerar åtgärder för att implementera ett maskinkommando, men på nivån för signaler som tillförs vissa logiska kretsar i datorn, och styr därigenom olika delsystem i datorn. Detta är den så kallade principen för mikroprogramstyrning.

Fortsätter analogin med en person, noterar vi: för att en dator ska äta ordentligt har många operativsystem, kompilatorer för hundratals programmeringsspråk, etc. uppfunnits, men alla är i själva verket bara en tallrik som mat (program) levereras enligt vissa regler mage (dator). Endast datorns mage älskar kost, monoton mat - ge den strukturerad information, i form av strikt organiserade sekvenser av nollor och ettor, vars kombinationer utgör maskinspråk.

Således, även om den utåt är en polyglot, förstår datorn bara ett språk - språket för maskininstruktioner. Naturligtvis, för att kommunicera och arbeta med en dator, är det inte nödvändigt att kunna det här språket, men nästan alla professionella programmerare ställs förr eller senare inför behovet av att studera det. Lyckligtvis behöver programmeraren inte försöka förstå innebörden av de olika kombinationerna binära tal, sedan tillbaka på 50-talet började programmerare använda en symbolisk analog av maskinspråk för programmering, som kallades assemblerspråk. Detta språk återspeglar exakt alla funktioner i maskinspråket. Det är därför, till skillnad från högnivåspråk, assemblerspråk är olika för varje typ av dator.

Av allt ovanstående kan vi dra slutsatsen att eftersom assemblerspråk är "inhemskt" för en dator, kan det mest effektiva programmet bara skrivas i det (förutsatt att det är skrivet av en kvalificerad programmerare). Det finns ett litet "men" här: det här är en mycket arbetsintensiv process som kräver mycket uppmärksamhet och praktisk erfarenhet. Därför är i verkligheten huvudsakligen program skrivna i assembler, vilket bör säkerställa ett effektivt arbete med hårdvaran. Ibland skrivs programavsnitt som är kritiska vad gäller körtid eller minnesförbrukning i assembler. Därefter formaliseras de i form av subrutiner och kombineras med kod på ett högnivåspråk.

Det är vettigt att börja lära sig assemblerspråket för vilken dator som helst efter att ha tagit reda på vilken del av datorn som är synlig och tillgänglig för programmering på detta språk. Detta är den så kallade datorprogrammodellen, varav en del är mikroprocessorprogrammodellen, som innehåller 32 register, i en eller annan grad, tillgängliga för programmeraren.

Dessa register kan delas in i två stora grupper:

^ 16 användarregister;

16 systemregister.

Assembly språkprogram använder register mycket intensivt. De flesta register har ett specifikt funktionssyfte.

Som namnet antyder kallas användarregister för användarregister eftersom programmeraren kan använda dem när han skriver sina program. Dessa register inkluderar (Fig. 3):

Åtta 32-bitars register som kan användas av programmerare för att lagra data och adresser (även kallade register allmänt syfte(RON)):

sex segmentregister: cs, ds, ss, es, fs, gs;

status- och kontrollregister:

Flaggor register eflags/flaggor;

Kommandopekarregister eip/ip.

Ris. 3. Användarregister för mikroprocessorer i486 och Pentium

Varför visas många av dessa register med snedstreck? Nej, det här är inte olika register - de är delar av ett stort 32-bitars register. De kan användas i programmet som separata objekt. Detta gjordes för att säkerställa funktionaliteten hos program skrivna för yngre 16-bitars modeller av Intel-mikroprocessorer, med början i i8086. Mikroprocessorerna i486 och Pentium har mestadels 32-bitars register. Deras antal, med undantag för segmentregister, är detsamma som i8086, men dimensionen är större, vilket återspeglas i deras beteckningar - de har
prefix e (Utökad).

^ Register för allmänna ändamål
Alla register i denna grupp ger dig tillgång till deras "nedre" delar (se fig. 3). Om du tittar på denna figur, notera att endast de nedre 16- och 8-bitarsdelarna av dessa register kan användas för självadressering. De övre 16 bitarna i dessa register är inte tillgängliga som oberoende objekt. Detta gjordes, som vi noterade ovan, för kompatibilitet med yngre 16-bitars modeller av Intel-mikroprocessorer.

Låt oss lista de register som hör till gruppen allmänna register. Eftersom dessa register är fysiskt placerade i mikroprocessorn inuti en aritmetisk logisk enhet (ALU), kallas de också för ALU-register:

eax/ax/ah/al (Ackumulatorregister) - batteri.
Används för att lagra mellanliggande data. Vissa kommandon kräver användning av detta register;

ebx/bx/bh/bl (Basregister) - basregister.
Används för att lagra basadressen för något objekt i minnet;

ecx/cx/ch/cl (Räkneregister) - räknareregister.
Används i team som utför vissa repetitiva åtgärder. Dess användning är ofta implicit och dold i algoritmen för motsvarande kommando.
Till exempel, kommandot för att organisera en slinga, förutom att överföra kontroll till ett kommando som finns på en viss adress, analyserar och minskar värdet på ecx/cx-registret med ett;

edx/dx/dh/dl (Dataregister) - dataregister.
Precis som eax/ax/ah/al-registret lagrar det mellanliggande data. I vissa kommandon är dess användning obligatorisk; För vissa kommandon sker detta implicit.

Följande två register används för att stödja så kallade kedjeoperationer, det vill säga operationer som sekventiellt bearbetar kedjor av element, som var och en kan vara 32, 16 eller 8 bitar långa:

esi/si (Källindexregister) - källindex.
Detta register i kedjade operationer innehåller den aktuella adressen för elementet i källkedjan;

edi/di (Destination Index register) - index för mottagaren (mottagaren).
Detta register i kedjade operationer innehåller den aktuella adressen i destinationskedjan.

I mikroprocessorarkitekturen stöds en datastruktur som kallas en stack på hård- och mjukvarunivå. För att arbeta med stacken finns det speciella kommandon iet, och i mikroprocessorns mjukvarumodell finns det speciella register för detta:

esp/sp (Stack Pointer register) - stack pointer register.
Innehåller en pekare till toppen av stapeln i det aktuella stapelsegmentet.

ebp/bp (Base Pointer register) - stack frame base pointer register.
Designad för att organisera slumpmässig tillgång till data inuti stacken.

En stack är ett programområde för tillfällig lagring av godtyckliga data. Naturligtvis kan data också lagras i ett datasegment, men i detta fall måste för varje tillfälligt lagrad data skapas en separat namngiven minnescell, vilket ökar programmets storlek och antalet namn som används. Bekvämligheten med stacken ligger i det faktum att dess område är återanvändbart, och att lagra data på stacken och hämta den därifrån görs med de effektiva push- och pop-kommandona utan att ange några namn.
Stacken används traditionellt, till exempel för att spara innehållet i register som används av ett program innan en subrutin anropas, som i sin tur kommer att använda processorregistren "för sina egna syften". Det ursprungliga innehållet i registren tas bort från stacken efter att subrutinen återvänder. En annan vanlig teknik är att skicka de parametrar som krävs till en subrutin via stacken. Subrutinen, som vet i vilken ordning parametrarna är placerade på stacken, kan ta dem därifrån och använda dem under dess exekvering. En utmärkande egenskap hos stacken är den unika ordningen i vilken data som finns i den hämtas: vid varje given tidpunkt är endast det översta elementet tillgängligt på stacken, d.v.s. elementet senast tryckt på stapeln. Genom att skjuta upp det översta elementet från stapeln blir nästa element tillgängligt. Stackelement är belägna i minnesområdet som är tilldelat för stacken, med början från botten av stacken (dvs från dess maximala adress) vid sekventiellt minskande adresser. Adressen för det översta, tillgängliga elementet lagras i stackpekarregistret SP. Liksom alla andra delar av programminnet måste stapeln vara en del av något segment eller bilda ett separat segment. I båda fallen placeras segmentadressen för detta segment i segmentstackregistret SS. Sålunda beskriver registerparet SS:SP adressen för en tillgänglig stackcell: SS lagrar segmentadressen för stacken och SP lagrar förskjutningen av den senast lagrade datan i stacken (fig. 4, a). Observera att i initialtillståndet pekar stackpekaren SP på en cell som ligger under stapelns botten och som inte ingår i den.

Fig 4. Stackorganisation: a - initialt tillstånd, b - efter laddning av ett element (i detta exempel, innehållet i AX-registret), c - efter laddning av det andra elementet (innehållet i DS-registret), d - efter urladdning av ett element, e - efter att ha lossat två element och återgått till deras ursprungliga tillstånd.

Lastning i stapeln utförs av ett speciellt kommando för att arbeta med stapeln (push). Denna instruktion minskar först innehållet i stackpekaren med 2 och placerar sedan operanden på adressen i SP. Om vi ​​till exempel vill lagra innehållet i AX-registret på stacken, bör vi köra kommandot

Stacken går in i det tillstånd som visas i fig. 1,10, b. Det kan ses att stackpekaren flyttas upp två byte (mot lägre adresser) och operanden som anges i push-kommandot skrivs till denna adress. Följande stackladdningskommando är t.ex.

kommer att sätta stacken i det tillstånd som visas i fig. 1,10, c. Stacken kommer nu att lagra två element, och endast det översta, som pekas på av stackpekaren SP, kommer att vara tillgängligt. Om vi ​​efter en tid behöver återställa det ursprungliga innehållet i registren som är lagrade på stacken, måste vi utföra pop (push)-kommandon för att ladda ner från stacken:

pop DS
pop AX

Hur stor ska stapeln vara? Det beror på hur intensivt det används i programmet. Om du till exempel planerar att lagra en array på 10 000 byte i stacken, måste stacken vara minst denna storlek. Man bör komma ihåg att i vissa fall används stacken automatiskt av systemet, särskilt när man kör int 21h interrupt-kommandot. Med detta kommando trycker processorn först returadressen till stacken och sedan skickar DOS innehållet i registren och annan information relaterad till det avbrutna programmet till stacken. Därför, även om ett program inte använder en stack alls, måste den fortfarande finnas i programmet och vara minst flera dussin ord i storlek. I vårt första exempel tilldelade vi 128 ord till stacken, vilket säkert räcker.

^ Struktur för ett assemblerprogram

Ett assemblerspråksprogram är en samling minnesblock som kallas minnessegment. Ett program kan bestå av ett eller flera sådana blocksegment. Varje segment innehåller en samling språkmeningar, som var och en upptar en separat rad med programkod.

Det finns fyra typer av assembler-påståenden:

kommandon eller instruktioner som är symboliska analoger till maskinkommandon. Under översättningsprocessen omvandlas assemblerinstruktioner till motsvarande kommandon för mikroprocessorinstruktionsuppsättningen;

makrokommandon - meningar av programtext formaterad på ett visst sätt, ersatta under sändning med andra meningar;

direktiv, som är instruktioner till assembleröversättaren att utföra vissa åtgärder. Direktiven har inga motsvarigheter i maskinrepresentation;

kommentarsrader som innehåller alla tecken, inklusive bokstäver i det ryska alfabetet. Kommentarer ignoreras av översättaren.

^ Sammansättningssyntax

De meningar som utgör ett program kan vara en syntaktisk konstruktion som motsvarar ett kommando, makro, direktiv eller kommentar. För att assembleröversättaren ska känna igen dem måste de vara utformade enligt vissa syntaktiska regler. För att göra detta är det bäst att använda en formell beskrivning av språkets syntax, som grammatikreglerna. De vanligaste sätten att beskriva ett programmeringsspråk på detta sätt är syntaxdiagram och utökade Backus-Naur-former. För praktisk användning Syntaxdiagram är mer bekväma. Till exempel kan syntaxen för assemblerspråkssatser beskrivas med hjälp av syntaxdiagrammen som visas i följande figurer.

Ris. 5. Monteringssatsformat

Ris. 6. Direktivformat

Ris. 7. Format för kommandon och makron

På dessa bilder:

etikettnamn - en identifierare vars värde är adressen till den första byten i meningen i källkoden för programmet som den anger;

namn - en identifierare som skiljer detta direktiv från andra direktiv med samma namn. Som ett resultat av montörens bearbetning av ett visst direktiv kan vissa egenskaper tilldelas det namnet;

operationskod (OPC) och direktiv är mnemonics motsvarande maskinkommando, makrokommando eller översättardirektiv;

operander är delar av ett kommando-, makro- eller assemblerdirektiv som anger de objekt på vilka åtgärder utförs. Assembly språkoperander beskrivs av uttryck med numeriska och textkonstanter, etiketter och variabelidentifierare med hjälp av operatortecken och vissa reserverade ord.

^ Hur använder man syntaxdiagram? Det är väldigt enkelt: allt du behöver göra är att hitta och sedan följa vägen från diagrammets ingång (till vänster) till dess utgång (till höger). Om en sådan väg finns är meningen eller konstruktionen syntaktisk korrekt. Om det inte finns någon sådan väg kommer kompilatorn inte att acceptera denna konstruktion. När du arbetar med syntaxdiagram, var uppmärksam på riktningen för korsningen som anges av pilarna, eftersom det bland banorna kan finnas några som kan följas från höger till vänster. I grund och botten återspeglar syntaxdiagram logiken i översättarens operation när man analyserar inmatningsmeningarna i programmet.

Godkända tecken när du skriver programtext är:

Alla latinska bokstäver: A-Z, a-z. I det här fallet anses stora och små bokstäver vara likvärdiga;

Siffror från 0 till 9;

Tecken ?, @, $, _, &;

Separatorer, . ()< > { } + / * % ! " " ? \ = # ^.

Sammansättningsspråkssatser bildas av lexem, som är syntaktiskt oskiljaktiga sekvenser av giltiga språksymboler som är meningsfulla för översättaren.

Lexem är:

identifierare är sekvenser av giltiga tecken som används för att beteckna programobjekt såsom operationskoder, variabelnamn och etikettnamn. Regeln för att skriva identifierare är följande: en identifierare kan bestå av ett eller flera tecken. Som symboler kan du använda bokstäver i det latinska alfabetet, siffror och några specialtecken - _, ?, $, @. En identifierare kan inte börja med ett siffror. Längden på identifieraren kan vara upp till 255 tecken, även om översättaren bara accepterar de första 32 och ignorerar resten. Du kan justera längden på möjliga identifierare med alternativet kommandoraden mv. Dessutom är det möjligt att instruera översättaren att skilja mellan stora och små bokstäver eller att ignorera deras skillnad (vilket görs som standard).

^Assembler-kommandon.

Assembler-kommandon avslöjar möjligheten att överföra dina krav till datorn, en mekanism för att överföra kontroll i ett program (cykler och övergångar) för logiska jämförelser och programorganisation. Men programmerbara uppgifter är sällan så enkla. De flesta program innehåller en serie loopar där flera instruktioner upprepas tills ett visst krav uppnås, och olika kontroller, som bestämmer vilken av flera åtgärder som ska utföras. Vissa instruktioner kan överföra kontroll genom att ändra den normala sekvensen av steg genom att direkt modifiera offsetvärdet i instruktionspekaren. Som sagt tidigare finns det olika kommandon för olika processorer kommer vi att överväga ett antal kommandon för 80186-, 80286- och 80386-processorerna.

För att beskriva flaggornas tillstånd efter att ha utfört ett visst kommando, kommer vi att använda ett urval från en tabell som återspeglar strukturen för eflags flaggregister:

Den nedre raden i denna tabell visar värdena för flaggorna efter att kommandot har utförts. Följande beteckningar används:

1 - efter att kommandot har utförts sätts flaggan (lika med 1);

0 - efter att kommandot har utförts återställs flaggan (lika med 0);

r - flaggans värde beror på resultatet av kommandot;

Efter att kommandot har utförts är flaggan inte definierad;

mellanslag - efter att kommandot har utförts ändras inte flaggan;

Följande notation används för att representera operander i syntaxdiagram:

r8, r16, r32 - en operand i ett av registren för bytestorlek, ord eller dubbelord;

m8, m16, m32, m48 - minnesoperandstorlek byte, ord, dubbelord eller 48 bitar;

i8, i16, i32 - omedelbar operandstorlek byte, ord eller dubbelord;

a8, a16, a32 - relativ adress (offset) i kodsegmentet.

Kommandon (i alfabetisk ordning):

*Dessa kommandon beskrivs i detalj.

TILLÄGGA
(Tillägg)

Tillägg

^ Kommandodiagram:

lägg till destination, källa

Syfte: tillägg av två käll- och måloperander av storlek byte, ord eller dubbelord.

Arbetsalgoritm:

lägg till käll- och destinationsoperander;

skriv tilläggsresultatet till mottagaren;

sätta flaggor.

Tillstånd för flaggor efter kommandoexekvering:

Ansökan:
Kommandot add används för att lägga till två heltalsoperander. Resultatet av tillägget placeras på adressen till den första operanden. Om resultatet av tillägget går utanför gränserna för mottagaroperanden (ett spill inträffar), bör denna situation beaktas genom att analysera cf-flaggan och den efterföljande möjliga användningen av adc-kommandot. Låt oss till exempel lägga till värdena i axregistret och ch-minnesområdet. Var uppmärksam på risken för spill när du lägger till.

Registrera plus register eller minne:

|000000dw|modregr/rm|

AX-register (AL) plus omedelbart värde:

|0000010w|--data--|data om w=1|

Register eller minne plus omedelbart värde:

|100000sw|mod000r/m|--data--|data om BW=01|

SAMTAL
(SAMTAL)

Anropa en procedur eller uppgift

^ Kommandodiagram:

Ändamål:

överföring av kontroll till en nära eller fjärran procedur med lagring av adressen för returpunkten på stapeln;

byta uppgifter.

Arbetsalgoritm:
bestäms av operandtypen:

Nära etikett - innehållet i eip/ip-kommandopekaren skjuts in i stacken och det nya adressvärdet som motsvarar etiketten laddas in i samma register;

Far label - innehållet i eip/ip och cs kommandopekaren skjuts in i stacken. Sedan laddas nya adressvärden som motsvarar den bortre etiketten in i samma register;

R16, 32 eller m16, 32 - definiera ett register eller minnescell som innehåller förskjutningar i det aktuella instruktionssegmentet till vilket styrningen överförs. När kontrollen överförs, skjuts innehållet i eip/ip-kommandopekaren till stacken;

Minnespekare - definierar en minnesplats som innehåller en 4 eller 6 byte pekare till den anropade proceduren. Strukturen för en sådan pekare är 2+2 eller 2+4 byte. Tolkningen av en sådan pekare beror på mikroprocessorns driftläge:

^ Tillstånd för flaggor efter kommandoexekvering (förutom uppgiftsbyte):

att köra kommandot påverkar inte flaggorna

När en uppgift byts ändras flaggvärdena enligt information om eflagsregistret i TSS-statussegmentet för uppgiften som byts till.
Ansökan:
Anropskommandot låter dig organisera en flexibel och multivariant överföring av kontroll till en subrutin samtidigt som adressen till returpunkten bevaras.

Objektkod (fyra format):

Direktadressering i ett segment:

|11101000|disp-låg|djup-hög|

Indirekt adressering i ett segment:

|11111111|mod010r/m|

Indirekt adressering mellan segment:

|11111111|mod011r/m|

Direkt adressering mellan segment:

|10011010|offset-låg|offset-hög|seg-låg|seg-hög|

CMP
(Jämför operander)

Operand jämförelse

^ Kommandodiagram:

cmp operand1,operand2

Syfte: jämförelse av två operander.

Arbetsalgoritm:

utför subtraktion(operand1-operand2);

beroende på resultatet, ställ in flaggorna, ändra inte operand1 och operand2 (det vill säga kommer inte ihåg resultatet).

Ansökan:
Detta kommando används för att jämföra två operander genom subtraktion utan att ändra operanderna. Baserat på resultatet av kommandot sätts flaggor. Kommandot cmp används med de villkorliga hoppkommandona och kommandot set byte byte setcc.

Objektkod (tre format):

Register eller minne med register:

|001110dw|modregr/m|

Omedelbart värde med AX (AL) register:

|0011110w|--data--|data om w=1|

Omedelbart värde med register eller minne:

|100000sw|mod111r/m|--data--|data if sw=0|

DEC
(Dekrementera operand med 1)

Minska en operand med en

^ Kommandodiagram:

dec operand

Syfte: Minska värdet på en operand i minnet eller registret med 1.

Arbetsalgoritm:
kommandot subtraherar 1 från operanden. Tillstånd för flaggor efter kommandoexekvering:

Ansökan:
Dec-instruktionen används för att minska värdet på en byte, ord, dubbelord i minnet eller register med ett. Observera dock att kommandot inte påverkar cf-flaggan.

Registrera: |01001reg|

^ Register eller minne: |1111111w|mod001r/m|

DIV
(DIVide osignerad)

Osignerad division

Lagöversikt:

div avdelare

Syfte: Utför en divisionsoperation mellan två binära värden utan tecken.

^ Driftsalgoritm:
Kommandot kräver att du specificerar två operander - utdelningen och divisorn. Utdelningen anges implicit och dess storlek beror på storleken på divisorn, som anges i kommandot:

om divisorn är en byte stor måste utdelningen finnas i yxregistret. Efter operationen placeras kvoten i al och resten i ah;

om divisor är ett ord i storlek, så måste utdelningen placeras i registerparet dx:ax, med den låga delen av utdelningen placerad i ax. Efter operationen placeras kvoten i ax och resten i dx;

om divisor är ett dubbelord i storlek, så måste utdelningen placeras i registerparet edx:eax, med den låga delen av utdelningen placerad i eax. Efter operationen placeras kvoten i eax och resten i edx.

^ Tillstånd för flaggor efter kommandoexekvering:

Ansökan:
Kommandot utför en heltalsdelning av operanderna, vilket ger resultatet av divisionen som kvoten och resten av divisionen. När du utför en divisionsoperation kan ett undantag inträffa: 0 - divisionsfel. Denna situation uppstår i ett av två fall: divisorn är 0 eller kvoten är för stor för att passa in i eax/ax/al-registret.

Objektkod:

|1111011w|mod110r/m|

INT
(Avbryta)

Anropar avbrottsservicerutinen

^ Kommandodiagram:

int interrupt_number

Syfte: anropa avbrottsservicerutinen med det avbrottsnummer som anges av kommandooperanden.

^ Driftsalgoritm:

tryck på flaggregistret eflags/flaggor och returadressen till stacken. När du skriver en returadress skrivs först innehållet i segmentregistret cs, sedan innehållet i kommandopekaren eip/ip;

återställ if och tf flaggorna till noll;

överföra kontrollen till avbrottstjänstprogrammet med angivet nummer. Styröverföringsmekanismen beror på mikroprocessorns driftläge.

^ Tillstånd för flaggor efter kommandoexekvering:

Ansökan:
Som du kan se från syntaxen finns det två former av detta kommando:

int 3 - har sin egen individuella operationskod 0cch och upptar en byte. Denna omständighet gör det mycket bekvämt för användning i olika programvarufelsökningar att ställa in brytpunkter genom att ersätta den första byten av ett kommando. Mikroprocessorn, som möter ett kommando med operationskoden 0cch i sekvensen av kommandon, anropar avbrottsbehandlingsprogrammet med vektornummer 3, som tjänar till att kommunicera med mjukvarufelsökaren.

Den andra formen av kommandot upptar två byte, har en opkod på 0cdh och låter dig initiera ett anrop till en avbrottstjänstrutin med ett vektornummer i intervallet 0–255. Funktioner för kontrollöverföring, som nämnts, beror på mikroprocessorns driftläge.

Objektkod (två format):

Registrera: |01000reg|

^ Register eller minne: |1111111w|mod000r/m|

J.C.C.
JCXZ/JECXZ
(Hoppa om skick)

(Hoppa om CX=Noll/ Hoppa om ECX=Noll)

Hoppa om villkoret är uppfyllt

Hoppa om CX/ECX är noll

^ Kommandodiagram:

jcc etikett
jcxz etikett
jecxz etikett

Syfte: övergång inom det aktuella kommandosegmentet beroende på något tillstånd.

^ Kommandoalgoritm (förutom jcxz/jecxz):
Kontrollera flaggornas tillstånd beroende på op-koden (den återspeglar tillståndet som kontrolleras):

om villkoret som testas är sant, gå sedan till cellen som indikeras av operanden;

om villkoret som kontrolleras är falskt, överför sedan kontrollen till nästa kommando.

Algoritm för kommandot jcxz/jecxz:
Kontrollera villkoret att innehållet i ecx/cx-registret är lika med noll:

om tillståndet kontrolleras

Kommandon kan särskiljas efter syfte (exempel på mnemoniska operationskoder för IBM PC assembler-kommandon anges inom parentes):

l avrättning aritmetiska operationer(ADD och ADC - addition och addition med bär, SUB och SBB - subtraktion och subtraktion med lån, MUL och IMUL - osignerad och signerad multiplikation, DIV och IDIV - osignerad och signerad division, CMP - jämförelser, etc. .);

l avrättning logiska operationer(ELLER, OCH, INTE, XOR, TEST, etc.);

l dataöverföring (MOV - framåt, XCHG - utbyte, IN - gå in i mikroprocessorn, OUT - utmatning från mikroprocessorn, etc.);

l överföring av kontroll (programgrenar: JMP - ovillkorligt hopp, CALL - proceduranrop, RET - retur från procedur, J* - villkorligt hopp, LOOP - loopkontroll, etc.);

l bearbetar teckensträngar (MOVS - överföringar, CMPS - jämförelser, LODS - laddningar, SCAS - skanningar. Dessa kommandon används vanligtvis med prefixet (repetitionsmodifierare) REP;

l programavbrott (INT - mjukvaruavbrott, INTO - villkorligt avbrott vid spill, IRET - retur från avbrott);

l mikroprocessorstyrning (ST* och CL* - inställning och återställning av flaggor, HLT - stopp, WAIT - väntar, NOP - tomgång, etc.).

En komplett lista med assembler-kommandon kan hittas under arbete.

Dataöverföringskommandon

l MOV dst, src - dataöverföring (flytta - skicka från src till dst).

Överföringar: en byte (om src och dst är i byteformat) eller ett ord (om src och dst är i ordformat) mellan register eller mellan ett register och minne, och skriver ett direkt värde till ett register eller minne.

Operanderna dst och src måste ha samma format - byte eller word.

Src kan vara av följande typ: r (register) - register, m (minne) - minne, i (impedans) - omedelbart värde. Dst kan vara av typen r, m. Du kan inte använda följande operander i ett kommando: rsegm tillsammans med i; två operander av typ m och två operander av typ rsegm). I-operanden kan också vara ett enkelt uttryck:

mov AX, (152 + 101B) / 15

Uttrycksutvärdering utförs endast under översättning. Byter inte flaggor.

l PUSH src - trycka ett ord på högen (push - trycka igenom; tryck på stapeln från src). Placerar innehållet i src - vilket 16-bitars register som helst (inklusive segmentregister) eller två minnesceller som innehåller ett 16-bitars ord - på toppen av stacken. Flaggorna ändras inte;

l POP dst - poppa ett ord från stapeln (pop - pop; räkna från stapeln till dst). Tar bort ett ord från toppen av stacken och placerar det i dst - valfritt 16-bitars register (inklusive segmentregister) eller i två minnesceller. Flaggorna ändras inte.

Kursarbete

Genom disciplin" Systemprogrammering»

Ämne nr 4: "Lösa procedurproblem"

Alternativ 2

STATE UNIVERSITET i ÖSTSIBIRIAN

TEKNIK OCH LEDNING

____________________________________________________________________

TEKNISK HÖGSKOLE

UTÖVA

för kursarbete

Disciplin:
Ämne: Lösa problem med procedurer
Skådespelare: Arina Aleksandrovna Glavinskaya
Chef: Dambaeva Sesegma Viktorovna
Sammanfattning av arbetet: studie av subrutiner på assembleringsspråk,
lösa problem med hjälp av subrutiner
1. Teoretisk del: Grundläggande information om Assembly-språket (set
kommandon, etc.), Organisation av subrutiner, Metoder för att skicka parametrar
i subrutiner
2. Praktisk del: Utveckla två subrutiner, varav den ena konverterar varje given bokstav till en stor bokstav (inklusive för ryska bokstäver), och den andra konverterar en bokstav till en liten bokstav.
konverterar en given bokstav till versaler, och den andra konverterar en given bokstav till gemener.
Konverterar en bokstav till gemener.
Projektets deadlines enligt schema:
1. Teoretisk del - 30 % senast vecka 7.
2. Praktisk del - 70 % senast vecka 11.
3. Skydd - 100 % senast vecka 14.
Designkrav:
1. Kursprojektets beräkning och förklarande notering ska redovisas i
elektroniska och papperskopior.
2. Rapportens volym måste vara minst 20 maskinskrivna sidor exklusive bilagor.
3. RPP upprättas i enlighet med GOST 7.32-91 och undertecknas av chefen.

Arbetsledare __________________

Skådespelare __________________

Utgivningsdatum" 26 " september 2017 G.


Introduktion. 2

1.1 Grundläggande information om Assembly-språket. 3

1.1.1 Kommandouppsättning. 4

1.2 Organisation av subrutiner på Assembly-språk. 4

1.3 Metoder för att skicka parametrar i subrutiner. 6

1.3.1 Att skicka parametrar genom register.. 6

1.3.2 Skicka parametrar via stacken. 7

2 PRAKTISKT AVSNITT... 9

2.1 Redogörelse för problemet. 9

2.2 Beskrivning av lösningen på problemet. 9

2.3 Testa programmet... 7

Slutsats. 8

Referenser.. 9


Introduktion

Assembly språk är notoriskt svårt att programmera. Som ni vet finns det många olika språk nu hög nivå, vilket gör att du kan spendera mycket mindre ansträngning när du skriver program. Naturligtvis uppstår frågan när en programmerare kan behöva använda assembler när han skriver program. För närvarande kan vi peka ut två områden där användningen av Assembly-språket är motiverat och ofta nödvändigt.

För det första är det de så kallade maskinberoende systemprogrammen som de vanligtvis styr olika enheter dator (sådana program kallas drivrutiner). I dessa systemprogram speciella maskinkommandon används som inte behöver användas i vanliga (eller, som de säger, tillämpad) program. Dessa kommandon är omöjliga eller mycket svåra att definiera på ett högnivåspråk.

Det andra tillämpningsområdet för Assembler är relaterat till optimering av programexekveringen. Mycket ofta producerar översättarprogram (kompilatorer) från högnivåspråk ett mycket ineffektivt maskinspråksprogram. Detta gäller vanligtvis beräkningsprogram där oftast en mycket liten (cirka 3-5%) sektion av programmet (huvudslingan) exekveras. För att lösa detta problem kan så kallade flerspråkiga programmeringssystem användas, som gör att delar av programmet kan skrivas på olika språk. Vanligtvis är huvuddelen av programmet skrivet på ett högnivåprogrammeringsspråk (Fortran, Pascal, C, etc.), och tidskritiska delar av programmet skrivs i Assembly. Hastigheten på hela programmet kan öka avsevärt. Ofta detta det enda sättet få programmet att ge resultat inom en acceptabel tid.

Syftet med detta kursarbeteär att få praktiska programmeringskunskaper i assemblerspråk.

Jobbmål:

1. Studera grundläggande information om Assembly-språket (struktur och komponenter i ett Assembly-program, kommandoformat, organisation av subrutiner, etc.);

2. Studera typerna av bitoperationer, format och logik för Assembler logiska instruktioner;

3. Lös ett individuellt problem om användningen av subrutiner i Assembly-språket;

4.. Formulera en slutsats om det utförda arbetet.

1 TEORETISKT AVSNITT

Assembly Language Basics

Assembler är ett programmeringsspråk på låg nivå, vilket är ett format för inspelning av maskinkommandon som är bekvämt för mänsklig uppfattning.

Assembly språkkommandon motsvarar ett till ett processorkommandon och representerar i själva verket en bekväm symbolisk form av inspelning (mnemonisk kod) av kommandon och deras argument. Assembly language tillhandahåller också grundläggande programmeringsabstraktioner: länkar samman programdelar och data genom symboliskt namngivna etiketter och direktiv.

Monteringsdirektiv tillåter dig att inkludera datablock (beskrivna explicit eller lästa från en fil) i ett program; upprepa ett visst fragment ett visst antal gånger; kompilera fragmentet enligt tillståndet; ställ in exekveringsadressen för ett fragment, ändra värdena för etiketter under kompileringsprocessen; använda makrodefinitioner med parametrar osv.

Fördelar och nackdelar

· minimal mängd redundant kod (användning av färre kommandon och minnesåtkomster). Som en konsekvens - hög hastighet och mindre programstorlek;

· stora mängder kod, ett stort antal ytterligare små uppgifter;

· dålig kodläsbarhet, svårighet att stödja (felsökning, lägga till funktioner);

· Svårigheten att implementera programmeringsparadigm och andra lite komplexa konventioner, komplexiteten i gemensam utveckling;

· färre tillgängliga bibliotek, deras låga kompatibilitet;

· direkt tillgång till hårdvara: in-/utgångsportar, speciella processorregister;

· maximal "passform" för den önskade plattformen (användning av speciella instruktioner, tekniska egenskaper"körtel");

· icke-portabilitet till andra plattformar (förutom binärt kompatibla).

Förutom instruktioner kan ett program innehålla direktiv: kommandon som inte översätts direkt till maskininstruktioner, men som styr kompilatorns funktion. Deras uppsättning och syntax varierar avsevärt och beror inte på hårdvaruplattformen, utan på kompilatorn som används (genererar dialekter av språk inom samma familj av arkitekturer). Uppsättningen av direktiv inkluderar:

· definition av data (konstanter och variabler);

· hantering av programorganisation i minne och utdatafilsparametrar;

· ställa in kompilatorns driftläge;

· alla typer av abstraktioner (dvs. element av högnivåspråk) - från utformningen av procedurer och funktioner (för att förenkla implementeringen av det procedurmässiga programmeringsparadigmet) till villkorliga konstruktioner och loopar (för det strukturerade programmeringsparadigmet);

· makron.

Kommandouppsättning

Typiska assemblerspråkkommandon är:

· Dataöverföringskommandon (mov, etc.)

Aritmetiska kommandon (lägg till, sub, imul, etc.)

Logiska och bitvisa operationer (eller, och, xor, shr, etc.)

· Kontrollkommandon för programkörning (jmp, loop, ret, etc.)

· Avbrottskommandon (ibland kallade kontrollkommandon): int

· I/O-kommandon till portar (in, ut)

Mikrokontroller och mikrodatorer kännetecknas också av kommandon som utför kontroller och övergångar baserat på förhållanden, till exempel:

· jne - hoppa om inte lika;

· jge - hoppa om större än eller lika med .

För att en maskin ska kunna utföra mänskliga kommandon på hårdvarunivå är det nödvändigt att specificera en viss sekvens av åtgärder på språket "nollor och ettor". Montören kommer att bli assistent i denna fråga. Detta är ett verktyg som fungerar med att översätta kommandon till maskinspråk. Att skriva ett program är dock en mycket arbetskrävande och komplex process. Detta språk är inte avsett att skapa lungor och enkla åtgärder. För tillfället låter alla programmeringsspråk som används (Assembler fungerar utmärkt) dig skriva speciella, effektiva uppgifter som i hög grad påverkar driften av hårdvaran. Huvudsyftet är att skapa mikroinstruktioner och små koder. Detta språk ger fler möjligheter än till exempel Pascal eller C.

En kort beskrivning av Assembly Languages

Alla programmeringsspråk är indelade i nivåer: låg och hög. Alla de syntaktiska systemen i Assembler-"familjen" kännetecknas av det faktum att det omedelbart kombinerar några av fördelarna med de vanligaste och modernaste språken. Gemensamt med andra är att de kan använda datorsystemet fullt ut.

En utmärkande egenskap hos kompilatorn är dess användarvänlighet. Detta skiljer den från de som bara arbetar med höga nivåer. Om du överväger något sådant programmeringsspråk, fungerar Assembler dubbelt så snabbt och bättre. För att skriva i den enkelt program, det tar inte för lång tid.

Kort om språkets struktur

Om vi ​​pratar generellt om språkets arbete och struktur kan vi med säkerhet säga att dess kommandon helt motsvarar processorkommandona. Det vill säga, assembler använder mnemoniska koder som är mest bekväma för en person att skriva.

Till skillnad från andra programmeringsspråk använder Assembly specifika etiketter istället för adresser för att skriva minnesceller. Tillsammans med kodexekveringsprocessen översätts de till så kallade direktiv. Dessa är relativa adresser som inte påverkar driften av processorn (inte översatta till maskinspråk), men som är nödvändiga för igenkänning av själva programmeringsmiljön.

Varje processorlinje har sin egen I denna situation kommer alla processer, inklusive den översatta, att vara korrekta

Assembly språk har flera syntaxer som kommer att diskuteras i artikeln.

Fördelar med språket

Den viktigaste och bekvämaste enheten i Assembly-språket är att du kan skriva vilket program som helst för processorn i det, vilket kommer att vara väldigt kompakt. Om koden visar sig vara enorm, omdirigeras vissa processer till RAM. Dessutom gör de allt ganska snabbt och utan misslyckanden, såvida de naturligtvis inte hanteras av en kvalificerad programmerare.

Drivrutiner, operativsystem, BIOS, kompilatorer, tolkar, etc. är alla program i Assembly-språk.

När du använder en disassembler som utför översättning från maskin till maskin kan du enkelt förstå hur den eller den systemuppgiften fungerar, även om det inte finns någon förklaring till det. Detta är dock bara möjligt om programmen är enkla. Tyvärr är icke-triviala koder ganska svåra att förstå.

Nackdelar med språket

Tyvärr har nybörjare (och ofta proffs) svårt att förstå språket. Montören kräver detaljerad beskrivningönskat kommando. På grund av behovet av att använda maskinkommandon ökar sannolikheten för felaktiga åtgärder och komplexiteten i exekveringen.

För att skriva ens det mesta ett enkelt program, programmeraren måste vara kvalificerad och hans kunskapsnivå är tillräckligt hög. Den genomsnittlige specialisten skriver tyvärr ofta dålig kod.

Om plattformen som programmet skapas för uppdateras måste alla kommandon skrivas om manuellt - detta krävs av själva språket. Samlaren stöder inte funktionen att automatiskt justera prestanda för processer och ersätta några element.

Språkkommandon

Som nämnts ovan har varje processor sin egen uppsättning kommandon. De enklaste elementen som känns igen av någon typ är följande koder:


Använda direktiv

Programmering av mikrokontroller i språket (Assembler tillåter detta och klarar av att fungera) på den lägsta nivån slutar i de flesta fall framgångsrikt. Det är bäst att använda processorer med begränsade resurser. För 32-bitars teknik givet språk passar perfekt. Du kan ofta se direktiv i kod. Vad är det här? Och vad används den till?

För det första är det nödvändigt att betona att direktiv inte översätts till maskinspråk. De reglerar hur kompilatorn gör jobbet. Till skillnad från kommandon skiljer sig dessa parametrar, som har olika funktioner, inte på grund av olika processorer, utan på grund av en annan översättare. Bland huvuddirektiven finns följande:


Namnets ursprung

Hur fick språket sitt namn - "Assembler"? Vi pratar om en översättare och en kompilator, som krypterar data. På engelska betyder Assembler inget annat än en assembler. Programmet sattes inte ihop manuellt; en automatisk struktur användes. Dessutom har användare och specialister för närvarande redan tappat skillnaden mellan termerna. Programmeringsspråk kallas ofta assembler, även om det bara är ett verktyg.

På grund av det vanliga samlingsnamnet tror vissa människor felaktigt att det finns ett enda lågnivåspråk (eller standardnormer för det). Så att programmeraren förstår vilken struktur vi pratar om, är det nödvändigt att klargöra för vilken plattform ett visst Assembly-språk används.

Makro betyder

Assembly-språk, som är relativt nya, har makrofunktioner. De gör det lättare att både skriva och köra ett program. Tack vare deras närvaro exekverar översättaren den skrivna koden många gånger snabbare. När du skapar ett villkorligt urval kan du skriva ett stort block av kommandon, men det är lättare att använda makroverktyg. De gör att du snabbt kan växla mellan åtgärder om ett villkor är uppfyllt eller inte.

När du använder makrospråkdirektiv tar programmeraren emot Assembler-makron. Ibland kan det användas flitigt, och ibland det funktionella egenskaper reduceras till ett lag. Deras närvaro i koden gör det lättare att arbeta med, vilket gör det mer begripligt och visuellt. Men du bör fortfarande vara försiktig - i vissa fall förvärrar makron tvärtom situationen.

Kommandostruktur i assemblerspråk Programmering på nivå med maskinkommandon är den lägsta nivån på vilken datorprogrammering är möjlig. Maskinens kommandosystem måste vara tillräckligt för att genomföra de nödvändiga åtgärderna genom att utfärda instruktioner till maskinutrustningen. Varje maskininstruktion består av två delar: en operationell, som bestämmer "vad man ska göra" och en operand, som bestämmer bearbetningsobjekten, det vill säga "vad man ska göra". En mikroprocessormaskininstruktion, skriven på Assembly-språk, är en enda rad som har följande form: etikettkommando/direktivoperand(er); kommentarer Etiketten, kommandot/direktivet och operanden är åtskilda av minst ett mellanslag eller tabbtecken. Kommandots operander separeras med kommatecken.

Assembly Language Kommandostruktur Ett assembler-kommando talar om för översättaren vilken åtgärd mikroprocessorn ska utföra. Monteringsdirektiv är parametrar som anges i programtexten som påverkar sammansättningsprocessen eller egenskaperna för utdatafilen. Operaanden anger det initiala värdet för datan (i datasegmentet) eller de element på vilka kommandoåtgärden utförs (i kodsegmentet). En instruktion kan ha en eller två operander, eller inga operander. Antalet operander anges implicit av instruktionskoden. Om ett kommando eller direktiv behöver fortsätta på nästa rad, används ett omvänt snedstreck: "" . Som standard skiljer assembler inte mellan stora och små bokstäver när du skriver kommandon och direktiv. Exempel på direktiv och kommandon Räkna db 1 ; Namn, direktiv, en operand mov eax, 0 ; Kommando, två operander

Identifierare är sekvenser av giltiga tecken som används för att beteckna variabelnamn och etikettnamn. Identifieraren kan bestå av ett eller flera av följande tecken: alla bokstäver i det latinska alfabetet; siffror från 0 till 9; specialtecken: _, @, $, ? . En prick kan användas som det första tecknet på etiketten. Reserverade assemblernamn (direktiv, operatorer, kommandonamn) kan inte användas som identifierare. Det första tecknet i identifieraren måste vara en bokstav eller ett specialtecken. Den maximala längden på en identifierare är 255 tecken, men översättaren accepterar de första 32 och ignorerar resten. Alla etiketter som är skrivna på en rad som inte innehåller ett assemblerdirektiv måste sluta med ett kolon ":". Etiketten, kommandot (direktivet) och operanden behöver inte starta på någon speciell position på raden. Det rekommenderas att skriva dem i en kolumn för bättre läsbarhet av programmet.

Etiketter Alla etiketter som är skrivna på en rad som inte innehåller ett assemblerdirektiv måste sluta med ett kolon ":". Etiketten, kommandot (direktivet) och operanden behöver inte starta på någon speciell position på raden. Det rekommenderas att skriva dem i en kolumn för bättre läsbarhet av programmet.

Kommentarer Att använda kommentarer i ett program förbättrar dess tydlighet, särskilt när syftet med en uppsättning kommandon är oklart. Kommentarer börjar på valfri rad i källmodulen med semikolon (;). Alla tecken till höger om "; " till slutet av raden finns en kommentar. En kommentar kan innehålla alla utskrivbara tecken, inklusive blanksteg. En kommentar kan sträcka sig över hela raden eller följa ett kommando på samma rad.

Assembly Language Programstruktur Ett program skrivet i assemblerspråk kan bestå av flera delar som kallas moduler, som var och en kan definiera en eller flera data-, stack- och kodsegment. Alla kompletta assemblerprogram måste inkludera en huvud- eller huvudmodul från vilken körningen börjar. En modul kan innehålla program, data och stacksegment, deklarerade med hjälp av lämpliga direktiv.

Minnesmodeller Innan du deklarerar segment måste du specificera minnesmodellen med hjälp av ett direktiv. MODELL modifierare memory_model, calling_convention, OS_type, stack_parameter Grundläggande minnesmodeller av assemblerspråk: Minnesmodell Kodadressering Dataadressering operativsystem Interleaving kod och data LITEN NÄRA MS-DOS Acceptabel LITEN NÄRA MS-DOS, Windows Inget MEDELLÅNGT NÄRA MS-DOS, Windows Inget KOMPAKT NÄRA FAR MS-DOS, Windows Inget STORT LÅNGT MS-DOS, Windows Inget ENORMT LÅNGT MS-DOS, Windows No NEAR Windows 2000, Windows XP, Windows Acceptable FLAT NEAR NT,

Minnesmodeller Den lilla modellen fungerar bara i 16-bitars MS-DOS-applikationer. I denna modell finns all data och kod på ett fysiskt segment. Storleken på programfilen i detta fall överstiger inte 64 KB. Den lilla modellen stöder ett kodsegment och ett datasegment. Data och kod adresseras så nära när denna modell används. Mediummodellen stöder flera kodsegment och ett datasegment, med alla referenser i kodsegment som standard som standard och referenser i ett datasegment anses vara nära. Den kompakta modellen stöder flera datasegment som använder fjärrdataadressering (fjärr), och ett kodsegment som använder nära adressering (nära). Den stora modellen stöder flera kodsegment och flera datasegment. Som standard anses alla referenser till kod och data långt. Den enorma modellen motsvarar nästan den stora minnesmodellen.

Minnesmodeller Den platta modellen antar en osegmenterad programkonfiguration och används endast i 32-bitars operativsystem. Denna modell liknar den lilla modellen genom att data och kod finns i ett enda segment, men den är 32-bitars. Att utveckla ett program för den platta modellen före direktivet. modell lägenhet bör placera en av direktiven: . 386, . 486, . 586 eller. 686. Valet av processorvalsdirektiv bestämmer uppsättningen av instruktioner som är tillgängliga när man skriver program. Bokstaven p efter processorvalsdirektivet betyder skyddat driftläge. Data- och kodadressering är nära, alla adresser och pekare är 32-bitars.

Minnesmodeller. MODELL modifier memory_model, calling_convention, OS_type, stack_parameter Modifieringsparametern används för att definiera segmenttyper och kan ha följande värden: använd 16 (segment av den valda modellen används som 16-bitars) använd 32 (segment av den valda modellen används som 32-bitars). Parametern calling_convention används för att bestämma metoden för att skicka parametrar när en procedur anropas från andra språk, inklusive högnivåspråk (C++, Pascal). Parametern kan ha följande värden: C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

Minnesmodeller. MODELL modifierare memory_model, calling_convention, OS_type, stack_parameter OS_type-parametern är OS_DOS som standard och är för närvarande det enda värdet som stöds för denna parameter. Parametern stack_parameter är satt till: NEARSTACK (SS-registret är lika med DS, data och stackareor är allokerade i samma fysiska segment) FARSTACK (SS-registret är inte lika med DS, data och stackareor är allokerade i olika fysiska segment). Standardvärdet är NEARSTACK.

Ett exempel på ett program som inte gör någonting. 686 P. MODELL PLAT, STDCALL. DATA. KOD START: RET END START RET - mikroprocessorkommando. Det säkerställer att programmet avslutas korrekt. Resten av programmet gäller driften av översättaren. . 686 P - Kommandon i skyddat läge Pentium 6 (Pentium II) är tillåtna. Detta direktiv väljer den uppsättning assemblerinstruktioner som stöds, som anger processormodellen. . MODELL FLAT, stdcall - platt minnesmodell. Denna minnesmodell används i Windows operativsystem. stdcall - den anropskonvention som används.

Ett exempel på ett program som inte gör någonting. 686 P. MODELL PLAT, STDCALL. DATA. KOD START: RET END START. DATA är ett programsegment som innehåller data. Detta program använder inte stacken, så segmentet. STACK saknas. . CODE är ett programsegment som innehåller kod. START - etikett. END START - slutet av programmet och ett meddelande till kompilatorn att programkörning ska börja med START-etiketten. Varje program måste innehålla ett END-direktiv för att markera slutet källkod program. Alla rader som följer END-direktivet ignoreras. Etiketten som anges efter END-direktivet berättar för översättaren namnet på huvudmodulen från vilken programkörningen börjar. Om programmet innehåller en modul kan etiketten efter END-direktivet utelämnas.

Montering språköversättare Översättare - program eller tekniska medel, som konverterar ett program på ett av programmeringsspråken till ett program på målspråket, kallat objektkod. Förutom att stödja maskinkommandominne, har varje översättare sin egen uppsättning direktiv och makroverktyg, ofta inkompatibla med något annat. Huvudtyperna av assemblerspråköversättare: MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler) - en fritt distribuerad multi-pass assembler skriven av Tomasz Gryshtar (polska), NASM (Netwide Assembler) - en gratis assembler för Intel x-arkitekturen 86, skapades av Simon Tatham med Julian Hall och utvecklas för närvarande av ett litet team av utvecklare på Source. Smedja. netto.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="Översätta ett program i Microsoft Visual Studio 2005 1) Skapa ett projekt genom att välja Arkiv->Ny- >Projektmeny Och"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В !} ytterligare alternativ I projektguiden, ange "Empty Project".

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="Översätta programmet i Microsoft Visual Studio 2005 2) I projektträdet (Visa->Solution Explorer) tillägga"> Трансляция программы в Microsoft Visual Studio 2005 2) В дереве проекта (View->Solution Explorer) добавить файл, в котором будет содержаться текст программы: Source. Files->Add->New. Item.!}

Översätta programmet till Microsoft Visual Studio 2005 3) Välj filtypen Code C++, men ange namnet med filtillägget. asm:

Översätta programmet till Microsoft Visual Studio 2005 5) Ställ in kompilatorparametrar. Välj efter höger knapp i projektfilen i menyn för anpassade byggregler...

Översätt programmet till Microsoft Visual Studio 2005 och välj Microsoft Macro Assembler i fönstret som visas.

Översättning av programmet i Microsoft Visual Studio 2005 Kontrollera med höger knapp i filen hej. asm projektträd i menyn Egenskaper och installera Allmänt->Verktyg: Microsoft Macro Assembler.

Src="https://present5.com/presentation/-29367016_63610977/image-22.jpg" alt="Översätta programmet i Microsoft Visual Studio 2005 6) Kompilera filen genom att välja Bygg->Bygg hej. prj."> Трансляция программы в Microsoft Visual Studio 2005 6) Откомпилировать файл, выбрав Build->Build hello. prj. 7) Запустить программу, нажав F 5 или выбрав меню Debug->Start Debugging.!}

Programmering i Windows OS Programmering i Windows OS är baserad på användningen av API-funktioner (Application Program Interface, dvs. programvara). Deras antal når 2000. Windows-programmet består till stor del av sådana samtal. Alla interaktioner med externa enheter och operativsystemsresurser uppstår, som regel, genom sådana funktioner. operationssalen Windows-system använder en platt minnesmodell. Adressen för valfri minnescell kommer att bestämmas av innehållet i ett 32-bitars register. Det finns 3 typer av programstrukturer för Windows: dialog (huvudfönstret är dialog), konsol eller fönsterlös struktur, klassisk struktur (fönster, ram).

Anropsfunktioner Windows API I hjälpfilen presenteras valfri API-funktion i formen funktionsnamn typ (FA 1, FA 2, FA 3) Typ – typ av returvärde; FAx – en lista över formella argument i den ordning de visas. Till exempel int Message. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Typ); Denna funktion visar ett fönster med ett meddelande och en utgångsknapp (eller -knappar). Betydelse av parametrar: h. Wnd är en beskrivning av fönstret där meddelandefönstret kommer att visas, lp. Text - text som visas i fönstret, lp. Bildtext - text i fönstrets titel, u. Typ - fönstertyp i synnerhet, du kan bestämma antalet utgångsknappar.

Samtal Windows funktioner API int meddelande. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Typ); Nästan alla API-funktionsparametrar är faktiskt 32-bitars heltal: HWND är ett 32-bitars heltal, LPCTSTR är en 32-bitars pekare till en sträng, UINT är ett 32-bitars heltal. Suffixet "A" läggs ofta till funktionsnamnet för att flytta till nyare versioner av funktionen.

Anropar Windows API int Message-funktioner. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Typ); När du använder MASM måste du lägga till @N N i slutet av namnet - antalet byte som de godkända argumenten upptar på stacken. För Win 32 API-funktioner kan detta antal definieras som antalet argument n multiplicerat med 4 (byte i varje argument): N=4*n. För att anropa en funktion, använd assembler CALL-instruktionen. I det här fallet skickas alla argument till funktionen till den via stacken (PUSH-kommandot). Riktning för att skicka argument: VÄNSTER TILL HÖGER - NEDAN UPP. Argumentet u kommer att skjutas upp på stapeln först. Typ. Anropet till den angivna funktionen kommer att se ut så här: CALL-meddelande. Låda. A@16

Anropar Windows API int Message-funktioner. Box(HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Caption, UINT u. Typ); Resultatet av att köra valfri API-funktion är vanligtvis ett heltal som returneras i EAX-registret. OFFSET-direktivet representerar en "offset i ett segment", eller, översatt till högnivåspråkliga termer, en "pekare" till början av en rad. EQU-direktivet, liksom #define i SI, definierar en konstant. EXTERN-direktivet talar om för översättaren att funktionen eller identifieraren är extern till denna modul.

Exempel på ett "Hej alla!"-program . 686 P. MODELL PLAT, STDCALL. STACK 4096. DATA MB_OK EQU 0 STR 1 DB "Mitt första program", 0 STR 2 DB "Hej alla!", 0 HW DD ? EXTERN Meddelande. Låda. A@16: NÄRA. KOD START: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Meddelande. Låda. A@16 RET SLUT START

INVOKE-direktivet MASM-språköversättaren låter dig också förenkla funktionsanrop med hjälp av ett makroverktyg - INVOKE-direktivet: INVOKE-funktion, parameter1, parameter2, ... Det finns inget behov av att lägga till @16 ​​till funktionsanropet; parametrar skrivs exakt i den ordning som de anges i funktionsbeskrivningen. Med hjälp av makro med hjälp av översättaren placeras parametrar på stacken. För att använda INVOKE-direktivet måste du ha en beskrivning av funktionsprototypen med hjälp av PROTO-direktivet i formen: Meddelande. Låda. ETT PROTO: DWORD, : DWORD Om ett program använder många Win 32 API-funktioner, är det lämpligt att använda inkluderingsdirektivet C: masm 32includeuser 32. inc



Om du upptäcker ett fel markerar du ett textstycke och trycker på Ctrl+Enter
DELA: