Grundläggande assemblerspråkkomponenter och kommandostruktur. Allmänna egenskaper hos Assembler-språkinstruktionssystemet för IBM-PC (grundläggande instruktionsuppsättning, huvudoperandadresseringsmetoder)

Grundläggande assemblerspråkkomponenter och kommandostruktur.  Allmänna egenskaper hos Assembler-språkinstruktionssystemet för IBM-PC (grundläggande instruktionsuppsättning, huvudoperandadresseringsmetoder)
Grundläggande assemblerspråkkomponenter och kommandostruktur. Allmänna egenskaper hos Assembler-språkinstruktionssystemet för IBM-PC (grundläggande instruktionsuppsättning, huvudoperandadresseringsmetoder)

Ämne 2.5 Processorprogrammering Grundläggande

När programmets längd ökar blir det svårare att komma ihåg koderna för olika operationer. Mnemonics ger lite hjälp i detta avseende.

Det symboliska instruktionskodningsspråket kallas assemblerare.

assembleringsspråkär ett språk där varje påstående motsvarar exakt en maskininstruktion.

hopsättning kallas att konvertera ett program från assemblerspråk, dvs förbereda ett program på maskinspråk genom att ersätta symboliska namn på operationer med maskinkoder och symboliska adresser med absoluta eller relativa tal, samt inkludera biblioteksprogram och generera sekvenser av symboliska instruktioner genom att specificera specifika parametrar i mikroinstruktioner. Det här programmet vanligtvis placerad i ROM eller inmatad i RAM från något externt medium.

Assembly språk har flera funktioner som skiljer det från högnivåspråk:

1. Detta är en en-till-en-överensstämmelse mellan assembly-språkpåståenden och maskininstruktioner.

2. Assemblyspråksprogrammeraren har tillgång till alla objekt och kommandon som finns på målmaskinen.

En förståelse för grunderna för programmering i maskinorienterade språk är användbar för:



Bättre förståelse för PC-arkitektur och bättre användning av datorer;

Att utveckla mer rationella strukturer av algoritmer för program för att lösa tillämpade problem;

Möjligheten att visa och korrigera körbara program med tilläggen .exe och .com, kompilerade från alla högnivåspråk, i händelse av förlust av källprogrammen (genom att anropa dessa program till DEBUG-programfelsökningen och dekompilera deras visning i assemblerspråk );

Sammanställning av program för att lösa de mest kritiska uppgifterna (ett program sammanställt i ett maskinorienterat språk är vanligtvis effektivare - kortare och snabbare med 30-60 procent än program som erhålls som ett resultat av översättning från högnivåspråk)

För implementering av procedurer som ingår i huvudprogrammet som separata fragment i händelse av att de inte kan implementeras vare sig på det högnivåspråk som används eller med OS-tjänstprocedurer.

Ett assemblerspråksprogram kan bara köras på datorer i samma familj, medan ett program skrivet på ett högnivåspråk potentiellt kan köras på olika maskiner.

Assembly-språkalfabetet består av ASCII-tecken.

Tal är bara heltal. Skilja på:

binära tal, avsluta med bokstaven B;

Decimaltal som slutar med D;

Hexadecimala tal, som slutar med bokstaven N.

Bagge, register, datarepresentation

För en viss serie riksdagsledamöter används ett individuellt programmeringsspråk - assemblerspråk.

Assembly språk intar en mellanposition mellan maskinkoder och högnivåspråk. Programmering på detta språk är lättare. Ett assemblerspråksprogram använder kapaciteten hos en viss maskin (mer exakt MP) mer rationellt än ett program på ett högnivåspråk (vilket är lättare för en programmerare än assembler). Vi kommer att överväga de grundläggande principerna för programmering i maskinorienterade språk med hjälp av assemblerspråket för MP KR580VM80 som ett exempel. För programmering i språket används en allmän teknik. Specifika tekniker för inspelning av program är relaterade till arkitekturen och kommandosystemets egenskaper hos mål-MP.

Mjukvarumodell mikroprocessorsystem baserad på MP KR580VM80

Programmodellen för MPS i enlighet med figur 1

MP-portar minne

S Z AC P C

Bild 1

Ur programmerarens synvinkel har KR580VM80 MP följande programtillgängliga register.

A– 8-bitars ackumulatorregister. Det är MP:s huvudregister. Varje operation som utförs i ALU involverar att placera en av operanderna som ska behandlas i ackumulatorn. Resultatet av operationen i ALU lagras också vanligtvis i A.

B, C, D, E, H, L– 8-bitars register för allmänna ändamål (RON). Inre minne MP. Designad för att lagra den bearbetade informationen, såväl som resultatet av operationen. Vid bearbetning av 16-bitars ord från registren bildas paren BC, DE, HL, och dubbelregistret kallas första bokstaven - B, D, H. I registerparet är det första registret det högsta. H, L-registren, som används både för att lagra data och för att lagra 16-bitars adresser för RAM-celler, har en speciell egenskap.

FL– flaggregister (funktionsregister) Ett 8-bitars register som lagrar fem funktioner för resultatet av aritmetiska och logiska operationer i MP. FL-format enligt bilden

Bit C (CY - bär) - bär, satt till 1 om det fanns en bäring från bytens höga ordning vid utförande av aritmetiska operationer.

Bit P (paritet) - paritet, sätts till 1 om antalet enheter i bitarna i resultatet är jämnt.

AC-biten är en extra överföring, utformad för att lagra överföringsvärdet från den nedre tetraden av resultatet.

Bit Z (noll) - sätt till 1 om resultatet av operationen är 0.

S-biten (tecken) sätts till 1 om resultatet är negativt och till 0 om resultatet är positivt.

SP-- stackpekaren, ett 16-bitars register, är utformad för att lagra adressen till minnesplatsen där den sista byten som skrevs in i stacken skrevs.

RS– programräknare (programräknare), 16-bitars register, utformad för att lagra adressen till nästa exekverbara instruktion. Programräknarens innehåll ökas automatiskt med 1 omedelbart efter att nästa instruktionsbyte har hämtats.

I det initiala minnesområdet på adressen 0000H - 07FF finns ett kontrollprogram och demoprogram. Detta är ROM-området.

0800 - 0AFF - adressområde för inspelning av de program som studeras. (BAGGE).

0В00 - 0ВВ0 - adressområde för dataregistrering. (BAGGE).

0BB0 är startadressen för stacken. (BAGGE).

Stack är ett speciellt organiserat område av RAM designat för tillfällig lagring av data eller adresser. Det sista numret som skjuts upp på högen är det första numret som hoppade av stapeln. Stackpekaren lagrar adressen till den sista stackplatsen där informationen lagras. När en subrutin anropas lagras returadressen till huvudprogrammet automatiskt i stacken. Som regel, i början av varje subrutin, lagras innehållet i alla register som är involverade i dess exekvering i stacken, och i slutet av subrutinen återställs de från stacken.

Assembly Language Data Format och Kommandostruktur

Minne MP KR580VM80 är en array av 8-bitars ord som kallas bytes. Varje byte har sin egen 16-bitars adress som bestämmer dess position i sekvensen av minnesceller. MP kan adressera 65536 byte minne, som kan innehålla både ROM och RAM.

Dataformat

Data lagras i minnet som 8-bitars ord:

D7 D6 D5 D4 D3 D2 D1 D0

Den minst signifikanta biten är bit 0, den mest signifikanta biten är bit 7.

Kommandot kännetecknas av formatet, det vill säga antalet bitar som tilldelats för det, vilka är uppdelade byte-för-byte i vissa funktionella fält.

Kommandoformat

MP KR580VM80-kommandon har en, två eller tre-byte format. Multi-byte instruktioner måste placeras i angränsande PLs. Formatet på kommandot beror på detaljerna för den operation som utförs.

Den första byten av kommandot innehåller op-koden skriven i mnemonisk form.

Den definierar formatet för kommandot och de åtgärder som måste utföras av MP på data under dess exekvering, och metoden för adressering, och kan även innehålla information om var data finns.

Den andra och tredje byten kan innehålla data som ska opereras på, eller adresser som indikerar platsen för data. De data som operationer utförs på kallas operander.

Single-byte kommandoformat enligt figur 2

Figur 4

I monteringsspråksinstruktioner har opkoden en förkortad form för att skriva engelska ord - en mnemonisk notation. Mnemonics (från grekiskans mnemonic - konsten att memorera) gör det lättare att komma ihåg kommandon enligt deras funktionella syfte.

Före körning översätts källprogrammet med hjälp av ett översättningsprogram, kallat assembler, till språket för kodkombinationer - maskinspråk, i denna form placeras det i MP:ns minne och används sedan när kommandot utförs.


Adresseringsmetoder

Alla operandkoder (ingång och utgång) måste finnas någonstans. De kan finnas i MP:s interna register (det mest bekväma och snabbaste alternativet). De kan finnas i system minne(det vanligaste alternativet). Slutligen kan de finnas i I/O-enheter (det sällsynta fallet). Placeringen av operanderna bestäms av instruktionskoden. Det finns olika metoder genom vilka instruktionskoden kan bestämma var den ingående operanden ska hämtas från och var den ska placeras. Dessa metoder kallas adresseringsmetoder.

För MP KR580VM80 finns följande adresseringsmetoder:

Omedelbar;

Registrera;

indirekt;

Stack.

Omedelbar adressering förutsätter att operanden (ingången) finns i minnet omedelbart efter instruktionskoden. Operanden är vanligtvis en konstant som behöver skickas någonstans, läggas till något, etc. data finns i kommandots andra eller andra och tredje byte, med lågdatabyten i den andra kommandobyten och högdatabyten i den tredje kommandobyten.

Hetero (aka absolut) adressering förutsätter att operanden (ingång eller utgång) finns i minnet på adressen vars kod finns inuti programmet omedelbart efter instruktionskoden. Används i tre-byte-kommandon.

Registrera adressering förutsätter att operanden (ingång eller utgång) finns i det interna MP-registret. Används i enkelbyte-kommandon

Indirekt (implicit) adressering förutsätter att MP:ns interna register inte är operanden i sig, utan dess adress i minnet.

Stack adressering förutsätter att kommandot inte innehåller en adress. Adressering till minnesceller med innehållet i 16-bitars SP-registret (stackpekare).

Kommandosystem

MP-kommandosystemet är en komplett lista över elementära åtgärder som MP kan utföra. MP som kontrolleras av dessa kommandon utför enkla steg, såsom elementär aritmetik och logiska operationer, dataöverföring, jämförelse av två värden, etc. Antalet kommandon MP KR580VM80 - 78 (inklusive modifieringar 244).

Det finns följande grupper av kommandon:

Dataöverföring;

Aritmetisk;

Hjärngymnastik;

Hoppa kommandon;

Kommandon för input-output, kontroll och arbete med stacken.


Symboler och förkortningar som används för att beskriva kommandon och skriva program

Symbol Minskning
ADDR 16 bitars adress
DATA 8-bitars data
DATA 16 16 bitars data
HAMN 8-bitars I/O-adress (I/O-enheter)
BYTE 2 Andra kommandobyte
BYTE 3 Tredje kommandobyte
R, Rl, R2 Ett av registren: A, B, C, D, E, H, L
RP Ett av registerparen: B - sätter ett flygplanspar; D - sätter ett par DE; H - anger ett par HL
RH Första registret av paret
RL Andra register av paret
Λ Boolesk multiplikation
V Boolean addition
Modulo två tillägg
M Minnescell vars adress anger innehållet i HL-registerparet, dvs M = (HL)

Strukturer i assemblerspråk

De arrayer vi har övervägt ovan är en samling element av samma typ. Men ofta i applikationer finns det ett behov av att överväga en viss uppsättning data annan typ som någon enskild typ.

Detta är mycket relevant, till exempel för databasprogram, där det är nödvändigt att associera en samling data av olika typer till ett objekt.

Till exempel tittade vi tidigare på Listing 4, som fungerade med en array av tre-byte element. Varje element var i sin tur två element av olika typer: ett en-byte räknarfält och ett två-byte fält som kunde bära lite mer information som behövs för lagring och bearbetning. Om läsaren är bekant med ett av högnivåspråken, då vet han att ett sådant objekt vanligtvis beskrivs med en speciell datatyp - strukturer.

För att förbättra användbarheten av assemblerspråk introducerades även denna datatyp i det.

A-priory strukturera är en datatyp som består av ett fast antal element av olika typer.

För att använda strukturer i ett program måste du göra tre saker:

    Fråga strukturmall .

    Detta innebär i huvudsak att definiera en ny datatyp, som senare kan användas för att definiera variabler av denna typ.

    Definiera strukturinstans .

    Detta steg innebär initiering av en specifik variabel med en fördefinierad (med hjälp av en mall) struktur.

    Organisera åtkomst till strukturmedlemmar .

Det är mycket viktigt att du redan från början förstår vad som är skillnaden mellan beskrivning strukturer i programmet och dess definition.

beskriva struktur i ett program betyder endast att indikera dess schema eller mönster; minne är inte tilldelat.

Denna mall kan endast betraktas som information för översättaren om fältens placering och deras standardvärde.

Definiera struktur betyder att instruera översättaren att allokera minne och tilldela ett symboliskt namn till detta minnesområde.

Du kan bara beskriva strukturen i programmet en gång och definiera den hur många gånger som helst.

Beskrivning av strukturmall

Strukturmallsdeklaration har följande syntax:

strukturnamn STRUC

strukturnamn SLUTAR

Här är en sekvens av databeskrivningsdirektiv db, dw, dd, dq Och dt.

Deras operander bestämmer storleken på fälten och eventuellt initiala värden. Dessa värden kommer möjligen att initiera motsvarande fält när strukturen är definierad.

Som vi redan noterade när vi beskrev mallen, tilldelas inget minne, eftersom detta bara är information för översättaren.

Plats mallen i programmet kan vara godtycklig, men enligt logiken hos enpassöversättaren måste den placeras före den plats där variabeln med typen av denna struktur definieras. Det vill säga, när man beskriver en variabel med typen av någon struktur i ett datasegment, måste dess mall placeras i början av datasegmentet eller före det.

Överväg att arbeta med strukturer med hjälp av exemplet att modellera en databas med anställda på en viss avdelning.

För enkelhets skull, för att komma bort från problemen med informationskonvertering under inmatning, kommer vi överens om att alla fält är symboliska.

Låt oss definiera poststrukturen för denna databas med följande mönster:

Definiera data med en strukturtyp

För att använda strukturen som beskrivs med hjälp av mallen i programmet är det nödvändigt att definiera en variabel med typen av denna struktur. Följande syntax används för detta:

[variabelnamn] strukturnamn

    variabelnamn- variabelidentifierare av den givna strukturtypen.

    Att ange ett variabelnamn är valfritt. Om det inte är specificerat kommer ett minnesområde med storleken på summan av längderna för alla element i strukturen helt enkelt att tilldelas.

    värdelista- en kommaseparerad lista över initiala värden för strukturelement inom vinkelparenteser.

    Hans uppgift är också frivillig.

    Om listan är ofullständig, initieras alla fält i strukturen för den givna variabeln med värden från mallen, om några.

    Det är tillåtet att initiera enskilda fält, men i detta fall måste de saknade fälten separeras med kommatecken. Saknade fält kommer att initieras med värden från structmallen. Om vi, när vi definierar en ny variabel med typen av denna struktur, håller med alla fältvärdena i dess mall (det vill säga inställda som standard), behöver du bara skriva vinkelparenteser.

    T.ex: segrararbetare.

Låt oss till exempel definiera flera variabler med den typ av struktur som beskrivs ovan.

Strukturmetoder

Tanken med att introducera en strukturell typ i alla programmeringsspråk är att kombinera variabler av olika typer till ett objekt.

Språket måste tillhandahålla ett sätt att komma åt dessa variabler inom en viss strukturinstans. För att i ett kommando referera till ett fält av någon struktur, används en speciell operator - symbol ". " (prick). Det används i följande syntax:

    adressuttryck- en variabelidentifierare av någon strukturell typ eller ett uttryck inom parentes i enlighet med syntaxreglerna som anges nedan (fig. 1);

    strukturfältsnamn- fältnamn från strukturmall.

    Detta är faktiskt också en adress, eller snarare, förskjutningen av fältet från början av strukturen.

Så operatören " . " (punkt) utvärderar uttrycket

Ris. 5. Syntax för ett adressuttryck i en strukturfältåtkomstoperator

Låt oss demonstrera på exemplet på strukturen vi har definierat arbetstagare några tekniker för att arbeta med strukturer.

Till exempel, extrahera till yxa fältvärden med ålder. Eftersom det är osannolikt att åldern på en arbetsför person kommer att vara mer än 99 år, efter att ha placerat innehållet i detta teckenfält i registret yxa det kommer att vara bekvämt att konvertera den till binär representation med kommandot aad.

Var försiktig, eftersom på grund av principen om datalagring "låg byte vid låg adress" den högsta siffran i åldern kommer att placeras i al, och den yngsta i ah.

För att korrigera det, använd bara kommandot xchg al, ah:

mov ax,ord ptr sotr1.ålder ;at al ålder sotr1

och det är möjligt så här:

Ytterligare arbete med en rad strukturer utförs på samma sätt som med en endimensionell matris. Flera frågor uppstår här:

Hur hanterar man storleken och hur man organiserar indexeringen av arrayelement?

Liksom andra identifierare som definieras i programmet, tilldelar översättaren namnet på strukturtypen och namnet på variabeln med strukturtypen ett typattribut. Värdet på detta attribut är storleken i byte som upptas av fälten i denna struktur. Du kan extrahera detta värde med operatorn typ.

När storleken på en strukturinstans väl har blivit känd är det inte särskilt svårt att organisera indexering i en rad strukturer.

T.ex:

Hur kopierar man ett fält från en struktur till motsvarande fält i en annan struktur? Eller hur kopierar man hela strukturen? Låt oss kopiera fältet nam tredje anställd på området nam femte anställd:

mas_sotr worker 10 dup()

mov bx,offset mas_sotr

mov si,(typ arbetare)*2 ;si=77*2

mov di,(typ arbetare)*4 ;si=77*4

Det verkar för mig att hantverket av en programmerare förr eller senare får en person att se ut som en bra hemmafru. Han, liksom hon, är ständigt på jakt efter var man kan spara något, skära ner och göra en underbar middag av ett minimum av mat. Och om detta lyckas, så är den moraliska tillfredsställelsen inte mindre, och kanske mer, än från en underbar middag hos hemmafrun. Graden av denna tillfredsställelse, förefaller det mig, beror på graden av kärlek till ens yrke.

Å andra sidan avslappnar framsteg i utvecklingen av mjukvara och hårdvara programmeraren något, och ganska ofta finns det en situation som liknar det välkända ordspråket om flugan och elefanten - för att lösa ett litet problem är tunga verktyg inblandade, vars effektivitet i det allmänna fallet endast är betydande vid genomförandet av relativt stora projekt.

Närvaron på språket för följande två typer av data beror förmodligen på "värdinnans" önskan att använda arbetsområdet på bordet (RAM) så effektivt som möjligt när du lagar mat eller för att placera produkter (programdata ).

Programmering på maskininstruktionsnivå är den lägsta nivån på vilken programmering är möjlig. Systemet med maskininstruktioner måste vara tillräckligt för att genomföra de nödvändiga åtgärderna genom att utfärda instruktioner till datorhårdvaran.

Varje maskininstruktion består av två delar:

  • operationssal - bestämma "vad man ska göra";
  • operand - definierar bearbetningsobjekt, "vad man ska göra med".

Maskininstruktionen för mikroprocessorn, skriven i assemblerspråk, är en enda rad med följande syntaktiska form:

etikett kommando/direktiv operand(er) ;kommentarer

Vart i obligatoriskt fält in line är ett kommando eller direktiv.

Etiketten, kommandot/direktivet och operander (om några) är åtskilda av minst ett mellanslag eller tabbtecken.

Om ett kommando eller direktiv behöver fortsätta på nästa rad, används bakstrecket: \.

Som standard skiljer inte assemblerspråk mellan stora och små bokstäver i kommandon eller direktiv.

Exempel på kodrader:

Countdb 1 ;Namn, direktiv, en operand
mov eax,0 ;Kommando, två operander
cbw ; Team

Taggar

Märka i assemblerspråk kan innehålla följande symboler:

  • alla bokstäver i det latinska alfabetet;
  • siffror från 0 till 9;
  • specialtecken: _, @, $, ?.

En prick kan användas som det första tecknet i en etikett, men vissa kompilatorer avråder från detta tecken. Reserverade assembly-språknamn (direktiv, operatorer, kommandonamn) kan inte användas som etiketter.

Det första tecknet i etiketten måste vara en bokstav eller ett specialtecken (inte en siffra). Den maximala etikettlängden är 31 tecken. Alla etiketter som är skrivna på en rad som inte innehåller ett assemblerdirektiv måste sluta med ett kolon: .

Lag

Team talar om för översättaren vilken åtgärd mikroprocessorn ska utföra. I ett datasegment definierar ett kommando (eller direktiv) ett fält, en arbetsyta eller en konstant. I ett kodsegment definierar en instruktion en åtgärd, såsom ett drag (mov) eller ett tillägg (lägg till).

direktiv

Montören har ett antal operatörer som låter dig styra processen för att montera och generera en lista. Dessa operatörer kallas direktiv . De agerar bara i processen att montera programmet och, till skillnad från instruktioner, genererar inte maskinkoder.

operander

Operand – ett objekt på vilket ett maskinkommando eller en programmeringsspråksoperatör exekveras.
En instruktion kan ha en eller två operander, eller inga operander alls. Antalet operander anges implicit av instruktionskoden.
Exempel:

  • Inga operander ret ;Retur
  • En operand inc ecx ;Öka ecx
  • Två operander lägger till eax,12 ;Lägg till 12 till eax

Etiketten, kommandot (direktivet) och operanden behöver inte starta på någon speciell position i strängen. Det rekommenderas dock att skriva dem i en kolumn för bättre läsbarhet av programmet.

Operander kan vara

  • identifierare;
  • teckensträngar omslutna av enkla eller dubbla citattecken;
  • heltal i binära, oktala, decimala eller hexadecimala.
Identifierare

Identifierare – sekvenser av giltiga tecken som används för att beteckna programobjekt såsom operationskoder, variabelnamn och etikettnamn.

Regler för att skriva identifierare.

  • Identifieraren kan vara ett eller flera tecken.
  • Som tecken kan du använda bokstäver i det latinska alfabetet, siffror och några speciella karaktärer: _, ?, $, @.
  • En identifierare kan inte börja med ett siffror.
  • ID:t kan vara upp till 255 tecken långt.
  • Översättaren accepterar de första 32 tecknen i identifieraren och ignorerar resten.
Kommentarer

Kommentarer separeras från den körbara raden med ett tecken; . I det här fallet är allt som skrivs efter semikolontecknet och fram till slutet av raden en kommentar. Användningen av kommentarer i ett program förbättrar dess tydlighet, särskilt när syftet med en uppsättning instruktioner är oklart. Kommentaren kan innehålla alla utskrivbara tecken, inklusive mellanslag. Kommentaren kan sträcka sig över hela raden eller följa kommandot på samma rad.

Monteringsprogrammets struktur

Ett program skrivet på assemblerspråk kan bestå av flera delar, så kallade moduler . Varje modul kan definiera ett eller flera data-, stack- och kodsegment. Alla kompletta assemblerspråksprogram måste innehålla en huvud- eller huvudmodul från vilken exekveringen börjar. En modul kan innehålla kod, data och stacksegment som deklareras med lämpliga direktiv. Innan du deklarerar segment måste du ange minnesmodellen med .MODEL-direktivet.

Ett exempel på ett "gör ingenting"-program i assemblerspråk:

686P
.MODEL FLAT, STDCALL
.DATA
.KODA
START:

RÖTA
SLUT START

Detta program innehåller endast en mikroprocessorinstruktion. Detta kommando är RET. Det säkerställer att programmet avslutas korrekt. I allmänhet används detta kommando för att avsluta en procedur.
Resten av programmet är relaterat till översättarens funktion.
.686P - Kommandon i skyddat läge Pentium 6 (Pentium II) är tillåtna. Detta direktiv väljer den assemblerinstruktionsuppsättning som stöds genom att specificera processormodellen. Bokstaven P i slutet av direktivet talar om för översättaren att processorn körs i skyddat läge.
.MODEL FLAT, stdcall är en platt minnesmodell. Denna minnesmodell används i Windows operativsystem. stdcall
.DATA är ett programsegment som innehåller data.
.CODE är ett programblock som innehåller kod.
START är en etikett. I assembler spelar etiketter en stor roll, vilket inte kan sägas om moderna högnivåspråk.
END START - slutet av programmet och ett meddelande till översättaren att programmet måste startas från etiketten START.
Varje modul måste innehålla ett END-direktiv som markerar slutet på programmets källkod. Alla rader som följer END-direktivet ignoreras. Att utelämna END-direktivet genererar ett fel.
Etiketten efter END-direktivet talar om för kompilatorn namnet på huvudmodulen från vilken programkörningen börjar. Om programmet innehåller en modul kan etiketten efter END-direktivet utelämnas.

Instruktionsstruktur för monteringsspråk Programmering på maskininstruktionsnivå är den lägsta nivån på vilken datorprogrammering är möjlig. Systemet med maskininstruktioner måste vara tillräckligt för att genomföra de nödvändiga åtgärderna genom att utfärda instruktioner till maskinvaran. Varje maskininstruktion består av två delar: en driftsdel som definierar "vad man ska göra" och en operand som definierar bearbetningsobjekt, det vill säga "vad man ska göra". Mikroprocessorns maskininstruktion, skriven på Assembly-språk, är en enkel rad, med följande form: etikettinstruktion/direktivoperand(er) ; kommentarer Etiketten, kommandot/direktivet och operanden är åtskilda av minst ett mellanslag eller tabbtecken. Instruktionsoperanderna separeras med kommatecken.

Struktur för en assemblerspråksinstruktion En assemblerspråksinstruktion talar om för kompilatorn vilken åtgärd mikroprocessorn ska utföra. Monteringsdirektiv är parametrar som anges i programtexten som påverkar sammansättningsprocessen eller egenskaperna för utdatafilen. Operanden specificerar det initiala värdet för datan (i datasegmentet) eller de element som instruktionen ska agera på (i kodsegmentet). En instruktion kan ha en eller två operander, eller inga operander. Antalet operander anges implicit av instruktionskoden. Om kommandot eller direktivet behöver fortsätta på nästa rad, används ett omvänt snedstreck: "" . Som standard skiljer inte assemblern mellan stora och små bokstäver i kommandon och direktiv. Direktiv och kommandoexempel 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 identifieringslängden är 255 tecken, men översättaren accepterar de första 32 tecknen 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 i strängen. 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 i strängen. Det rekommenderas att skriva dem i en kolumn för bättre läsbarhet av programmet.

Kommentarer Användningen av kommentarer i ett program förbättrar dess tydlighet, särskilt när syftet med en uppsättning instruktioner är oklart. Kommentarer börjar på valfri rad källmodul med semikolon (;). Alla tecken till höger om "; ' till slutet av raden finns kommentarer. Kommentaren kan innehålla alla utskrivbara tecken, inklusive "mellanslag". Kommentaren kan sträcka sig över hela raden eller följa kommandot på samma rad.

Struktur för ett assemblerspråksprogram Ett assemblerspråksprogram kan bestå av flera delar, kallade moduler, som var och en kan definiera ett eller flera data-, stack- och kodsegment. Alla kompletta assemblerspråksprogram måste innehålla en huvud- eller huvudmodul från vilken exekveringen börjar. En modul kan innehålla program, data och stacksegment som deklareras med lämpliga direktiv.

Minnesmodeller Innan du deklarerar segment måste du ange minnesmodellen med hjälp av ett direktiv. MODELL modifierare memory_model, calling_convention, OS_type, stack_parameter Grundläggande assemblerspråk minnesmodeller: Minnesmodell Kodadressering Dataadressering operativ system Kod- och datainterleaving LITEN NÄRA MS-DOS Tillåten LITEN NÄRA MS-DOS, Windows Inget MEDIUM LÅ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 Tillåtet FLAT NEAR NT,

Minnesmodeller Den lilla modellen fungerar bara i 16-bitars MS-DOS-applikationer. I denna modell finns all data och kod i 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 vid användning av denna modell adresseras som nära (nära). Mediemodellen stöder flera kodsegment och ett datasegment, där alla länkar i kodsegmenten anses vara långt (avlägset) som standard, och länkar i datasegmentet anses vara nära (nära). Den kompakta modellen stöder flera datasegment som använder fjärrdataadressering (fjärr) och ett kodsegment som använder näradataadressering (nära). Den stora modellen stöder flera kodsegment och flera datasegment. Som standard anses all kod och datareferenser vara långt borta. Den enorma modellen motsvarar nästan den stora minnesmodellen.

Minnesmodeller Den platta modellen antar en icke-segmenterad programkonfiguration och används endast på 32-bitars operativsystem. Denna modell liknar den lilla modellen genom att data och kod finns i samma 32-bitars segment. 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 processorvalsdirektivet bestämmer uppsättningen av kommandon som är tillgängliga när man skriver program. Bokstaven p efter processorvalsdirektivet betyder skyddat driftsätt. 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). Calling_convention-parametern används för att bestämma hur parametrar skickas 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 på det här ögonblicket detta är det enda värdet som stöds för denna parameter. Parametern stack_param är satt till: NEARSTACK (SS-registret är lika med DS, data och stackregioner är belägna i samma fysiska segment) FARSTACK (SS-registret är inte lika med DS, data och stackregioner är placerade i olika fysiska segment). Standard är NEARSTACK.

Ett exempel på ett "att göra ingenting"-program. 686 P. MODELL PLAT, STDCALL. DATA. KOD START: RET END START RET - mikroprocessorkommando. Det säkerställer att programmet avslutas korrekt. Resten av programmet är relaterat till översättarens funktion. . 686 P - Kommandon i skyddat läge Pentium 6 (Pentium II) är tillåtna. Detta direktiv väljer den assemblerinstruktionsuppsättning som stöds genom att specificera processormodellen. . MODELL FLAT, stdcall - platt minnesmodell. Denna minnesmodell används i Windows operativsystem. stdcall är proceduren som anropar konventionen att använda.

Ett exempel på ett "att göra ingenting"-program. 686 P. MODELL PLAT, STDCALL. DATA. KOD START: RET END START . DATA - programsegment som innehåller data. Detta program använder inte stacken, så segmentera. STACK saknas. . CODE - ett segment av programmet som innehåller koden. START - etikett. END START - slutet av programmet och ett meddelande till kompilatorn att programmet måste startas från etiketten START. Varje program måste innehålla ett END-direktiv som markerar slutet på programmets källkod. Alla rader som följer END-direktivet ignoreras.Etiketten efter END-direktivet talar om för kompilatorn namnet på huvudmodulen från vilken programkörningen börjar. Om programmet innehåller en modul kan etiketten efter END-direktivet utelämnas.

Assembly språköversättare En översättare är ett program eller tekniska medel A som konverterar ett program på ett av programmeringsspråken till ett program på målspråket, kallat objektkod. Förutom att stödja maskininstruktionsmnemonics har varje översättare sin egen uppsättning direktiv och makron, 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 montör för Intels arkitekturer x86 skapades av Simon Tatham med Julian Hall och utvecklas för närvarande av ett litet utvecklingsteam på Source. Förfalska. netto.

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

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

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

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

Översättning av programmet i Microsoft Visual Studio 2005 och i fönstret som visas väljer du Microsoft Macro Assembler.

Översättning av programmet i Microsoft Visual Studio 2005 Kontrollera med höger knapp i filen hej. asm i projektträdet från menyn Egenskaper och ställ in Allmänt->Verktyg: Microsoft Macro Assembler.

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

OS programmering Windows programmering i OC bygger Windows på användningen av API-funktioner (Application Program Interface, dvs gränssnitt mjukvaruapplikation). Deras antal når 2000. Programmet för Windows består till stor del av sådana samtal. All interaktion med externa enheter och resurser i operativsystemet sker som regel genom sådana funktioner. Operations rum Windows-system använder en platt minnesmodell. Adressen för valfri minnesplats 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 en dialogruta), konsol eller fönsterlös struktur, klassisk struktur (fönster, ram).

Ring upp Windows-funktioner API I hjälpfilen representeras valfri API-funktion som typen funktionsnamn (FA 1, FA 2, FA 3) Typ – returvärdestyp; FAX – lista över formella argument i deras ordning, till exempel int Message. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Bildtext, UINT u. Typ); Denna funktion visar ett fönster med ett meddelande och en utgångsknapp(ar). Betydelse av parametrar: h. Wnd - handtag till fönstret där meddelandefönstret kommer att visas, lp. Text - texten som visas i fönstret, lp. Bildtext - text i fönstrets titel, u. Typ - fönstertyp, i synnerhet kan du ange antalet utgångsknappar.

Anropar Windows API-funktioner int Meddelande. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Bildtext, UINT u. Typ); Nästan alla API-funktionsparametrar är faktiskt 32-bitars heltal: HWND är ett 32-bitars heltal, LPCTSTR är en 32-bitars strängpekare, UINT är ett 32-bitars heltal. Suffixet "A" läggs ofta till i namnet på funktioner för att hoppa till nyare versioner av funktioner.

Anropar Windows API-funktioner int Meddelande. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Bildtext, 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 i stacken. För Win 32 API-funktioner kan detta antal definieras som antalet argument n gånger 4 (byte i varje argument): N=4*n. För att anropa en funktion används CALL-instruktionen från assemblern. I detta fall skickas alla argument till funktionen till den via stacken (PUSH-kommandot). Argument passerar riktning: VÄNSTER TILL HÖGER - NEDAN UPP. Argumentet u kommer att skjutas på stapeln först. typ. Ring upp specificerad funktion kommer att se ut så här: CALL Message. låda. [e-postskyddad]

Anropar Windows API-funktioner int Meddelande. Box (HWND h. Wnd, LPCTSTR lp. Text, LPCTSTR lp. Bildtext, UINT u. Typ); Resultatet av att köra valfri API-funktion är vanligtvis ett heltal, som returneras i EAX-registret. OFFSET-direktivet är en "segmentoffset" eller, på högnivåspråk, en "pekare" till början av en sträng. EQU-direktivet, som #define i C, definierar en konstant. EXTERN-direktivet talar om för kompilatorn att en funktion eller identifierare är extern till modulen.

Ett exempel på programmet "Hej alla!" . 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. [e-postskyddad]: NÄRA. KOD START: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Meddelande. låda. [e-postskyddad] RET END START

INVOKE-direktivet MASM-språköversättaren gör det också möjligt att förenkla funktionsanropet med hjälp av ett makroverktyg - INVOKE-direktivet: INVOKE-funktion, parameter1, parameter2, ... Det finns inget behov av att lägga till @16 ​​till funktionsanropet; parametrarna skrivs exakt i den ordning som de anges i funktionsbeskrivningen. översättarmakron överför parametrar till 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

Allmän information om assemblerspråk

Det symboliska assemblerspråket gör det möjligt att i stort sett eliminera bristerna med maskinspråksprogrammering.

Dess främsta fördel är att i assemblerspråk representeras alla programelement i symbolisk form. Omvandlingen av symboliska kommandonamn till deras binära koder är ansvaret för specialprogram- assembler, som befriar programmeraren från mödosamt arbete och eliminerar de oundvikliga felen.

Symboliska namn som introduceras vid programmering i assemblerspråk återspeglar som regel programmets semantik och förkortningen av kommandon - deras huvudfunktion. Till exempel: PARAM - parameter, TABELL - tabell, MASK - mask, ADD - addition, SUB - subtraktion, etc. n. Sådana namn kommer lätt ihåg av programmeraren.

För programmering i assemblerspråk är det nödvändigt att ha komplexa verktyg än för programmering på maskinspråk: du behöver datorsystem baserade på mikrodatorer eller datorer med en uppsättning kringutrustning(alfanumeriskt tangentbord, teckendisplay, diskettenhet och skrivare), samt inbyggda eller korsprogrammerade system för de erforderliga typerna av mikroprocessorer. Assembly-språk låter dig effektivt skriva och felsöka mycket mer komplexa program än maskinspråk (upp till 1 - 4 KB).

Monteringsspråk är maskinorienterade, det vill säga beroende på maskinspråket och strukturen för motsvarande mikroprocessor, eftersom de tilldelar ett specifikt symboliskt namn till varje mikroprocessorinstruktion.

Monteringsspråk ger en betydande ökning av produktiviteten hos programmerare jämfört med maskinspråk och behåller samtidigt möjligheten att använda alla mjukvarutillgängliga hårdvaruresurser i mikroprocessorn. Detta gör det möjligt för skickliga programmerare att skriva program som körs på kortare tid och tar upp mindre minne än program skrivna på ett högnivåspråk.

I detta avseende är nästan alla I/O-enhetskontrollprogram (drivrutiner) skrivna i assemblerspråk, trots närvaron av ett ganska stort utbud av högnivåspråk.

Med hjälp av assemblerspråk kan programmeraren ställa in följande parametrar:

mnemonisk (symboliskt namn) för varje kommando i mikroprocessorns maskinspråk;

standardformat för rader i ett program som beskrivs i assembler;

format för att specificera olika sätt adresserings- och kommandoalternativ;

format för att specificera teckenkonstanter och konstanter av heltalstyp i olika talsystem;

pseudo-kommandon som styr processen för montering (översättning) av programmet.

På assemblerspråk skrivs programmet rad för rad, det vill säga en rad tilldelas för varje instruktion.

För mikrodatorer byggda på basis av de vanligaste typerna av mikroprocessorer kan det finnas flera varianter av assemblerspråk, dock har man oftast en praktisk fördelning - detta är det så kallade standard assemblerspråket

Programmering på maskininstruktionsnivå är den lägsta nivån på vilken programmering är möjlig. Systemet med maskininstruktioner måste vara tillräckligt för att genomföra de nödvändiga åtgärderna genom att utfärda instruktioner till datorhårdvaran.

Varje maskininstruktion består av två delar:

drift - bestämma "vad man ska göra";

· operand - definierar bearbetningsobjekt, "vad man ska göra med".

Maskininstruktionen för mikroprocessorn, skriven i assemblerspråk, är en enda rad med följande syntaktiska form:

etikett kommando/direktiv operand(er) ;kommentarer

I det här fallet är ett obligatoriskt fält på en rad ett kommando eller direktiv.

Etiketten, kommandot/direktivet och operander (om några) är åtskilda av minst ett mellanslag eller tabbtecken.

Om ett kommando eller direktiv behöver fortsätta på nästa rad, används bakstrecket: \.

Som standard skiljer inte assemblerspråk mellan stora och små bokstäver i kommandon eller direktiv.

Direkt adressering: Den effektiva adressen bestäms direkt av maskininstruktionsoffsetfältet, som kan vara 8, 16 eller 32 bitar stort.

mov eax, summa ; eax = summa

Samlaren ersätter summan med motsvarande adress lagrad i datasegmentet (som standard adresserad av register ds) och placerar värdet som lagrats vid adresssumma i register eax.

indirekt adressering har i sin tur följande typer:

Indirekt grundläggande (register) adressering;

Indirekt grundläggande (register) adressering med offset;

· indirekt indexadressering;

· indirekt basindexadressering.

Indirekt grundläggande (register) adressering. Med denna adressering kan den effektiva adressen för operanden finnas i vilket som helst av de allmänna registren, förutom sp/esp och bp/ebp (dessa är specifika register för att arbeta med ett stacksegment). Syntaktisk i en instruktion uttrycks detta adresseringsläge genom att omge registernamnet inom hakparenteser.

mov eax, ; eax = *esi; *esi-värde vid adress esi