Grunnleggende komponenter i monteringsspråk og instruksjonsstruktur. Dataformat og struktur av assembly-språkkommandoer. I faget "Systemprogrammering"

Introduksjon.

Språket som kildeprogrammet er skrevet på kalles inngang språk, og språket det er oversatt til for utførelse av prosessoren er på fridager tunge. Prosessen med å konvertere inndataspråk til utdataspråk kalles kringkaste. Siden prosessorer er i stand til å kjøre programmer på binært maskinspråk, som ikke brukes til programmering, er oversettelse av alle kildeprogrammer nødvendig. Kjent to veier sendinger: sammenstilling og tolkning.

samling kildeprogrammet blir først fullstendig oversatt til et tilsvarende program i utdataspråket, kalt gjenstand programmet og deretter utført. Denne prosessen implementeres ved hjelp av en spesiell programmer, kalt kompilator. En kompilator der inngangsspråket er en symbolsk form for å representere maskinspråket (utdata) for binære koder kalles montør.

tolkninger Hver tekstlinje i kildeprogrammet blir analysert (tolket) og kommandoen som er spesifisert i den, utføres umiddelbart. Implementeringen av denne metoden er betrodd tolkeprogram. Tolking tar lang tid. For å øke effektiviteten, i stedet for å behandle hver linje, konverterer tolken først alle team strenger til tegn (

). Den genererte sekvensen av symboler brukes til å utføre funksjonene som er tildelt det originale programmet.

Monteringsspråket som er omtalt nedenfor implementeres ved hjelp av kompilering.

Funksjoner ved språket.

Hovedtrekkene til montøren:

● i stedet for binære koder, bruker språket symbolske navn - mnemonikk. For eksempel for tilleggskommandoen (

) mnemonikk brukes

Subtraksjoner (

multiplikasjon (

Divisjoner (

osv. Symbolske navn brukes også for å adressere minneceller. For å programmere i assemblerspråk, i stedet for binære koder og adresser, trenger du kun å kjenne til symbolske navn som assembleren oversetter til binære koder;

hver utsagn samsvarer én maskinkommando(kode), dvs. det er en en-til-en-korrespondanse mellom maskinkommandoer og operatører i et assembly-språkprogram;

● språk gir tilgang til alle objekter og lag. Språk på høyt nivå har ikke denne muligheten. For eksempel lar assembly-språket deg sjekke biter av flaggregisteret og språk på høyt nivå (for eksempel,

) har ikke denne evnen. Merk at systemprogrammeringsspråk (for eksempel C) ofte har en mellomposisjon. Når det gjelder tilgjengelighet, er de nærmere assemblerspråk, men har syntaksen til et språk på høyt nivå;

● monteringsspråk er ikke et universelt språk. Hver spesifikk gruppe mikroprosessorer har sin egen assembler. Språk på høyt nivå har ikke denne ulempen.

I motsetning til høynivåspråk tar det mye tid å skrive og feilsøke et program på assemblerspråk. Til tross for dette har forsamlingsspråk fått bred bruk på grunn av følgende forhold:

● et program skrevet på assemblerspråk er betydelig mindre i størrelse og kjører mye raskere enn et program skrevet på et høyt nivåspråk. For noen applikasjoner spiller disse indikatorene en primær rolle, for eksempel mange systemprogrammer (inkludert kompilatorer), kredittkortprogrammer, mobil, enhetsdrivere osv.;

● noen prosedyrer krever full tilgang til maskinvaren, noe som vanligvis er umulig å gjøre på et språk på høyt nivå. Denne saken inkluderer avbrudds- og avbruddsbehandlere i operativsystemer, samt enhetskontrollere i innebygde sanntidssystemer.

I de fleste programmer er det bare en liten prosentandel av den totale koden som er ansvarlig for en stor prosentandel av programmets utførelsestid. Vanligvis er 1 % av programmet ansvarlig for 50 % av gjennomføringstiden, og 10 % av programmet er ansvarlig for 90 % av gjennomføringstiden. Derfor, for å skrive et spesifikt program under reelle forhold, brukes både assembler og et av høynivåspråkene.

Operatørformat i assemblerspråk.

Et assembly-språkprogram er en liste over kommandoer (utsagn, setninger), som hver opptar en egen linje og inneholder fire felt: et etikettfelt, et operasjonsfelt, et operandfelt og et kommentarfelt. Hvert felt har en egen kolonne.

Etikettfelt.

Kolonne 1 er tildelt etikettfeltet. Etiketten er et symbolsk navn, eller identifikator, adresser hukommelse. Det er nødvendig slik at du kan:

● foreta en betinget eller ubetinget overgang til kommandoen;

● få tilgang til stedet der dataene er lagret.

Slike uttalelser er forsynt med en etikett. For å indikere et navn, brukes (store) bokstaver i det engelske alfabetet og tall. Navnet må ha en bokstav i begynnelsen og et kolonskilletegn på slutten. Kolonetiketten kan skrives på en egen linje, og opkoden kan skrives på neste linje i kolonne 2, noe som forenkler kompilatorens arbeid. Fraværet av et kolon tillater ikke å skille en etikett fra en operasjonskode hvis de er plassert på separate linjer.

I noen versjoner av assembly-språket plasseres kolon bare etter instruksjonsetiketter, ikke etter dataetiketter, og lengden på etiketten kan være begrenset til 6 eller 8 tegn.

Det skal ikke være identiske navn i etikettfeltet, siden etiketten er knyttet til kommandoadresser. Hvis det under programkjøring ikke er nødvendig å kalle en kommando eller data fra minnet, forblir etikettfeltet tomt.

Driftskodefelt.

Dette feltet inneholder mnemonisk kode for en kommando eller pseudo-kommando (se nedenfor). Kommandoen mnemonisk kode velges av språkutviklerne. På assemblerspråk

mnemonic er valgt for å laste et register fra minnet

), og for å lagre innholdet i registeret i minnet - en mnemonikk

). På assemblerspråk

for begge operasjonene kan du bruke samme navn

Hvis valget av mnemoniske navn kan være vilkårlig, bestemmes behovet for å bruke to maskininstruksjoner av prosessorarkitekturen

Mnemonikken til registre avhenger også av assemblerversjonen (tabell 5.2.1).

Operand felt.

Her ligger Tilleggsinformasjon, nødvendig for å utføre operasjonen. I operandfeltet for hoppkommandoer angis adressen som hoppet må gjøres til, samt adresser og registre som er operander for maskinkommandoen. Som et eksempel gir vi operander som kan brukes for 8-bits prosessorer

● numeriske data,

presentert i forskjellige tallsystemer. For å indikere tallsystemet som brukes, etterfølges konstanten av en av de latinske bokstavene: B,

Følgelig, binære, oktale, heksadesimale, desimale tallsystemer (

Du trenger ikke å skrive det ned). Hvis det første sifferet i et heksadesimalt tall er A, B, C,

Deretter legges det til en ubetydelig 0 (null) foran;

● koder for interne mikroprosessorregistre og minneceller

M (kilder eller mottakere av informasjon) i form av bokstavene A, B, C,

M eller deres adresser i et hvilket som helst nummersystem (for eksempel 10B - registeradresse

i binært system);

● identifikatorer,

for registerpar av fly,

De første bokstavene er B,

N; for et par akkumulator og funksjonsregister -

; for programtelleren -

;for stabelpekeren -

● etiketter som angir adressene til operandene eller neste instruksjoner i betinget

(hvis vilkåret er oppfylt) og ubetingede overganger. For eksempel operand M1 i kommandoen

betyr behovet for en ubetinget overgang til kommandoen, hvis adresse i etikettfeltet er merket med identifikatoren M1;

● uttrykk,

som er konstruert ved å koble dataene diskutert ovenfor ved å bruke aritmetiske og logiske operatorer. Merk at metoden for å reservere dataplass avhenger av språkversjonen. Montering språkutviklere for

Definer ordet), og senere inn Alternativt alternativ.

som var på språket for prosessorer helt fra begynnelsen

I språkversjon

brukt

Definer en konstant).

Prosessorer behandler operander av forskjellig lengde. For å definere det tok assemblerutviklere forskjellige beslutninger, for eksempel:

II-registre med forskjellige lengder har forskjellige navn: EAX - for plassering av 32-bits operander (type

); AX - for 16-bit (type

og AN - for 8-bit (type

● for prosessorer

Suffikser legges til hver operasjonskode: suffiks

For type

; suffiks ".B" for type

forskjellige op-koder brukes for operander av forskjellige lengder, for eksempel for å laste en byte, halvord (

) og ord inn i et 64-bits register ved å bruke opkoder

hhv.

Kommentarfelt.

Dette feltet gir forklaringer om handlingene til programmet. Kommentarer påvirker ikke driften av programmet og er beregnet på mennesker. De kan være nødvendige for å modifisere et program, som uten slike kommentarer kan være helt uforståelig selv for erfarne programmerere. En kommentar begynner med et symbol og brukes til å forklare og dokumentere programmer. Startkarakteren til en kommentar kan være:

● semikolon (;) på språk for selskapets prosessorer

Utropstegn(!) på språk for

Hver separat kommentarlinje innledes med en ledende karakter.

Pseudo-kommandoer (direktiver).

I assemblerspråk er det to hovedtyper kommandoer:

grunnleggende instruksjoner som tilsvarer prosessorens maskinkode. Disse kommandoene utfører all behandlingen tiltenkt av programmet;

pseudo-kommandoer eller direktiver, designet for å betjene prosessen med å oversette et program til et kodekombinasjonsspråk. Som eksempel i tabellen. 5.2.2 viser noen pseudo-kommandoer fra assembleren

for familien

.

Ved programmering er det situasjoner der, ifølge algoritmen, den samme kjeden av kommandoer må gjentas mange ganger. For å komme ut av denne situasjonen kan du:

● skriv den nødvendige sekvensen med kommandoer hver gang den vises. Denne tilnærmingen fører til en økning i volumet av programmet;

● ordne denne sekvensen i en prosedyre (subrutine) og kall den om nødvendig. Denne utgangen har sine ulemper: hver gang du må utføre en spesiell prosedyrekallingskommando og en returkommando, som, hvis sekvensen er kort og ofte brukt, kan redusere hastigheten til programmet betraktelig.

Den enkleste og effektiv metode gjentatt repetisjon av en kjede av kommandoer består i å bruke makro, som kan representeres som en pseudo-kommando designet for å oversette en gruppe kommandoer som ofte finnes i et program.

En makro, eller makrokommando, er preget av tre aspekter: makrodefinisjon, makroinversjon og makroutvidelse.

Makrodefinisjon

Dette er en betegnelse for en gjentatt gjentatt sekvens av programkommandoer, brukt for referanser i programteksten.

Makrodefinisjonen har følgende struktur:

Liste over uttrykk; Makrodefinisjon

I den gitte strukturen til makrodefinisjon kan tre deler skilles:

● tittel

makro, inkludert navnet

Pseudo-kommando

og et sett med parametere;

● merket med prikker kropp makro;

● team

eksamen

makrodefinisjoner.

Makrodefinisjonsparametersettet inneholder en liste over alle parametere gitt i operandfeltet for den valgte gruppen med instruksjoner. Hvis disse parameterne ble gitt tidligere i programmet, trenger de ikke å angis i makrodefinisjonsoverskriften.

For å sette sammen den valgte gruppen av kommandoer igjen, brukes en appell som består av navnet

makrokommandoer og liste over parametere med andre verdier.

Når assembleren møter en makrodefinisjon under kompileringsprosessen, lagrer den den i makrodefinisjonstabellen. Ved påfølgende opptredener i programmet til navnet (

) av en makro, erstatter assembleren den med brødteksten til makroen.

Å bruke et makronavn som opkode kalles makro-reversering(makroanrop), og erstatte det med brødteksten til makroen - makro ekspansjon.

Hvis et program er representert som en sekvens av tegn (bokstaver, tall, mellomrom, skilletegn og vognretur for å flytte til en ny linje), så består makroutvidelse av å erstatte noen kjeder fra denne sekvensen med andre kjeder.

Makroutvidelse skjer under monteringsprosessen, ikke under programkjøring. Metoder for å manipulere strenger med tegn er tilordnet makro betyr.

Monteringsprosessen er utført i to omganger:

● Ved den første passeringen blir alle makrodefinisjoner bevart, og makroanrop utvides. I dette tilfellet blir det originale programmet lest og konvertert til et program der alle makrodefinisjoner er fjernet, og hvert makrokall erstattes av makroens kropp;

● den andre passeringen behandler det resulterende programmet uten makroer.

Makroer med parametere.

For å jobbe med gjentatte sekvenser av kommandoer, hvis parametere kan ha forskjellige verdier, er makrodefinisjoner gitt:

● med faktiske parametere som er plassert i operandfeltet til makrokallet;

● med formell parametere. Under makroutvidelse erstattes hver formell parameter som vises i hoveddelen av makroen med den tilsvarende faktiske parameteren.

bruke makroer med parametere.

Program 1 inneholder to lignende sekvenser av kommandoer, som er forskjellige ved at den første bytter P og

Og den andre

Program 2 inkluderer en makro med to formelle parametere P1 og P2. Under makroutvidelse erstattes hvert P1-tegn i makrokroppen med den første faktiske parameteren (P,

), og symbolet P2 erstattes av den andre faktiske parameteren (

) fra program nr. 1. I makrokallet

program 2 er merket: P,

Den første faktiske parameteren,

Andre faktiske parameter.

Program 1

Program 2

MOV EBX,Q MOV EAX,Pl

MOV Q,EAX MOV EBX,P2

MOV P,EBX MOV P2,EAX

Utvidede muligheter.

La oss se på noen avanserte språkfunksjoner

Hvis en makro som inneholder en betinget hoppkommando og en etikett som skal hoppes til kalles to eller flere ganger, vil etiketten dupliseres (duplisert etikettproblem), noe som vil forårsake en feil. Derfor tildeler hvert anrop en egen etikett som en parameter (av programmereren). På språket

etiketten er erklært lokal (

) og takket være avanserte funksjoner genererer assembleren automatisk en annen etikett hver gang makroen utvides.

lar deg definere makroer inne i andre makroer. Denne avanserte funksjonen er veldig nyttig i kombinasjon med betinget kobling av et program. La oss vurdere

IF WORDSIZE GT 16 M2 MAKRO

M2-makroen kan defineres i begge deler av setningen

Definisjonen avhenger imidlertid av hvilken prosessor programmet er satt sammen på: 16-bit eller 32-bit. Hvis M1 ikke kalles, vil ikke makro M2 bli definert i det hele tatt.

En annen avansert funksjon er at makroer kan kalle andre makroer, inkludert seg selv - tilbakevendende anrop. I sistnevnte tilfelle, for å unngå en endeløs sløyfe, må makroen sende en parameter til seg selv som endres med hver utvidelse, og også Sjekk denne parameteren og avslutte rekursjonen når parameteren når en viss verdi.

Om bruk av makromidler i assembler.

Når du bruker makroer, må assembleren kunne utføre to funksjoner: lagre makrodefinisjoner Og utvide makroutfordringer.

Lagre makrodefinisjoner.

Alle makronavn er lagret i en tabell. Hvert navn er ledsaget av en peker til den tilsvarende makroen slik at den kan kalles om nødvendig. Noen montører har en egen tabell for makronavn, andre har en generell tabell der, sammen med makronavn, alle maskininstruksjoner og direktiver er plassert.

Når du møter en makro under montering er skapt:

nytt bordelement med navnet på makroen, antall parametere og en peker til en annen makrodefinisjonstabell der hoveddelen av makroen vil bli lagret;

● liste formell parametere.

Brødteksten til makroen, som ganske enkelt er en streng med tegn, leses og lagres i makrodefinisjonstabellen. Formelle parametere som forekommer i løkkens kropp er merket spesiell karakter.

Intern representasjon av en makro

fra eksempelet ovenfor for program 2 (s. 244) er:

MOV EAX, MOV EBX, MOV MOV &

der semikolon brukes som vognreturtegnet, og og-tegnet & brukes som det formelle parametertegnet.

Utvide makroanrop.

Hver gang en makrodefinisjon påtreffes under montering, lagres den i makrotabellen. Når en makro kalles, stopper assembleren midlertidig å lese inngangsdata fra inndataenheten og begynner å lese den lagrede makrokroppen. De formelle parameterne som er hentet ut fra makrokroppen, erstattes av faktiske parametere og leveres av samtalen. Parametrene og før-tegnet lar assembleren gjenkjenne dem.

Til tross for at det finnes mange versjoner av assembler, har monteringsprosessene fellestrekk og er like på mange måter. Driften av en to-pass assembler er diskutert nedenfor.

To-pass assembler.

Et program består av en rekke utsagn. Derfor ser det ut til at når du monterer, kan du bruke følgende handlingssekvens:

● oversette det til maskinspråk;

● overføre den resulterende maskinkoden til en fil, og den tilsvarende delen av oppføringen til en annen fil;

● gjenta de oppførte prosedyrene til hele programmet er oversatt.

Denne tilnærmingen er imidlertid ikke effektiv. Et eksempel er det såkalte problemet viderekobling. Hvis den første setningen er et hopp til setning P, plassert helt på slutten av programmet, kan ikke assembleren oversette den. Han må først bestemme adressen til operatør P, og for å gjøre dette må han lese hele programmet. Hver fullstendig lesing av kildeprogrammet kalles passasje. La oss vise hvordan du kan løse lookahead-lenkeproblemet ved å bruke to pass:

på første pass bør du samle inn og lagre alle symboldefinisjoner (inkludert etiketter) i tabellen, og ved den andre passeringen, les og sett sammen hver operatør. Denne metoden er relativt enkel, men en andre gang gjennom det originale programmet krever ekstra tid brukt på I/O-operasjoner;

● ved første pass bør du konvertere programmet til en mellomform og lagre det i en tabell, og utfør den andre passeringen ikke i henhold til det opprinnelige programmet, men i henhold til tabellen. Denne monteringsmetoden sparer tid, siden den andre passasjen ikke utfører I/O-operasjoner.

Første pass.

Første pasningsmål- bygg et symbolbord. Som nevnt ovenfor, er et annet mål med den første passeringen å bevare alle makrodefinisjoner og utvide anrop etter hvert som de vises. Følgelig skjer både symboldefinisjon og makroutvidelse i én omgang. Symbolet kan være enten merkelapp, eller betydning, som et spesifikt navn er tildelt ved å bruke -you-direktivet:

;Verdi - bufferstørrelse

Ved å tildele betydning til symbolske navn i kommandoetikettfeltet, spesifiserer assembleren i hovedsak adressene som hver kommando vil ha under programkjøring. For dette formålet lagrer montøren under monteringsprosessen instruksjonsadresseteller(

) som en spesiell variabel. Ved begynnelsen av den første passeringen settes verdien av spesialvariabelen til 0 og økes etter hver kommando behandlet med lengden på den kommandoen. Som eksempel i tabellen. 5.2.3 viser et programfragment som indikerer lengden på kommandoer og tellerverdier. Ved den første passeringen genereres tabeller symbolske navn, direktiver Og operasjonskoder, og om nødvendig bokstavelig bord. En bokstavelig er en konstant som samleren automatisk reserverer minne for. La oss umiddelbart legge merke til at moderne prosessorer inneholder instruksjoner med umiddelbare adresser, så samlerne deres støtter ikke bokstaver.

Symbolnavntabell

inneholder ett element for hvert navn (tabell 5.2.4). Hvert element i den symbolske navnetabellen inneholder selve navnet (eller en peker til det), dets numeriske verdi, og noen ganger litt tilleggsinformasjon, som kan omfatte:

● lengden på datafeltet knyttet til symbolet;

● minneomfordelingsbiter (som indikerer om verdien til et symbol endres hvis programmet lastes inn på en annen adresse enn assembleren hadde til hensikt);

● informasjon om hvorvidt symbolet kan nås utenfor prosedyren.

Symboliske navn er etiketter. De kan spesifiseres ved hjelp av operatorer (f.eks.

Direktivtabell.

Denne tabellen viser alle direktivene, eller pseudo-kommandoene, som oppstår når du setter sammen et program.

Driftskodetabell.

For hver operasjonskode har tabellen separate kolonner: operasjonskodebetegnelse, operand 1, operand 2, heksadesimal verdi av operasjonskoden, kommandolengde og kommandotype (tabell 5.2.5). Operasjonskoder er delt inn i grupper avhengig av antall og type operander. Kommandotypen bestemmer gruppenummeret og spesifiserer prosedyren som kalles for å behandle alle kommandoer i den gruppen.

Andre pass.

Mål for den andre pasningen- opprettelse av et objektprogram og utskrift, om nødvendig, av monteringsprotokollen; ut informasjon som er nødvendig for linkeren for å koble prosedyrer som ble satt sammen til forskjellige tider til én kjørbar fil.

I den andre omgangen (som i den første) blir linjene som inneholder utsagnene lest og behandlet én etter én. Den opprinnelige operatoren og utdataoperatoren avledet fra den i heksadesimal gjenstand Koden kan skrives ut eller legges i en buffer for senere utskrift. Etter tilbakestilling av kommandoadressetelleren, kalles kommandoen neste uttalelse.

Kildeprogrammet kan inneholde feil, for eksempel:

det gitte symbolet er ikke definert eller er definert mer enn én gang;

● op-koden er representert med et ugyldig navn (på grunn av en skrivefeil), har ikke nok operander eller har for mange operander;

● ingen operatør

Noen montører kan oppdage et udefinert symbol og erstatte det. Men i de fleste tilfeller, når den støter på en feilsetning, viser assembleren en feilmelding på skjermen og prøver å fortsette monteringsprosessen.

Artikler dedikert til forsamlingsspråk.

NATIONAL UNIVERSITY OF UZBEKISTAN OPPKAPT ETTER MIRZO ULUGBEK

DATATEKNOLOGISK FAKULTET

Om emnet: Semantisk parsing av en EXE-fil.

Fullført:

Tasjkent 2003.

Forord.

Monteringsspråk og kommandostruktur.

EXE-filstruktur (semantisk parsing).

COM-filstruktur.

Prinsippet om handling og spredning av viruset.

Demonter.

Programmer.

Forord

Yrket som programmerer er fantastisk og unikt. I dag er det umulig å forestille seg vitenskap og liv uten den nyeste teknologien. Alt relatert til menneskelig aktivitet kan ikke gjøres uten datateknologi. Og dette bidrar til dens høye utvikling og perfeksjon. Selv om utviklingen av personlige datamaskiner begynte for ikke så lenge siden, har det i løpet av denne tiden blitt gjort kolossale skritt i programvareprodukter, og disse produktene vil bli mye brukt i lang tid. Fagfeltet datarelatert kunnskap har gjennomgått en eksplosjon, det samme har den tilsvarende teknologien. Hvis vi ikke tar hensyn til den kommersielle siden, kan vi si at det ikke er fremmede på dette området av ​profesjonell aktivitet. Mange mennesker utvikler programmer ikke for profitt eller inntekt, men av egen fri vilje, av lidenskap. Dette skal selvsagt ikke påvirke kvaliteten på programmet, og i denne bransjen er det så å si konkurranse og etterspørsel etter kvalitetsutførelse, stabilt arbeid og oppfyllelse av alle moderne krav. Her er det også verdt å merke seg utseendet til mikroprosessorer på 60-tallet, som kom til å erstatte et stort antall lampesett. Det er noen typer mikroprosessorer som er veldig forskjellige fra hverandre. Disse mikroprosessorene skiller seg fra hverandre i bitdybde og innebygde systemkommandoer. De vanligste er: Intel, IBM, Celeron, AMD, etc. Alle disse prosessorene er relatert til den avanserte arkitekturen til Intel-prosessorer. Utbredelsen av mikrodatamaskiner førte til en ny vurdering av holdninger til assembly-språk av to hovedgrunner. For det første krever programmer skrevet i assemblerspråk betydelig mindre minne og utførelsestid. For det andre gir kunnskap om monteringsspråk og den resulterende maskinkoden en forståelse av maskinens arkitektur, noe som neppe vil bli gitt når du arbeider i et språk på høyt nivå. Selv om de fleste programvarefagfolk utvikler seg på høynivåspråk som Pascal, C eller Delphi, noe som er enklere når du skriver programmer, er den kraftigste og mest effektive programvare skrevet helt eller delvis på samlespråk. Språk på høyt nivå ble designet for å unngå spesielle tekniske funksjoner spesifikke datamaskiner. Og monteringsspråket er på sin side designet for de spesifikke spesifikasjonene til prosessoren. Derfor, for å skrive et assembly-språkprogram for en bestemt datamaskin, må du kjenne arkitekturen. Disse dager, utsikten over de viktigste programvareprodukt er en EXE-fil. Med tanke på positive sider Dette betyr at forfatteren av programmet kan være trygg på integriteten. Men ofte er dette langt fra tilfelle. Det er også en demonter. Ved hjelp av en demonter kan du finne ut avbrudd og programkoder. Det vil ikke være vanskelig for en person som er godt bevandret i assembler å gjenskape hele programmet etter sin smak. Kanskje det er her det mest uløselige problemet oppstår - viruset. Hvorfor skriver folk et virus? Noen stiller dette spørsmålet med overraskelse, noen med sinne, men likevel fortsetter det å være folk som er interessert i denne oppgaven, ikke ut fra synspunktet om å forårsake skade, men som en interesse for systemprogrammering. Virus er skrevet av forskjellige årsaker. Noen liker systemanrop, andre forbedrer kunnskapen om assembler. Jeg skal prøve å forklare alt dette i min kursarbeid. Den sier også ikke bare om strukturen til EXE-filen, men også om assemblerspråket.

^ Forsamlingsspråk.

Det er interessant å følge, fra tidspunktet for utseendet til de første datamaskinene til i dag, transformasjonen av programmerernes ideer om monteringsspråk.

En gang i tiden var montering et språk uten hvilket du ikke kunne få en datamaskin til å gjøre noe nyttig. Gradvis endret situasjonen seg. Mer praktiske måter å kommunisere med en datamaskin dukket opp. Men, i motsetning til andre språk, døde ikke assembler; dessuten kunne den i prinsippet ikke gjøre dette. Hvorfor? På leting etter et svar, la oss prøve å forstå hva forsamlingsspråk er generelt.

Kort sagt er monteringsspråk en symbolsk representasjon av maskinspråk. Alle prosesser i en maskin på det laveste maskinvarenivået drives kun av maskinspråkkommandoer (instruksjoner). Fra dette er det klart at, til tross for det vanlige navnet, er monteringsspråket forskjellig for hver type datamaskin. Dette gjelder også utseende programmer skrevet på assemblerspråk og ideer som dette språket er en refleksjon av.

Det er umulig å virkelig løse problemer relatert til maskinvare (eller til og med, dessuten, avhengig av maskinvare, for eksempel å øke hastigheten på et program), uten kunnskap om assembler.

En programmerer eller en hvilken som helst annen bruker kan bruke hvilket som helst verktøy på høyt nivå, til og med programmer for å konstruere virtuelle verdener, og kanskje ikke engang mistenke at datamaskinen faktisk ikke utfører kommandoene til språket programmet er skrevet på, men deres transformerte representasjon i form av en kjedelig og kjedelig sekvens av kommandoer fra et helt annet språk - maskinspråk. La oss nå forestille oss at en slik bruker har et ikke-standardproblem eller at noe bare ikke fungerer. For eksempel må programmet hans fungere med en uvanlig enhet eller utføre andre handlinger som krever kunnskap om driftsprinsippene til maskinvare. Uansett hvor smart programmereren er, uansett hvor godt språket han skrev det fantastiske programmet på, kan han ikke klare seg uten kunnskap om assembler. Og det er ingen tilfeldighet at nesten alle høynivåspråkkompilatorer inneholder midler for å koble modulene sine med assemblermoduler eller støtte tilgang til assemblernivået for programmering.

Datageneralistenes tid har selvfølgelig allerede passert. Som de sier, du kan ikke omfavne det enorme. Men det er noe til felles, et slags grunnlag som enhver seriøs datautdanning er bygget på. Dette er kunnskap om prinsippene for datamaskindrift, dens arkitektur og monteringsspråk som en refleksjon og legemliggjøring av denne kunnskapen.

En typisk moderne datamaskin (i486- eller Pentium-basert) består av følgende komponenter (Figur 1).

Ris. 1. Datamaskin og periferiutstyr

Ris. 2. Blokkskjema personlig datamaskin

Fra figuren (Figur 1) er det tydelig at datamaskinen består av flere fysiske enheter, som hver er koblet til én enhet, kalt systemenheten. Hvis vi tenker logisk, er det klart at det spiller rollen som en slags koordinerende enhet. La oss se inne i systemenheten (ingen grunn til å prøve å komme inn i skjermen - det er ikke noe interessant der, og dessuten er det farlig): åpne saken og se noen tavler, blokker, tilkoblingsledninger. For å forstå deres funksjonelle formål, la oss se på blokkskjemaet til en typisk datamaskin (fig. 2). Den krever ikke absolutt nøyaktighet og er kun ment å vise formålet, sammenkoblingen og den typiske sammensetningen av elementene i en moderne personlig datamaskin.

La oss diskutere diagrammet i fig. 2 i en noe ukonvensjonell stil.
Det er vanlig at en person, når han møter noe nytt, ser etter noen assosiasjoner som kan hjelpe ham å forstå det ukjente. Hvilke assosiasjoner vekker datamaskinen? For eksempel forbinder jeg ofte en datamaskin med personen selv. Hvorfor?

Når en person skapte en datamaskin, trodde han et sted dypt inne i seg selv at han skapte noe som ligner på seg selv. Datamaskinen har organer for å motta informasjon fra omverdenen - et tastatur, en mus og magnetiske diskstasjoner. I fig. 2 er disse organene plassert til høyre for systembussene. Datamaskinen har organer som "fordøyer" informasjonen som mottas - disse er prosessor og RAM. Og til slutt har datamaskinen taleorganer som produserer resultatene av behandlingen. Dette er også noen av enhetene til høyre.

Moderne datamaskiner, selvfølgelig, er langt fra menneskelig. De kan sammenlignes med skapninger som samhandler med omverdenen på nivå med et stort, men begrenset sett med ubetingede reflekser.
Dette settet med reflekser danner et system med maskinkommandoer. Uansett hvor høyt nivå du kommuniserer med en datamaskin, kommer det til slutt ned til en kjedelig og monoton sekvens av maskinkommandoer.
Hver maskinkommando er en slags stimulans for å begeistre en eller annen ubetinget refleks. Reaksjonen på denne stimulansen er alltid entydig og "hardwired" i mikrokommandoblokken i form av et mikroprogram. Dette mikroprogrammet implementerer handlinger for å implementere en maskinkommando, men på nivået av signaler som leveres til visse logikk datamaskin, og kontrollerer derved forskjellige undersystemer til datamaskinen. Dette er det såkalte prinsippet for mikroprogramkontroll.

For å fortsette analogien med en person, legger vi merke til: for at en datamaskin skal spise ordentlig, er det oppfunnet mange operativsystemer, kompilatorer for hundrevis av programmeringsspråk osv. Men alle er faktisk bare en tallerken som mat (programmer) leveres etter visse regler mage (datamaskin). Bare datamaskinens mage elsker kosthold, monoton mat - gi den strukturert informasjon, i form av strengt organiserte sekvenser av nuller og enere, hvis kombinasjoner utgjør maskinspråket.

Dermed, selv om den utad er en polyglot, forstår datamaskinen bare ett språk - språket for maskininstruksjoner. Selvfølgelig, for å kommunisere og jobbe med en datamaskin, er det ikke nødvendig å kunne dette språket, men nesten enhver profesjonell programmerer før eller senere blir møtt med behovet for å studere det. Heldigvis trenger ikke programmereren å prøve å forstå betydningen av ulike kombinasjoner av binære tall, siden tilbake på 50-tallet begynte programmerere å bruke en symbolsk analog av maskinspråk for programmering, som ble kalt monteringsspråk. Dette språket gjenspeiler nøyaktig alle funksjonene til maskinspråket. Det er derfor, i motsetning til høynivåspråk, er assembly-språket forskjellig for hver type datamaskin.

Fra alt det ovennevnte kan vi konkludere med at siden monteringsspråket er "innfødt" for en datamaskin, kan det mest effektive programmet bare skrives i det (forutsatt at det er skrevet av en kvalifisert programmerer). Det er et lite "men" her: dette er en svært arbeidskrevende prosess som krever mye oppmerksomhet og praktisk erfaring. Derfor skriver de i realiteten hovedsakelig programmer i assembler som skal gi effektivt arbeid med maskinvare. Noen ganger skrives programdeler som er kritiske med tanke på utførelsestid eller minneforbruk i assembler. Deretter blir de formalisert i form av subrutiner og kombinert med kode på et høynivåspråk.

Det er fornuftig å begynne å lære assemblerspråket til en hvilken som helst datamaskin først etter å ha funnet ut hvilken del av datamaskinen som er synlig og tilgjengelig for programmering på dette språket. Dette er den såkalte dataprogrammodellen, en del av denne er mikroprosessorprogrammodellen, som inneholder 32 registre, i en eller annen grad, tilgjengelig for bruk av programmereren.

Disse registrene kan deles inn i to store grupper:

^ 16 brukerregistre;

16 systemregistre.

Assembly språkprogrammer bruker registre veldig intensivt. De fleste registre har et bestemt funksjonelt formål.

Som navnet antyder, kalles brukerregistre brukerregistre fordi programmereren kan bruke dem når han skriver programmene sine. Disse registrene inkluderer (fig. 3):

Åtte 32-biters registre som kan brukes av programmerere til å lagre data og adresser (også kalt generelle registre (GPR)):

seks segmentregistre: cs, ds, ss, es, fs, gs;

status- og kontrollregistre:

Flagg registrerer eflag/flagg;

Kommandopekerregister eip/ip.

Ris. 3. Brukerregistre for i486 og Pentium mikroprosessorer

Hvorfor vises mange av disse registrene med skråstreker? Nei, dette er ikke forskjellige registre - de er deler av ett stort 32-bits register. De kan brukes i programmet som separate objekter. Dette ble gjort for å sikre funksjonaliteten til programmer skrevet for yngre 16-bits modeller av Intel-mikroprosessorer, fra i8086. Mikroprosessorene i486 og Pentium har stort sett 32-bits registre. Antallet deres, med unntak av segmentregistre, er det samme som i8086, men dimensjonen er større, noe som gjenspeiles i betegnelsene deres - de har
prefiks e (Utvidet).

^ Registre for generelle formål
Alle registre i denne gruppen gir deg tilgang til deres "nedre" deler (se fig. 3). Når du ser på denne figuren, legg merke til at bare de nedre 16 og 8-bits delene av disse registerene kan brukes til selvadressering. De øvre 16 bitene i disse registerene er ikke tilgjengelige som uavhengige objekter. Dette ble gjort, som vi bemerket ovenfor, for kompatibilitet med yngre 16-bits modeller av Intel-mikroprosessorer.

La oss liste opp registrene som tilhører gruppen allmennregistre. Siden disse registrene er fysisk plassert i mikroprosessoren inne i den aritmetiske logiske enheten (ALU), kalles de også ALU-registre:

eax/ax/ah/al (akkumulatorregister) - batteri.
Brukes til å lagre mellomdata. Noen kommandoer krever bruk av dette registeret;

ebx/bx/bh/bl (Basisregister) - basisregister.
Brukes til å lagre basisadressen til et objekt i minnet;

ecx/cx/ch/cl (Telleregister) - telleregister.
Brukes i team som utfører noen repeterende handlinger. Bruken er ofte implisitt og skjult i algoritmen til den tilsvarende kommandoen.
For eksempel, kommandoen for å organisere en sløyfe, i tillegg til å overføre kontroll til en kommando plassert på en bestemt adresse, analyserer og reduserer verdien av ecx/cx-registeret med én;

edx/dx/dh/dl (Dataregister) - dataregister.
Akkurat som eax/ax/ah/al-registeret, lagrer det mellomliggende data. I noen kommandoer er bruken obligatorisk; For noen kommandoer skjer dette implisitt.

Følgende to registre brukes til å støtte såkalte kjedede operasjoner, det vil si operasjoner som sekvensielt behandler kjeder av elementer, som hver kan være 32, 16 eller 8 biter lange:

esi/si (Kildeindeksregister) - kildeindeks.
Dette registeret i kjedede operasjoner inneholder gjeldende adresse til elementet i kildekjeden;

edi/di (Destination Index register) - indeks for mottakeren (mottakeren).
Dette registeret i kjedede operasjoner inneholder gjeldende adresse i destinasjonskjeden.

I mikroprosessorarkitekturen støttes en datastruktur som en stabel på maskinvare- og programvarenivå. For å jobbe med stabelen er det spesielle kommandoer iet, og i mer det spesielle registre for dette:

esp/sp (Stack Pointer register) - stack pointer register.
Inneholder en peker til toppen av stabelen i gjeldende stabelsegment.

ebp/bp (Base Pointer register) - stable frame base pointer register.
Designet for å organisere tilfeldig tilgang til data inne i stabelen.

En stack er et programområde for midlertidig lagring av vilkårlige data. Data kan selvfølgelig også lagres i et datasegment, men i dette tilfellet, for hver data som lagres midlertidig, må det opprettes en egen navngitt minnecelle, som øker størrelsen på programmet og antall navn som brukes. Det praktiske med stabelen ligger i det faktum at området kan gjenbrukes, og lagring av data på stabelen og henting derfra gjøres ved å bruke de effektive push- og pop-kommandoene uten å spesifisere noen navn.
Stabelen brukes tradisjonelt for eksempel for å lagre innholdet i registre som brukes av et program før det kalles opp en subrutine, som igjen vil bruke prosessorregistrene "til sine egne formål." Det opprinnelige innholdet i registrene blir tatt av stabelen etter at subrutinen kommer tilbake. En annen vanlig teknikk er å sende parametrene den krever til en subrutine via stabelen. Subrutinen, som vet i hvilken rekkefølge parametrene er plassert på stabelen, kan ta dem derfra og bruke dem under utførelsen. Særpreget trekk Stakken er en unik rekkefølge hvor dataene som finnes i den hentes: til enhver tid er kun det øverste elementet tilgjengelig på stabelen, dvs. elementet sist skjøvet på stabelen. Ved å sprette det øverste elementet fra stabelen blir det neste elementet tilgjengelig. Stabelelementer er plassert i minneområdet som er tildelt for stabelen, med start fra bunnen av stabelen (dvs. fra dens maksimale adresse) ved sekvensielt avtagende adresser. Adressen til det øverste, tilgjengelige elementet er lagret i stabelpekerregisteret SP. Som alle andre områder av programminnet, må stabelen være en del av et segment eller danne et eget segment. I begge tilfeller plasseres segmentadressen til dette segmentet i segmentstabelregisteret SS. Registerparet SS:SP beskriver således adressen til en tilgjengelig stabelcelle: SS lagrer segmentadressen til stabelen, og SP lagrer forskyvningen av de siste dataene som er lagret på stabelen (fig. 4, a). Merk at i starttilstanden peker stabelpekeren SP til en celle som ligger under bunnen av stabelen og ikke er inkludert i den.

Fig 4. Stabelorganisering: a - starttilstand, b - etter lasting av ett element (i dette eksemplet innholdet i AX-registeret), c - etter lasting av det andre elementet (innhold i DS-registeret), d - etter lossing av ett element, e - etter å ha losset to elementer og gå tilbake til sin opprinnelige tilstand.

Lasting i stabelen utføres av en spesiell kommando for arbeid med stabelen (push). Denne instruksjonen reduserer først innholdet i stabelpekeren med 2 og plasserer deretter operanden på adressen i SP. Hvis vi for eksempel ønsker å midlertidig lagre innholdet i AX-registeret på stabelen, bør vi kjøre kommandoen

Stabelen går inn i tilstanden vist i fig. 1.10, f. Det kan sees at stabelpekeren flyttes opp to byte (mot lavere adresser) og operanden spesifisert i push-kommandoen skrives til denne adressen. Følgende stabellastingskommando er f.eks.

vil sette stabelen i tilstanden vist i fig. 1,10, c. Stabelen vil nå lagre to elementer, og bare det øverste, pekt på av stabelpekeren SP, vil være tilgjengelig. Hvis vi etter en tid trenger å gjenopprette det opprinnelige innholdet i registrene som er lagret på stabelen, må vi utføre pop (push)-kommandoer for å laste ut fra stabelen:

pop DS
pop AX

Hvor stor skal stabelen være? Det avhenger av hvor intensivt det brukes i programmet. Hvis du for eksempel planlegger å lagre en matrise på 10 000 byte på stabelen, må stabelen ha minst denne størrelsen. Det bør huskes at i noen tilfeller blir stabelen automatisk brukt av systemet, spesielt når du utfører int 21h interrupt-kommandoen. Med denne kommandoen skyver prosessoren først returadressen inn på stabelen, og deretter skyver DOS innholdet i registrene og annen informasjon relatert til det avbrutte programmet over på stabelen. Derfor, selv om et program ikke bruker en stabel i det hele tatt, må den fortsatt være til stede i programmet og være minst flere dusin ord i størrelse. I vårt første eksempel tildelte vi 128 ord til stabelen, noe som absolutt er nok.

^ Strukturen til et assemblerprogram

Et assembly-språkprogram er en samling av minneblokker kalt minnesegmenter. Et program kan bestå av ett eller flere slike blokksegmenter. Hvert segment inneholder en samling språksetninger, som hver opptar en egen linje med programkode.

Det er fire typer assembler-utsagn:

kommandoer eller instruksjoner som er symbolske analoger til maskinkommandoer. Under oversettelsesprosessen konverteres assemblerinstruksjoner til de tilsvarende kommandoene til;

makrokommandoer - setninger av programtekst formatert på en bestemt måte, erstattet under sending med andre setninger;

direktiver, som er instruksjoner til assembler-oversetteren om å utføre visse handlinger. Direktiver har ingen motparter i maskinrepresentasjon;

kommentarlinjer som inneholder tegn, inkludert bokstaver i det russiske alfabetet. Kommentarer ignoreres av oversetteren.

^ Monteringssyntaks

Setningene som utgjør et program kan være en syntaktisk konstruksjon som tilsvarer en kommando, makro, direktiv eller kommentar. For at assembler-oversetteren skal gjenkjenne dem, må de være dannet i henhold til visse syntaktiske regler. For å gjøre dette er det best å bruke en formell beskrivelse av syntaksen til språket, som grammatikkreglene. De vanligste måtene å beskrive et programmeringsspråk på på denne måten er syntaksdiagrammer og utvidede Backus-Naur-former. Til praktisk bruk syntaksdiagrammer er mer praktiske. For eksempel kan syntaksen til assembly-språksetninger beskrives ved å bruke syntaksdiagrammene vist i de følgende figurene.

Ris. 5. Monteringssetningsformat

Ris. 6. Direktivformat

Ris. 7. Format på kommandoer og makroer

På disse bildene:

etikettnavn - en identifikator hvis verdi er adressen til den første byten i setningen i kildekoden til programmet som den utpeker;

navn – en identifikator som skiller dette direktivet fra andre direktiver med samme navn. Som et resultat av montørens behandling av et bestemt direktiv, kan visse egenskaper tildeles det navnet;

en operasjonskode (OPC) og et direktiv er mnemoniske symboler for den tilsvarende maskininstruksjonen, makroinstruksjonen eller oversetterdirektivet;

operander er deler av et kommando-, makro- eller assembler-direktiv som angir objektene som handlinger utføres på. Assembly-språkoperander er beskrevet av uttrykk med numeriske og tekstkonstanter, etiketter og variable identifikatorer ved bruk av operatortegn og noen reserverte ord.

^ Hvordan bruker jeg syntaksdiagrammer? Det er veldig enkelt: alt du trenger å gjøre er å finne og deretter følge banen fra diagrammets inngang (til venstre) til utgangen (til høyre). Hvis en slik bane finnes, er setningen eller konstruksjonen syntaktisk korrekt. Hvis det ikke er en slik bane, vil ikke kompilatoren godta denne konstruksjonen. Når du arbeider med syntaksdiagrammer, vær oppmerksom på retningen på kryssingen som angis av pilene, siden det blant stiene kan være noen som kan følges fra høyre til venstre. I hovedsak reflekterer syntaksdiagrammer logikken til oversetterens operasjoner når de analyserer inndatasetningene til programmet.

Akseptable tegn når du skriver programtekst er:

Alle bokstaver: A-Å, a-å. I dette tilfellet anses store og små bokstaver som likeverdige;

Tall fra 0 til 9;

Tegn ?, @, $, _, &;

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

Forsamlingsspråksetninger er dannet fra leksemer, som er syntaktisk uatskillelige sekvenser av gyldige språksymboler som gir mening for oversetteren.

Leksemene er:

identifikatorer er sekvenser av gyldige tegn som brukes til å angi programobjekter som operasjonskoder, variabelnavn og etikettnavn. Regelen for å skrive identifikatorer er som følger: en identifikator kan bestå av ett eller flere tegn. Som symboler kan du bruke bokstaver i det latinske alfabetet, tall og noen spesialtegn - _, ?, $, @. En identifikator kan ikke begynne med et siffertegn. Lengden på identifikatoren kan være opptil 255 tegn, selv om oversetteren bare godtar de første 32 og ignorerer resten. Du kan justere lengden på mulige identifikatorer ved å bruke alternativet kommandolinje mv. I tillegg er det mulig å instruere oversetteren om å skille mellom store og små bokstaver eller å ignorere forskjellen deres (noe som gjøres som standard).

^Assembler-kommandoer.

Assembler-kommandoer avslører muligheten til å overføre dine krav til datamaskinen, en mekanisme for å overføre kontroll i et program (sykluser og overganger) for logiske sammenligninger og programorganisering. Imidlertid er programmerbare oppgaver sjelden så enkle. De fleste programmer inneholder en serie løkker der flere kommandoer gjentas til et visst krav er oppnådd, og ulike kontroller som bestemmer hvilken av flere handlinger som skal utføres. Noen instruksjoner kan overføre kontroll ved å endre den normale sekvensen av trinn ved å direkte modifisere offsetverdien i instruksjonspekeren. Som nevnt tidligere er det forskjellige kommandoer for forskjellige prosessorer, men vi skal se på en rekke noen kommandoer for 80186-, 80286- og 80386-prosessorene.

For å beskrive tilstanden til flaggene etter å ha utført en bestemt kommando, vil vi bruke et utvalg fra en tabell som gjenspeiler strukturen til eflags flaggregister:

Den nederste raden i denne tabellen viser verdiene til flaggene etter at kommandoen er utført. Følgende notasjoner brukes:

1 - etter at kommandoen er utført, settes flagget (lik 1);

0 - etter at kommandoen er utført, tilbakestilles flagget (lik 0);

r - verdien av flagget avhenger av resultatet av kommandoen;

Etter at kommandoen er utført, er flagget ikke definert;

mellomrom - etter at kommandoen er utført, endres ikke flagget;

Følgende notasjon brukes til å representere operander i syntaksdiagrammer:

r8, r16, r32 - en operand i et av registrene for bytestørrelse, ord eller dobbeltord;

m8, m16, m32, m48 - minneoperandstørrelse byte, ord, dobbeltord eller 48 biter;

i8, i16, i32 - umiddelbar operandstørrelse byte, ord eller dobbeltord;

a8, a16, a32 - relativ adresse (offset) i kodesegmentet.

Kommandoer (i alfabetisk rekkefølge):

*Disse kommandoene er beskrevet i detalj.

LEGG TIL
(Addisjon)

Addisjon

^ Kommandodiagram:

legg til destinasjon, kilde

Formål: tillegg av to kilde- og destinasjonsoperander av størrelse byte, ord eller dobbeltord.

Arbeidsalgoritme:

legg til kilde- og destinasjonsoperander;

skriv tilleggsresultatet til mottakeren;

sette flagg.

Status for flagg etter utførelse av kommando:

Applikasjon:
Add-kommandoen brukes til å legge til to heltallsoperander. Resultatet av tillegget plasseres på adressen til den første operanden. Hvis resultatet av tillegget går utover grensene til mottakeroperanden (et overløp oppstår), bør denne situasjonen tas i betraktning ved å analysere cf-flagget og den påfølgende mulige bruken av adc-kommandoen. La oss for eksempel legge til verdiene i akseregisteret og ch-minneområdet. Når du legger til, ta hensyn til muligheten for overløp.

Registrer pluss register eller minne:

|000000dw|modregr/rm|

AX register (AL) pluss umiddelbar verdi:

|0000010w|--data--|data hvis w=1|

Register eller minne pluss umiddelbar verdi:

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

ANROP
(ANROP)

Kalle en prosedyre eller oppgave

^ Kommandodiagram:

Hensikt:

overføring av kontroll til en nær eller fjern prosedyre med lagring av adressen til returpunktet på stabelen;

bytte oppgaver.

Arbeidsalgoritme:
bestemt av operandtypen:

Nær etikett - innholdet i eip/ip-kommandopekeren skyves på stabelen og den nye adresseverdien som tilsvarer etiketten lastes inn i samme register;

Far label - innholdet i eip/ip og cs kommandopekeren skyves på stabelen. Deretter lastes nye adresseverdier som tilsvarer den fjerneste etiketten inn i de samme registrene;

R16, 32 eller m16, 32 - definer et register eller en minnecelle som inneholder forskyvninger i det gjeldende instruksjonssegmentet som kontrollen overføres til. Når kontrollen overføres, skyves innholdet i eip/ip-kommandopekeren på stabelen;

Minnepeker - definerer en minneplassering som inneholder en 4 eller 6 byte peker til den anropte prosedyren. Strukturen til en slik peker er 2+2 eller 2+4 byte. Tolkningen av en slik peker avhenger av driftsmodusen til mikroprosessoren:

^ Status for flagg etter kommandoutførelse (unntatt oppgavebytte):

utførelse av kommandoen påvirker ikke flaggene

Når en oppgave byttes, endres flaggverdiene i henhold til informasjon om eflags-registeret i TSS-statussegmentet til oppgaven det byttes til.
Applikasjon:
Anropskommandoen lar deg organisere en fleksibel og multivariant overføring av kontroll til en subrutine samtidig som adressen til returpunktet bevares.

Objektkode (fire formater):

Direkte adressering i et segment:

|11101000|disp-lav|dyp-høy|

Indirekte adressering i et segment:

|11111111|mod010r/m|

Indirekte adressering mellom segmenter:

|11111111|mod011r/m|

Direkte adressering mellom segmenter:

|10011010|offset-low|offset-high|seg-low|seg-high|

CMP
(Sammenlign operander)

Operand sammenligning

^ Kommandodiagram:

cmp operand1,operand2

Formål: sammenligning av to operander.

Arbeidsalgoritme:

utføre subtraksjon(operand1-operand2);

avhengig av resultatet, sett flaggene, ikke endre operand1 og operand2 (det vil si, husk ikke resultatet).

Applikasjon:
Denne kommandoen brukes til å sammenligne to operander ved subtraksjon uten å endre operandene. Basert på resultatene av kommandoen settes flagg. cmp-kommandoen brukes med de betingede hoppkommandoene og set byte byte-kommandoen setcc.

Objektkode (tre formater):

Register eller minne med register:

|001110dw|modregr/m|

Umiddelbar verdi med AX (AL) register:

|0011110w|--data--|data hvis w=1|

Umiddelbar verdi med register eller minne:

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

DES
(Dekrementer operand med 1)

Reduser en operand med én

^ Kommandodiagram:

des operand

Formål: Reduser verdien av en operand i minnet eller registeret med 1.

Arbeidsalgoritme:
kommandoen trekker 1 fra operanden. Status for flagg etter utførelse av kommando:

Applikasjon:
Dec-instruksjonen brukes til å redusere verdien av en byte, ord, dobbeltord i minnet eller register med én. Vær imidlertid oppmerksom på at kommandoen ikke påvirker cf-flagget.

Registrer: |01001reg|

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

DIV
(DIVide usignert)

Usignert divisjon

Lagoversikt:

div skillevegg

Formål: Utfør en divisjonsoperasjon mellom to binære verdier uten fortegn.

^ Driftsalgoritme:
Kommandoen krever to operander - dividenden og divisoren. Utbyttet spesifiseres implisitt og størrelsen avhenger av størrelsen på divisoren, som er spesifisert i kommandoen:

hvis divisor er en byte i størrelse, må utbyttet være plassert i økseregisteret. Etter operasjonen plasseres kvotienten i al og resten i ah;

hvis divisor er et ord i størrelse, så må utbyttet være plassert i registerparet dx:ax, med den laveste delen av utbyttet plassert i ax. Etter operasjonen plasseres kvotienten i ax og resten i dx;

hvis divisor er et dobbeltord i størrelse, må utbyttet være plassert i registerparet edx:eax, med lavordensdelen av utbyttet i eax. Etter operasjonen legges kvotienten i eax og resten i edx.

^ Status for flagg etter utførelse av kommando:

Applikasjon:
Kommandoen utfører en heltallsdeling av operandene, og produserer resultatet av divisjonen som kvotient og resten av divisjonen. Når du utfører en delingsoperasjon, kan det oppstå et unntak: 0 - divisjonsfeil. Denne situasjonen oppstår i ett av to tilfeller: divisoren er 0 eller kvotienten er for stor til å passe inn i eax/ax/al-registeret.

Objektkode:

|1111011w|mod110r/m|

INT
(Avbryte)

Ringer avbruddsservicerutinen

^ Kommandodiagram:

int interrupt_number

Formål: kall opp avbruddsservicerutinen med avbruddsnummeret spesifisert av kommandooperanden.

^ Driftsalgoritme:

skyv flaggregisteret eflag/flagg og returadressen på stabelen. Ved skriving av en returadresse skrives først innholdet i segmentregisteret cs, deretter innholdet i kommandopekeren eip/ip;

tilbakestill if og tf flaggene til null;

overføre kontrollen til avbruddsserviceprogrammet med det angitte nummeret. Kontrolloverføringsmekanismen avhenger av driftsmodusen til mikroprosessoren.

^ Status for flagg etter utførelse av kommando:

Applikasjon:
Som du kan se fra syntaksen, er det to former for denne kommandoen:

int 3 - har sin egen individuelle operasjonskode 0cch og opptar en byte. Denne omstendigheten gjør det veldig praktisk for bruk i ulike programvaredebuggere å angi bruddpunkter ved å erstatte den første byten i en kommando. Mikroprosessoren, som møter en kommando med operasjonskode 0cch i rekkefølgen av kommandoer, kaller opp avbruddsbehandlingsprogrammet med vektornummer 3, som tjener til å kommunisere med programvaredebuggeren.

Den andre formen for kommandoen opptar to byte, har en opkode på 0cdh og lar deg starte et anrop til en avbruddstjenesterutine med et vektornummer i området 0–255. Funksjoner for kontrolloverføring, som nevnt, avhenger av driftsmodusen til mikroprosessoren.

Objektkode (to formater):

Registrer: |01000reg|

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

J.C.C.
JCXZ/JECXZ
(Hopp hvis tilstand)

(Hopp hvis CX=null/hopp hvis ECX=null)

Hopp hvis betingelsen er oppfylt

Hopp hvis CX/ECX er null

^ Kommandodiagram:

jcc-etikett
jcxz etikett
jecxz etikett

Formål: overgang innenfor gjeldende kommandosegment avhengig av en tilstand.

^ Kommandoalgoritme (unntatt jcxz/jecxz):
Kontrollerer statusen til flaggene avhengig av op-koden (den gjenspeiler tilstanden som kontrolleres):

hvis tilstanden som testes er sann, gå til cellen angitt av operanden;

hvis tilstanden som kontrolleres er usann, overfører du kontrollen til neste kommando.

Algoritme for kommandoen jcxz/jecxz:
Kontroller betingelsen om at innholdet i ecx/cx-registeret er lik null:

hvis tilstanden kontrolleres

Kommandostruktur på assemblerspråk Programmering på nivå med maskinkommandoer er minimumsnivået der dataprogrammering er mulig. Maskinkommandosystemet må være tilstrekkelig til å gjennomføre nødvendige handlinger ved å gi instruksjoner til maskinutstyret. Hver maskininstruksjon består av to deler: en operasjonell, som bestemmer "hva du skal gjøre" og en operand, som bestemmer behandlingsobjektene, det vil si "hva du skal gjøre". En mikroprosessormaskininstruksjon, skrevet på Assembly-språket, er en enkelt linje som har følgende form: etikettkommando/direktivoperand(er); kommentarer Etiketten, kommandoen/direktivet og operanden er atskilt med minst ett mellomrom eller tabulatortegn. Operandene til kommandoen er atskilt med komma.

Assembly Language Kommandostruktur En assembler-kommando forteller oversetteren hvilken handling mikroprosessoren skal utføre. Monteringsdirektiver er parametere spesifisert i programteksten som påvirker monteringsprosessen eller egenskapene til utdatafilen. Operaanden spesifiserer startverdien til dataene (i datasegmentet) eller elementene som kommandohandlingen utføres på (i kodesegmentet). En instruksjon kan ha en eller to operander, eller ingen operander. Antall operander er implisitt spesifisert av instruksjonskoden. Hvis en kommando eller et direktiv må fortsette på neste linje, brukes omvendt skråstrek: "" . Som standard skiller ikke assembler mellom store og små bokstaver når du skriver kommandoer og direktiver. Eksempler på direktiver og kommandoer Tell db 1 ; Navn, direktiv, en operand mov eax, 0 ; Kommando, to operander

Identifikatorer er sekvenser av gyldige tegn som brukes til å betegne variabelnavn og etikettnavn. Identifikatoren kan bestå av ett eller flere av følgende tegn: alle bokstaver i det latinske alfabetet; tall fra 0 til 9; spesialtegn: _, @, $, ? . En prikk kan brukes som det første tegnet på etiketten. Reserverte assemblernavn (direktiver, operatører, kommandonavn) kan ikke brukes som identifikatorer. Det første tegnet i identifikatoren må være en bokstav eller et spesialtegn. Maksimal lengde Identifikatoren har 255 tegn, men oversetteren godtar de første 32 og ignorerer resten. Alle etiketter som er skrevet på en linje som ikke inneholder et assembler-direktiv, må slutte med et kolon ":". Etiketten, kommandoen (direktivet) og operanden trenger ikke å starte på noen bestemt posisjon på linjen. Det anbefales å skrive dem i en spalte for større lesbarhet av programmet.

Etiketter Alle etiketter som er skrevet på en linje som ikke inneholder et assembler-direktiv må slutte med et kolon ":". Etiketten, kommandoen (direktivet) og operanden trenger ikke å starte på noen bestemt posisjon på linjen. Det anbefales å skrive dem i en spalte for større lesbarhet av programmet.

Kommentarer Bruk av kommentarer i et program forbedrer dets klarhet, spesielt der formålet med et sett med kommandoer er uklart. Kommentarer begynner på en hvilken som helst linje i kildemodulen med semikolon (;). Alle tegn til høyre for "; " til slutten av linjen er en kommentar. En kommentar kan inneholde alle utskrivbare tegn, inkludert mellomrom. En kommentar kan strekke seg over hele linjen eller følge en kommando på samme linje.

Assembly Language Programstruktur Et program skrevet i assemblerspråk kan bestå av flere deler kalt moduler, som hver kan definere ett eller flere data-, stack- og kodesegmenter. Ethvert komplett program i assemblerspråk må inkludere én hoved- eller hovedmodul som utførelsen starter fra. Modulen kan inneholde programsegmenter, data og stabelsegmenter deklarert ved hjelp av passende direktiver.

Minnemodeller Før du deklarerer segmenter, må du spesifisere minnemodellen ved hjelp av et direktiv. MODELL modifikator memory_model, calling_convention, OS_type, stack_parameter Grunnleggende minnemodeller for assemblyspråk: Minnemodell Kodeadressering Dataadressering operativsystem Interleaving kode og data TINY NÆR MS-DOS Akseptabel LITEN NÆR MS-DOS, Windows Ingen MIDDELS LANGT NÆR MS-DOS, Windows Ingen KOMPAKT NÆR LANGT MS-DOS, Windows Ikke STOR FART MS-DOS, Windows Ingen STOR LANGT MS-DOS, Windows No NEAR Windows 2000, Windows XP, Windows Acceptable FLAT NEAR NT,

Minnemodeller Den lille modellen fungerer bare i 16-bits MS-DOS-applikasjoner. I denne modellen er alle data og kode plassert på ett fysisk segment. Størrelsen på programfilen i dette tilfellet overstiger ikke 64 KB. Den lille modellen støtter ett kodesegment og ett datasegment. Data og kode adresseres så nært når denne modellen brukes. Mediummodellen støtter flere kodesegmenter og ett datasegment, med alle referanser i kodesegmenter ansett som langt som standard, og referanser i et datasegment ansett som nærliggende. Den kompakte modellen støtter flere datasegmenter som bruker fjerndataadressering (fart), og ett kodesegment som bruker næradressering (nær). Den store modellen støtter flere kodesegmenter og flere datasegmenter. Som standard regnes alle referanser til kode og data langt. Den enorme modellen tilsvarer nesten den store minnemodellen.

Minnemodeller Den flate modellen antar en usegmentert programkonfigurasjon og brukes kun i 32-biters operativsystemer. Denne modellen ligner på den lille modellen ved at dataene og koden er plassert i et enkelt segment, men den er 32-bit. Å utvikle et program for den flate modellen før direktivet. modell flat bør plassere en av direktivene: . 386,. 486,. 586 eller. 686. Valget av prosessorvalgsdirektiv bestemmer settet med instruksjoner som er tilgjengelige når du skriver programmer. Bokstaven p etter prosessorvalgdirektivet betyr beskyttet driftsmodus. Data- og kodeadressering er nær, og alle adresser og pekere er 32-biters.

Minnemodeller. MODELL modifikator memory_model, calling_convention, OS_type, stack_parameter Modifikatorparameteren brukes til å definere segmenttyper og kan ha følgende verdier: bruk 16 (segmenter av den valgte modellen brukes som 16-bit) bruk 32 (segmenter av den valgte modellen brukes som 32-bit). Calling_convention-parameteren brukes til å bestemme metoden for å sende parametere når en prosedyre kalles fra andre språk, inkludert høynivåspråk (C++, Pascal). Parameteren kan ha følgende verdier: C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

Minnemodeller. MODELL modifikator memory_model, calling_convention, OS_type, stack_parameter OS_type-parameteren er OS_DOS som standard, og på dette øyeblikket dette er den eneste støttede verdien for denne parameteren. Stack_parameter-parameteren er satt til: NEARSTACK (SS-register er lik DS, data og stabelområder er allokert i samme fysiske segment) FARSTACK (SS-register er ikke lik DS, data og stabelområder er allokert i forskjellige fysiske segmenter). Standardverdien er NEARSTACK.

Et eksempel på et program som ikke gjør noe. 686 P. MODELL FLAT, STDCALL. DATA. KODE START: RET END START RET - mikroprosessorkommando. Det sikrer at programmet avsluttes på riktig måte. Resten av programmet gjelder driften av oversetteren. . 686 P - Pentium 6 (Pentium II) beskyttet modus kommandoer er tillatt. Dette direktivet velger det støttede settet med monteringsinstruksjoner, som indikerer prosessormodellen. . MODELL FLAT, stdcall - flat minne modell. Denne minnemodellen brukes i Windows-operativsystemet. stdcall - prosedyrekallingskonvensjonen som brukes.

Et eksempel på et program som ikke gjør noe. 686 P. MODELL FLAT, STDCALL. DATA. KODE START: RET END START. DATA er et programsegment som inneholder data. Dette programmet bruker ikke stabelen, så segmentet. STAKKEN mangler. . CODE er et programsegment som inneholder kode. START - etikett. END START - slutten av programmet og en melding til kompilatoren om at programkjøringen skal begynne med START-etiketten. Hvert program må inneholde et END-direktiv for å markere slutten kildekode programmer. Alle linjer som følger END-direktivet ignoreres. Etiketten spesifisert etter END-direktivet forteller oversetteren navnet på hovedmodulen som programkjøringen starter fra. Hvis programmet inneholder én modul, kan etiketten etter END-direktivet utelates.

Montering språkoversettere Oversetter - program eller tekniske midler, som konverterer et program representert på et av programmeringsspråkene til et program på målspråket, kalt objektkode. I tillegg til å støtte maskininstruksjonsminne, har hver oversetter sitt eget sett med direktiver og makroverktøy, ofte uforenlige med noe annet. De viktigste typene assembler-oversettere: MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler) - en fritt distribuert multi-pass assembler skrevet av Tomasz Gryshtar (polsk), NASM (Netwide Assembler) - en gratis assembler for Intel x architecture 86, ble opprettet av Simon Tatham med Julian Hall og utvikles for tiden av et lite team av utviklere hos Source. Smi. nett.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="Oversette et program i Microsoft Visual Studio 2005 1) Opprett et prosjekt ved å velge Fil->Ny- >Prosjektmeny Og"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В дополнительных опциях мастера проекта указать “Empty Project”.!}

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

Oversette programmet til Microsoft Visual Studio 2005 3) Velg filtypen Code C++, men spesifiser navnet med filtypen. asm:

Oversette programmet til Microsoft Visual Studio 2005 5) Angi kompilatorparametere. Høyreklikk på menyen Egendefinerte byggeregler i prosjektfilen...

Oversett programmet til Microsoft Visual Studio 2005 og velg Microsoft Macro Assembler i vinduet som vises.

Oversettelse av programmet i Microsoft Visual Studio 2005 Sjekk med høyre knapp i filen hei. asm-prosjekttreet i Egenskaper-menyen og installer Generelt->Verktøy: Microsoft Macro Assembler.

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

Programmering i Windows OS Programmering i Windows OS er basert på bruk av API-funksjoner (Application Program Interface, dvs.tt). Antallet deres når 2000. Windows-programmet består i stor grad av slike samtaler. Alle interaksjoner med eksterne enheter og operativsystemressurser oppstår som regel gjennom slike funksjoner. Operasjonssal Windows-system bruker en flat minnemodell. Adressen til en hvilken som helst minnecelle vil bli bestemt av innholdet i ett 32-bits register. Det er 3 typer programstrukturer for Windows: dialog (hovedvinduet er dialog), konsoll eller vindusløs struktur, klassisk struktur (vindu, ramme).

Anrop Windows-funksjoner API I hjelpefilen presenteres enhver API-funksjon som type funksjonsnavn (FA 1, FA 2, FA 3) Type – returverditype; FAx – en liste over formelle argumenter i den rekkefølgen de vises, for eksempel int Message. Boks(HWND h. Wnd, LPCTSTR lp. Tekst, LPCTSTR lp. Bildetekst, UINT u. Type); Denne funksjonen viser et vindu med en melding og en exit-knapp (eller -knapper). Betydning av parametere: h. Wnd er en beskrivelse av vinduet der meldingsvinduet vises, lp. Tekst - tekst som vises i vinduet, lp. Bildetekst - tekst i vinduets tittel, u. Type - vindustype; spesielt kan du bestemme antall utgangsknapper.

Kalle opp Windows API int Meldingsfunksjoner. Boks(HWND h. Wnd, LPCTSTR lp. Tekst, LPCTSTR lp. Bildetekst, UINT u. Type); Nesten alle API-funksjonsparametere er faktisk 32-biters heltall: HWND er et 32-biters heltall, LPCTSTR er en 32-biters peker til en streng, UINT er et 32-biters heltall. Suffikset "A" legges ofte til funksjonsnavnet for å flytte til nyere versjoner av funksjonen.

Kalle opp Windows API int Meldingsfunksjoner. Boks(HWND h. Wnd, LPCTSTR lp. Tekst, LPCTSTR lp. Bildetekst, UINT u. Type); Når du bruker MASM, må du legge til @N N på slutten av navnet - antallet byte som de beståtte argumentene opptar på stabelen. For Win 32 API-funksjoner kan dette tallet defineres som antall argumenter n multiplisert med 4 (byte i hvert argument): N=4*n. For å kalle en funksjon, bruk assembler CALL-instruksjonen. I dette tilfellet sendes alle funksjonsargumenter til den via stabelen (PUSH-kommando). Retning for å sende argumenter: VENSTRE TIL HØYRE - NEDEN OPP. Argumentet u blir skjøvet på stabelen først. Type. Anropet til den angitte funksjonen vil se slik ut: CALL-melding. Eske. A@16

Kalle opp Windows API int Meldingsfunksjoner. Boks(HWND h. Wnd, LPCTSTR lp. Tekst, LPCTSTR lp. Bildetekst, UINT u. Type); Resultatet av å utføre en API-funksjon er vanligvis et heltall som returneres i EAX-registeret. OFFSET-direktivet representerer en "forskyvning i et segment", eller, oversatt til språk på høyt nivå, en "peker" til begynnelsen av en linje. EQU-direktivet, som #define i SI, definerer en konstant. EXTERN-direktivet forteller oversetteren at funksjonen eller identifikatoren er ekstern i forhold til denne modulen.

Eksempel på et "Hei alle sammen!"-program . 686 P. MODELL FLAT, STDCALL. STACK 4096. DATA MB_OK EQU 0 STR 1 DB "Mitt første program", 0 STR 2 DB "Hei alle sammen!", 0 HW DD ? EKSTERN melding. Eske. A@16: NÆR. KODE START: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Melding. Eske. A@16 RET END START

INVOKE-direktivet MASM-språkoversetteren lar deg også forenkle funksjonskall ved hjelp av et makroverktøy - INVOKE-direktivet: INVOKE-funksjon, parameter1, parameter2, ... Det er ikke nødvendig å legge til @16 ​​i funksjonskallet; parametere skrives nøyaktig i den rekkefølgen de er gitt i funksjonsbeskrivelsen. Ved hjelp av makro ved hjelp av oversetteren plasseres parametere på stabelen. For å bruke INVOKE-direktivet må du ha en beskrivelse av funksjonsprototypen ved hjelp av PROTO-direktivet i formen: Melding. Eske. ET PROTO: DWORD, : DWORD Hvis et program bruker mange Win 32 API-funksjoner, er det tilrådelig å bruke include-direktivet C: masm 32includeuser 32. inc

Emne 2.5 Grunnleggende om prosessorprogrammering

Etter hvert som lengden på programmet øker, blir det stadig vanskeligere å huske kodene for ulike operasjoner. Mnemonics gir litt hjelp i denne forbindelse.

Det symbolske kommandokodespråket kalles montør.

Forsamlingsspråk er et språk der hver ytring tilsvarer nøyaktig én maskinkommando.

montering kalles å konvertere et program fra assemblerspråk, dvs. å forberede et program på maskinspråk ved å erstatte symbolske navn på operasjoner med maskinkoder, og symbolske adresser med absolutte eller relative tall, samt inkorporere bibliotekprogrammer og generere sekvenser av symbolske instruksjoner ved å spesifisere spesifikke parametere i mikrolag. Dette programmet er vanligvis plassert i ROM eller lagt inn i RAM fra noen eksterne medier.

Monteringsspråk har flere funksjoner som skiller det fra språk på høyt nivå:

1. Dette er en en-til-en-korrespondanse mellom assembly-språksetninger og maskininstruksjoner.

2. En assemblerspråkprogrammerer har tilgang til alle objekter og instruksjoner som finnes på målmaskinen.

Å forstå det grunnleggende om programmering i maskinorienterte språk er nyttig for:



Bedre forståelse av PC-arkitektur og mer kompetent bruk av datamaskiner;

Å utvikle mer rasjonelle strukturer av algoritmer for programmer for å løse anvendte problemer;

Muligheten til å vise og korrigere kjørbare programmer med utvidelsen .exe og .com, kompilert fra alle høynivåspråk, i tilfelle tap av kildeprogrammene (ved å kalle de spesifiserte programmene i DEBUG-programmets debugger og dekompilere visningen deres i assembly Språk);

Kompilere programmer for å løse de mest kritiske problemene (et program skrevet på et maskinorientert språk er vanligvis mer effektivt - kortere og raskere med 30-60 prosent av programmene oppnådd som et resultat av oversettelse fra språk på høyt nivå)

Å implementere prosedyrer inkludert i hovedprogrammet i form av separate fragmenter i tilfelle de ikke kan implementeres verken på høynivåspråket som brukes eller ved bruk av OS-tjenesteprosedyrer.

Et program i assemblerspråk kan bare kjøres på én familie av datamaskiner, mens et program skrevet på et høynivåspråk potensielt kan kjøres på forskjellige maskiner.

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

Tall er bare heltall. Det er:

Binære tall slutter med bokstaven B;

Desimaltall som slutter med bokstaven D;

Heksadesimale tall slutter med bokstaven H.

RAM, registre, datapresentasjon

For en viss serie parlamentsmedlemmer brukes et individuelt programmeringsspråk - assembly language.

Monteringsspråk inntar en mellomposisjon mellom maskinkoder og høynivåspråk. Programmering på dette språket er enklere. Et program i assemblerspråk gjør mer effektiv bruk av egenskapene til en spesifikk maskin (mer presist, en MP) enn et program på et høynivåspråk (som er enklere for en programmerer enn assembler). La oss se på de grunnleggende prinsippene for programmering i maskinorienterte språk ved å bruke eksempelet på monteringsspråk for MP KR580VM80. En generell metodikk brukes for å programmere i språket. Spesifikke tekniske teknikker for opptak av programmer er knyttet til funksjonene til arkitekturen og kommandosystemet til mål-MP.

Programvaremodell mikroprosessorsystem basert på MP KR580VM80

Programvaremodell av MPS i samsvar med figur 1

MP-porter minne

S Z A.C. P C

Bilde 1

Fra programmererens synspunkt har MP KR580VM80 følgende programtilgjengelige registre.

EN– 8-biters akkumulatorregister. Det er hovedregisteret til MP. Enhver operasjon utført i en ALU innebærer å plassere en av operandene som skal behandles i akkumulatoren. Resultatet av en operasjon i ALU er også vanligvis lagret i A.

B, C, D, E, H, L– 8-bits registre for generelle formål (GPR). Indre minne MP. Designet for å lagre behandlet informasjon, samt resultatene av operasjonen. Ved behandling av 16-bits ord danner registre parene BC, DE, HL, og dobbeltregisteret kalles den første bokstaven - B, D, H. I et registerpar er det høyeste det første registeret. Registerne H og L har en spesiell egenskap, som brukes både for lagring av data og for lagring av 16-bits adresser til RAM-celler.

FL– flaggregister (tegnregister) 8-bits register der fem tegn på resultatet av å utføre aritmetiske og logiske operasjoner i MP er lagret. FL format i henhold til bildet

Bit C (CY - bære) - bære, satt til 1 hvis det var en bære fra den høye rekkefølgen til byten ved utførelse av aritmetiske operasjoner.

Bit P (paritet) – paritet, satt til 1 hvis antallet enere i bitene til resultatet er partall.

AC-sifferet er en ekstra bære, designet for å lagre bæreverdien fra lavordens tetrad av resultatet.

Bit Z (null) – satt til 1 hvis resultatet av operasjonen er 0.

Bit S (tegn) – settes til 1 hvis resultatet er negativt, og til 0 hvis resultatet er positivt.

SP– stack pointer, et 16-bits register, designet for å lagre adressen til minnecellen der den siste byten som ble satt inn i stabelen ble skrevet.

RS– programteller (programteller), et 16-bits register, designet for å lagre adressen til neste instruksjon som skal utføres. Innholdet i programtelleren økes automatisk med 1 umiddelbart etter henting av neste instruksjonsbyte.

I det opprinnelige minneområdet til adressen 0000Н – 07FF er det kontrollprogram og demonstrasjonsprogrammer. Dette er ROM-området.

0800 – 0AFF - adresseområde for opptak av programmene som studeres. (RAM).

0В00 – 0ВВ0 - adresseområde for skriving av data. (RAM).

0ВВ0 – startadressen til stabelen. (RAM).

En stabel er et spesielt organisert område med RAM beregnet for midlertidig lagring av data eller adresser. Det siste tallet som er skrevet til stabelen, vises først. Stabelpekeren lagrer adressen til den siste stabelcellen der informasjonen er skrevet. Når en subrutine kalles opp, lagres returadressen til hovedprogrammet automatisk på stabelen. Som regel lagres innholdet i alle registre som er involvert i dens utførelse i begynnelsen av hver subrutine på stabelen, og på slutten av subrutinen blir de gjenopprettet fra stabelen.

Dataformat og kommandostruktur for monteringsspråk

Minnet til MP KR580VM80 er en rekke 8-bits ord kalt bytes.Hver byte har sin egen 16-bits adresse, som bestemmer posisjonen i sekvensen av minneceller. MP kan adressere 65536 byte med minne, som kan inneholde både ROM og RAM.

Dataformat

Data lagres i minnet som 8-bits ord:

D7 D6 D5 D4 D3 D2 D1 D0

Den minst signifikante biten er bit 0, den mest signifikante biten er bit 7.

En kommando er preget av formatet, det vil si antall biter som er tildelt for den, som er delt byte-for-byte i visse funksjonelle felt.

Kommandoformat

MP KR580VM80-kommandoer har ett, to eller tre byte-format. Multibyte-kommandoer må plasseres på tilstøtende språk. Kommandoformatet avhenger av spesifikasjonene til operasjonen som utføres.

Den første byten av kommandoen inneholder operasjonskoden, skrevet i mnemonisk form.

Den bestemmer kommandoformatet og handlingene som må utføres av MP på dataene under utførelsen, og adresseringsmetoden, og kan også inneholde informasjon om plasseringen av dataene.

Den andre og tredje byten kan inneholde data som operasjoner utføres på, eller adresser som indikerer plasseringen av dataene. Dataene som handlinger utføres på kalles operander.

Single-byte kommandoformat i henhold til figur 2

Figur 4

I assembly-språkkommandoer har operasjonskoden en forkortet form for å skrive engelske ord - en mnemonisk notasjon. Mnemonics (fra det greske mnemonic - kunsten å memorere) gjør det lettere å huske kommandoer etter deres funksjonelle formål.

Før utførelse oversettes kildeprogrammet ved hjelp av et oversettelsesprogram kalt assembler til språket for kodekombinasjoner - maskinspråk, i denne formen plasseres det i minnet til MP og brukes deretter når kommandoen utføres.


Adresseringsmetoder

Alle operandkoder (inngang og utgang) må være plassert et sted. De kan være plassert i de interne registrene til MP (den mest praktiske og raskt alternativ). De kan være plassert i systemminnet (det vanligste alternativet). Til slutt kan de lokaliseres i I/O-enheter (det sjeldneste tilfellet). Plasseringen av operandene bestemmes av instruksjonskoden. Eksistere ulike metoder, med hvilken instruksjonskoden kan bestemme hvor inngangsoperanden skal tas og hvor utgangsoperanden skal plasseres. Disse metodene kalles adresseringsmetoder.

For MP KR580VM80 finnes følgende adresseringsmetoder:

Direkte;

Registrere;

Indirekte;

Stablet.

Direkte adressering forutsetter at (input)-operanden er plassert i minnet umiddelbart etter instruksjonskoden. Operaanden er vanligvis en konstant som må sendes et sted, legges til noe osv. dataene er inneholdt i den andre eller andre og tredje byten av kommandoen, med den lave byten med data plassert i den andre byten av kommandoen, og den høye byten i den tredje kommandobyten.

Rett (aka absolutt) adressering forutsetter at operanden (inngang eller utgang) er plassert i minnet på adressen, hvis kode er plassert inne i programmet umiddelbart etter instruksjonskoden. Brukes i tre-byte kommandoer.

Registrere adressering forutsetter at operanden (inngang eller utgang) er i det interne registeret til MP. Brukes i enkeltbyte-kommandoer

Indirekte (implisitt) adressering forutsetter at det interne registeret til MP ikke inneholder selve operanden, men adressen i minnet.

Stable adressering forutsetter at kommandoen ikke inneholder en adresse. Adressering av minneceller ved hjelp av innholdet i 16-bits SP-registeret (stabelpeker).

Kommandosystem

MP-kommandosystemet er en komplett liste over elementære handlinger som MP er i stand til å utføre. MP kontrollert av disse kommandoene utfører enkle handlinger, som elementære aritmetiske og logiske operasjoner, dataoverføring, sammenligning av to verdier, etc. Antallet kommandoer til MP KR580VM80 er 78 (som tar hensyn til modifikasjoner 244).

Følgende grupper av kommandoer skilles ut:

Data overføring;

Aritmetikk;

Hjernetrim;

Hoppkommandoer;

Input/output, control og stack-kommandoer.


Symboler og forkortelser som brukes når du beskriver kommandoer og komponerer programmer

Symbol Reduksjon
ADDR 16-biters adresse
DATA 8-bits data
DATA 16 16-biters data
HAVN 8-biters I/O-enhetsadresse
BYTE 2 Andre byte av kommandoen
BYTE 3 Tredje kommandobyte
R, Rl, R2 Ett av registrene: A, B, C, D, E, H, L
R.P. Ett av registerparene: B - spesifiserer paret BC; D - spesifiserer et DE-par; H – spesifiserer HL-paret
RH Første register av paret
R.L. Andre register av paret
Λ Logisk multiplikasjon
V Logisk tillegg
Tillegg modulo to
M En minnecelle hvis adresse spesifiserer innholdet i registerparet HL, dvs. M = (HL)



Topp