Forsamlingsspråk

Forsamlingsspråk


Motorola MC6800 Assembler oppføring
?
Generell informasjon
Vanlige utvidelser .asm
Paradigme Imperativ , ustrukturert
Dukket opp i 1949

Assembly language eller assembler (på engelsk : assembler language og forkortelsen asm ) er et programmeringsspråk på lavt nivå . Den består av et sett med mnemonikk som representerer grunnleggende instruksjoner for datamaskiner , mikroprosessorer , mikrokontrollere og andre programmerbare integrerte kretser . Den implementerer en symbolsk representasjon av de binære maskinkodene og andre konstanter som er nødvendige for å programmere en prosessorarkitektur og er den mest direkte representasjonen av den spesifikke maskinkoden for hver arkitektur som kan leses av en programmerer. Hver prosessorarkitektur har sitt eget assembly-språk som vanligvis er definert av maskinvareprodusenten , og er basert på mnemonics som symboliserer prosesseringstrinn ( instruksjoner ), prosessorregistre , minneplasseringer og andre språkfunksjoner. Et monteringsspråk er derfor spesifikt for en viss fysisk (eller virtuell) datamaskinarkitektur . Dette er i motsetning til de fleste programmeringsspråk på høyt nivå , som ideelt sett er bærbare .

Et hjelpeprogram kalt en assembler brukes til å oversette assembly-språkutsagn til maskinkoden til måldatamaskinen. Montøren utfører en omtrent isomorf oversettelse (en en-til-en-kartlegging) fra mnemoniske uttalelser til maskininstruksjonene og dataene. Dette er i motsetning til språk på høyt nivå, der en enkelt setning generelt gir opphav til mange maskininstruksjoner.

Mange sofistikerte montører tilbyr tilleggsmekanismer for å lette programutvikling, kontrollere monteringsprosessen og hjelpe til med feilsøking . Spesielt inkluderer de fleste moderne montører et makroanlegg (beskrevet nedenfor), og kalles makromontører .

Det ble hovedsakelig brukt i de tidlige dagene av programvareutvikling , da kraftige høynivåspråk ennå ikke var tilgjengelig og ressursene var begrenset. Den brukes for tiden ofte i akademiske miljøer og forskningsmiljøer, spesielt når direkte manipulering av maskinvare , høy ytelse eller kontrollert og redusert ressursbruk er nødvendig. Det brukes også i utviklingen av enhetsdrivere (på engelsk enhetsdrivere ) og i utviklingen av operativsystemer, på grunn av behovet for direkte tilgang til maskininstruksjoner. Mange programmerbare enheter (som mikrokontrollere) er fortsatt avhengige av assembleren som den eneste måten å manipulere dem på.

Funksjoner

Monteringsprogram

Vanligvis lager et moderne monteringsprogram objektkode ved å oversette mnemonic assembly- språkinstruksjoner til opkoder og løse symbolske navn for minneplasseringer og andre enheter. [ 2 ] Bruken av symbolske referanser er en nøkkelfunksjon i assembly-språket, og unngår kjedelige beregninger og manuell oppdatering av adresser etter hver programmodifikasjon. De fleste montører inkluderer også makrofasiliteter for å utføre tekstsubstitusjon - f.eks. generere korte sekvenser med instruksjoner som innebygd utvidelse i stedet for å ringe subrutiner .

Assemblere er generelt enklere å skrive enn kompilatorer for språk på høyt nivå , og har vært tilgjengelig siden 1950-tallet. Moderne assemblere, spesielt for RISC -baserte arkitekturer som MIPS , Sun SPARC og HP PARISC , samt for x86 ( -64 ), optimalisere instruksjonsplanlegging for å utnytte CPU-rørledningen effektivt.

I kompilatorer for høynivåspråk er de det siste trinnet før du genererer kjørbar kode.

Antall trinn

Det er to typer samlere basert på hvor mange passeringer gjennom kilden som kreves for å produsere det kjørbare programmet.

Fordelen med en enkelt-pass assembler er hastighet, som ikke er så viktig som det en gang ble gitt fremskritt i datamaskinens hastighet og kapasitet. Fordelen med to-trinns assembler er at symbolene kan defineres hvor som helst i kildekoden til programmet. Dette gjør at programmer kan defineres på mer logiske og meningsfulle måter, noe som gjør to-trinns assemblerprogrammer lettere å lese og vedlikeholde. [ 3 ]

Montører på høyt nivå

De mest sofistikerte høynivåmontørene gir språkabstraksjoner som:

Bruk av begrepet

Merk at, i normal profesjonell bruk, brukes begrepet assembler ofte for å referere til både assemblerspråk og assemblerprogram (som konverterer kildekode skrevet på assemblerspråk til objektkode som deretter vil bli koblet til å produsere maskinspråk ). Følgende to uttrykk bruker begrepet "montør":

Språk

Assembly språk reflekterer direkte arkitekturen og maskinspråkinstruksjonene til CPU, og kan være svært forskjellig fra én CPU-arkitektur til en annen.

Hver mikroprosessorarkitektur har sitt eget maskinspråk, og følgelig sitt eget assemblyspråk, siden den er nært knyttet til strukturen til maskinvaren den er programmert for. Mikroprosessorer er forskjellige i typen og antall operasjoner de støtter; de kan også ha ulikt antall registre, og ulik representasjon av datatyper i minnet. Selv om de fleste mikroprosessorer er i stand til i det vesentlige de samme funksjonene, er måten de gjør det på, forskjellig, og de respektive monteringsspråkene gjenspeiler den forskjellen.

CPU-instruksjoner

De fleste CPUer har mer eller mindre de samme gruppene av instruksjoner, selv om de ikke nødvendigvis har alle instruksjonene i hver gruppe. Operasjonene som kan utføres varierer fra én CPU til en annen. En bestemt CPU kan ha instruksjoner som en annen ikke har, og omvendt.

Tidlige 8-bits mikroprosessorer hadde ikke operasjoner for å multiplisere eller dividere tall, for eksempel, og du måtte lage subrutiner for å utføre disse operasjonene. Andre CPUer har kanskje ikke flyttalloperasjoner, og du må lage eller skaffe biblioteker som utfører disse operasjonene.

CPU-instruksjoner kan grupperes, i henhold til deres funksjonalitet, i:

Heltallsoperasjoner: (8, 16, 32 og 64 bits avhengig av CPU-arkitekturen, på svært gamle systemer også 12, 18, 24, 36 og 48 biter).

Dette er operasjoner utført av den aritmetiske logiske enheten til CPU:

Dataflytteoperasjoner:

Mellom registre og minne: Selv om instruksjonen kalles "move", i CPU, betyr "move data" faktisk å kopiere data, fra en kilde til en destinasjon, uten at dataene forsvinner fra kilden. Verdier kan flyttes: Merk: En umiddelbar verdi er en konstant som er spesifisert i samme mikroinstruksjon. Stableoperasjoner ( stack , på engelsk): Inn-/ utgangsoperasjoner : De er operasjoner som flytter data fra et register, til og fra en port; eller minne, til og fra en port

Operasjoner for programflytkontroll:

Operasjoner med reelle tall:

Standarden for reelle talloperasjoner i CPUer er definert av IEEE 754 .

En CPU kan ha flyttallsoperasjoner med reelle tall ved å bruke den numeriske koprosessoren (hvis noen), for eksempel følgende:

Assembly-språket har mnemonics for hver av CPU-instruksjonene i tillegg til andre mnemonics som skal behandles av monteringsprogrammet (som makroer og andre setninger på monteringstidspunktet).

Montering

Transformasjonen fra assemblerspråk til maskinkode gjøres av et assemblerprogram , og den omvendte oversettelsen kan gjøres av en disassembler . I motsetning til høynivåspråk , er det her vanligvis en 1-til-1-korrespondanse mellom enkle monteringsinstruksjoner og maskinspråk. Men i noen tilfeller kan en montør gi "pseudo-instruksjoner" som utvides til større maskinkode for å gi nødvendig funksjonalitet og forenkle programmering. For eksempel, for betinget maskinkode som "hvis X større enn eller lik", kan en assembler bruke en pseudo-instruksjon for å gruppere "gjør hvis mindre enn", og "hvis = 0" på resultatet av den forrige betingelsen. Mer komplette Assemblers gir også et rikt makrospråk som brukes til å generere mer kompleks kode og datastrømmer.

For den samme prosessoren og det samme settet med CPU-instruksjoner kan forskjellige monteringsprogrammer hver ha variasjoner og forskjeller i settet med mnemonics eller i syntaksen til assemblerspråket deres. For eksempel, i et assemblerspråk for x86-arkitekturen, kan instruksjonen om å flytte 5til registeret uttrykkes ALsom følger: MOV AL, 5, mens for en annen assembler for samme arkitektur vil den bli uttrykt omvendt: MOV 5, AL. Begge assembly-språkene ville gjøre nøyaktig det samme, bare uttrykt annerledes. Førstnevnte bruker Intel -syntaksen , mens sistnevnte bruker AT&T -syntaks .

Bruken av assembler løser ikke definitivt problemet med hvordan man programmerer et mikroprosessorbasert system på en enkel måte, siden man for å gjøre effektiv bruk av det må kjenne mikroprosessoren grundig , arbeidsregistrene som er tilgjengelige for den, strukturen til minnet, og mange flere ting knyttet til dets grunnleggende driftsstruktur.

Eksempler

Et program skrevet i assemblerspråk består av en serie instruksjoner som tilsvarer strømmen av ordrer som kan utføres av en mikroprosessor.

For eksempel, i assemblerspråk for en x86 -prosessor :

Setning

Tildeler den heksadesimale 61 verdien (97 desimaler ) til " AL"-registeret.

Monteringsprogrammet leser setningen ovenfor og produserer sin binære ekvivalent i maskinspråk .

Mnemonikken MOVer en operasjonskode eller " opcode ". Op -koden følges av en liste over argumenter eller parametere , og fullfører en typisk assembler-instruksjon. I eksemplet er ALdet et 8-bits prosessorregister, som vil bli tildelt den angitte heksadesimale verdien 61.

Maskinkoden generert av assembleren består av 2 byte. Den første byten inneholder den pakkede MOV-instruksjonen og registerkoden der dataene skal flyttes til:

1011 0000 01100001 | | | | | +---- Tall 61h i binær | | | +--- Registrer AL +-------- MOV instruksjon

I den andre byten er tallet 61h spesifisert, skrevet i binært som 01100001, som vil bli tildelt registeret AL, og etterlater den kjørbare setningen som:

Som kan forstås og utføres direkte av prosessoren.

Språkdesign

Grunnleggende elementer

Det er en stor grad av mangfold i måten assembler-forfattere kategoriserer utsagn på og i nomenklaturen de bruker. Spesielt beskriver noen alt som en pseudooperasjon (pseudo-Op), med unntak av den maskinelle mnemonicen eller den utvidede mnemonicen.

Et typisk assemblerspråk består av 3 typer instruksjonssetninger som brukes til å definere operasjonene til programmet:

Opcode mnemonics og utvidet mnemonics

I motsetning til instruksjonene (utsagnene) for språk på høyt nivå , er instruksjonene på assembler-språk generelt veldig enkle. Generelt er en mnemonic et symbolsk navn for en enkelt kjørbar maskinspråkinstruksjon (en opcode ), og det er minst én opcode-mnemonic definert for hver maskinspråkinstruksjon. Hver instruksjon består vanligvis av en operasjon eller opkode pluss null eller flere operander . De fleste instruksjoner refererer til en enkelt verdi, eller et par verdier. Operandene kan være umiddelbare (typisk én-byte-verdier, kodet i selve instruksjonen), registre spesifisert i instruksjonen, implisitte eller adressene til data som ligger andre steder i minnet. Dette bestemmes av den underliggende arkitekturen til prosessoren, assembleren gjenspeiler ganske enkelt hvordan denne arkitekturen fungerer. Utvidet mnemonikk brukes ofte til å spesifisere en kombinasjon av en op-kode med en spesifikk operand, for eksempel bruker System/360-montøren a Bsom en utvidet mnemonikk for el BCmed en maske på 15 og NOPal BCmed en maske på 0.

Utvidet mnemonikk brukes ofte for å støtte spesialisert bruk av instruksjoner, ofte for formål som ikke er tydelige fra navnet på instruksjonen. For eksempel har mange CPUer ikke en eksplisitt NOP(No Operation) instruksjon, men de har instruksjoner som kan brukes til det formålet. På 8086 CPU brukes instruksjonen XCHG AX,AX(bytter AX-registeret med seg selv) for NOP, med NOPå være en pseudo-op-kode for å kode instruksjonen XCHG AX,AX. Noen demontører gjenkjenner dette og vil dekode instruksjonen XCHG AX,AXsom NOP. På samme måte bruker IBM-montører for System/360 den utvidede mnemonics NOPy NOPRmed null masker for BCog BCR.

Noen montører støtter også enkle innebygde makroinstruksjoner som genererer to eller flere maskininstruksjoner. For eksempel, med noen montører for Z80 , instruksjonen

LD HL, BC

generere instruksjonene

LD L, C LD H, B. [ 4 ]

LD HL, BCer en pseudo-op-kode , som i dette tilfellet simulerer å være en 16-bits instruksjon. Når den utvides, produseres to 8-biters instruksjoner som tilsvarer den simulerte 16-biters.

Dataseksjoner

Det er instruksjoner som brukes til å definere dataelementer for å håndtere data og variabler. De definerer datatypen, lengden og justeringen av dataene. Disse instruksjonene kan også definere om dataene er tilgjengelige for eksterne programmer (separat sammensatte programmer) eller kun for programmet der datadelen er definert. Noen montører klassifiserer disse instruksjonene som pseudo-instruksjoner.

Assembler-direktiver

Assembler-direktiver, også kalt pseudo-op-koder, pseudo-operasjoner eller pseudo-ops, er instruksjoner som utføres av en assembler på monteringstidspunktet, ikke av CPU-en ved kjøretid . De kan gjøre sammenstillingen av programmet avhengig av parametere spesifisert av programmereren, slik at et program kan settes sammen på forskjellige måter, kanskje for forskjellige applikasjoner. De kan også brukes til å manipulere visningen av et program for å gjøre det enklere å lese og vedlikeholde.

For eksempel kan direktiver brukes til å reservere lagringsområder og eventuelt tildele deres opprinnelige innhold. Direktivnavn begynner ofte med et punktum for å skille dem fra maskininstruksjoner.

Symboliske samlere lar programmerere assosiere vilkårlige navn (etiketter eller symboler) med minneplasseringer. Vanligvis har hver konstant og variabel et navn slik at instruksjoner kan referere til disse stedene ved navn, og dermed fremme selvdokumenterende kode. I kjørbar kode er navnet på hvert underprogram knyttet til inngangspunktet, så ethvert kall til et underprogram kan bruke navnet. Innenfor underprogrammer er GOTO- destinasjoner gitt etiketter. Noen samlere støtter lokale symboler som er leksikalsk forskjellige fra vanlige symboler (f.eks. bruken av "10$" som GOTO-destinasjon).

De fleste montører gir fleksibel symbolhåndtering, slik at programmerere kan håndtere ulike navneområder , automatisk beregne forskyvninger i datastrukturer og tilordne etiketter som refererer til bokstavelige verdier eller resultatet av enkle beregninger utført av samleren. Etiketter kan også brukes til å initialisere konstanter og variabler med flyttbare adresser.

Assembly-språk, som de fleste andre dataspråk, lar kommentarer legges til kildekoden , som ignoreres av monteringsprogrammet. God bruk av kommentarer er enda viktigere med monteringskode enn med språk på høyt nivå, siden meningen og hensikten med en instruksjonssekvens kan være vanskeligere å forstå ut fra selve koden.

Fornuftig bruk av disse fasilitetene kan betydelig forenkle problemene med koding og vedlikehold av lavnivåkode. Rå assembly-språkkildekode generert av kompilatorer eller disassemblere - kode uten noen kommentarer, meningsfulle symboler eller datadefinisjoner - er svært vanskelig å lese når endringer må gjøres.

Makro

Mange samlere støtter forhåndsdefinerte makroer, og andre støtter makroer definert (og gjentatte ganger omdefinert) av programmereren som involverer sekvenser av tekstlinjer, der variabler og konstanter er innebygd. Denne sekvensen av tekstlinjer kan inkludere opkoder eller direktiver. Når en makro er definert, kan navnet brukes i stedet for en mnemonikk. Når assembleren behandler en slik setning, erstatter den setningen med tekstlinjene som er knyttet til den makroen. Den behandler dem deretter som om de hadde eksistert i den originale kildekodefilen (inkludert, i noen assemblers, utvidelse av makroer som finnes i erstatningsteksten).

Siden makroer kan ha korte navn, men spenner over flere, eller faktisk mange, kodelinjer, kan de brukes til å få assembly-språkprogrammer til å virke mye kortere, og krever færre linjer med kildekode, slik tilfellet er med språk på høyt nivå. De kan også brukes til å legge til høyere nivåer av struktur til monteringsprogrammer; de introduserer eventuelt innebygd feilsøkingskode via parametere og andre lignende funksjoner.

Mange samlere har innebygde (eller forhåndsdefinerte) makroer for systemanrop og andre spesielle kodesekvenser, som datagenerering og lagring utført gjennom avanserte bitvise operasjoner og boolske operasjoner brukt i spill, sikkerhetsprogramvare, administrasjonsdata og kryptografi.

Makromontører lar ofte makroer ta parametere . Noen samlere inkluderer sofistikerte makrospråk, som inkluderer språkelementer på høyt nivå som valgfrie parametere, symbolske variabler, betingelser, strengmanipulasjoner , aritmetiske operasjoner, alt som kan brukes under utførelse av en gitt makro, og lar makroer lagre konteksten eller utveksle informasjon. Dermed kan en makro generere et stort antall assembly-språkinstruksjoner eller datadefinisjoner, basert på makroens argumenter. Dette kan brukes til å generere for eksempel datastrukturer i rekordstil eller "utrullede" løkker, eller det kan generere hele algoritmer basert på komplekse parametere. En organisasjon som bruker assemblerspråk, som har blitt kraftig utvidet ved å bruke en slik pakke med makroer, kan betraktes som å jobbe i et språk på høyt nivå, siden slike programmerere ikke jobber med de konseptuelle elementene på lavere nivå på datamaskinen.

Makroer ble brukt til å tilpasse storskala programvaresystemer for spesifikke kunder i stormaskintiden . Makroer ble også brukt av brukerne selv for å møte behovene til organisasjonene deres ved å lage spesifikke versjoner av produsentens operativsystemer. Dette ble for eksempel gjort av systemprogrammerere som jobbet med IBMs Conversational Monitor System/Virtual Machine (CMS/VM) og IBMs sanntidstransaksjonsbehandlings -plugins , CICS , Customer Information Control System , flyselskapet/finanssystemet som startet på 1970-tallet og kjører fortsatt med mange datareservasjonssystemer (CRS) og kredittkortsystemer i dag.

Det er også mulig å bruke bare makrobehandlingsevnene til en assembler for å generere kode skrevet på helt andre språk. For eksempel for å generere en COBOL -versjon av et program ved å bruke et rent assembler-makroprogram som inneholder linjer med COBOL-kode inne i monteringstidsoperatører som instruerer assembleren om å generere vilkårlig kode.

Dette var fordi, som 1970-tallet bemerket, begrepet "makrobehandling" er uavhengig av begrepet "montering", det førstnevnte er, i moderne termer, mer av tekstbehandling enn objektkodegenerering. Konseptet med makrobehandling dukket opp, og dukker opp, i programmeringsspråket C, som støtter "forbehandlerinstruksjoner" for å sette variabler, og utfører betinget testing på verdiene deres. Legg merke til at i motsetning til visse tidligere makroprosessorer innen montører, var ikke C-forprosessoren Turing-komplett fordi den manglet loop eller gå til kapasitet , sistnevnte tillot programmer å loope.

Til tross for kraften til makrobehandling, falt den ut av bruk på mange høynivåspråk (et viktig unntak er C/C++), men det vedvarte i assemblers. Dette var fordi mange programmerere var ganske forvirret av makroparametersubstitusjon og ikke skilte forskjellen mellom makrobehandling, montering og utførelse.

Makroparametererstatning er strengt tatt etter navn: ved makrobehandlingstid erstattes verdien av en parameter ordrett med navnet. Den mest kjente typen resulterende feil var bruken av en parameter som i seg selv var et uttrykk og ikke et primærnavn når makroforfatteren forventet et navn. I makroen:

foo: makro til last a*b

hensikten var at den kallende rutinen skulle oppgi navnet på en variabel, og den "globale b"-variabelen eller konstanten ville bli brukt til å multiplisere "a". Hvis foo kalles med parameteren a-c, skjer makroutvidelse load a-c*b. For å unngå mulig tvetydighet kan brukere av makroprosessorer legge inn formelle parametere innenfor makrodefinisjoner i parentes, eller anropsrutiner kan omslutte inndataparametere i parentes. [ 5 ]​ Den korrekte makroen, med parentesene, ville altså være:

foo: makro til belastning (a)*b

og utvidelsen av den, ville resultere i:load (a-c)*b

PL /I og C/C++ tilbyr makroer, men denne funksjonen kan bare manipulere tekst. På den annen side beholder homoikoniske språk , som Lisp , Prolog og Forth , kraften til assembly-språkmakroer fordi de kan manipulere sin egen kode som data.

Støtte for strukturert programmering

Noen montører har innlemmet elementer av strukturert programmering for å kode utførelsesflyten. Det tidligste eksemplet på denne tilnærmingen var i Concept-14 makrosettet, opprinnelig foreslått av Dr. HD Mills (mars 1970), og implementert av Marvin Kessler ved IBMs Federal Systems Division , som utvidet S /360 med IF/ELSE/ENDIF strømningskontrollblokker og lignende. [ 6 ] Dette var en måte å redusere eller eliminere bruken av GOTO-operasjoner i assembly-språkkode, en av hovedfaktorene som forårsaker spaghetti-kode i assembly-språk. Denne tilnærmingen ble allment akseptert på begynnelsen av 1980-tallet (de siste dagene med storskala bruk av forsamlingsspråk).

Et merkelig design var A-natural, en "strømorientert" assembler for 8080 / Z80-prosessorene [ referanse nødvendig ] fra Whitesmiths Ltd. (utviklere av det Unix - lignende Idris-operativsystemet ), og det som ble rapportert som den første kommersielle C-en. kompilator). Språket ble klassifisert som en assembler, fordi det fungerte med rå maskinelementer som opkoder, registre og minnereferanser; men den inkorporerte en uttrykkssyntaks for å angi rekkefølgen for utførelse. Parenteser og andre spesielle symboler, sammen med blokkorienterte strukturerte programmeringskonstruksjoner, kontrollerte sekvensen av genererte instruksjoner. A-natural ble bygget som objektspråket til en C-kompilator, snarere enn håndkoding, men dens logiske syntaks fikk noen tilhengere.

Det har vært liten tilsynelatende etterspørsel etter mer sofistikerte montører på grunn av nedgangen i storskala utvikling av forsamlingsspråk. [ 7 ] Til tross for dette, utvikles og brukes de fortsatt i tilfeller der ressursbegrensninger eller særtrekk i målsystemarkitekturen hindrer effektiv bruk av høynivåspråk. [ 8 ]

Bruk av assemblerspråk

Historisk perspektiv

Forsamlingsspråk ble først utviklet på 1950-tallet, da de ble referert til som andre generasjons programmeringsspråk. For eksempel var SOAP (Symbolic Optimal Assembly Program) et monteringsspråk fra 1957 for IBM 650 -datamaskinen . Monteringsspråk eliminerte mye av den feilutsatte og tidkrevende programmeringen av førstegenerasjonsspråk, som var nødvendig med tidlige datamaskiner, og frigjorde programmerere fra kjedelighet som å huske numeriske koder og beregne adresser. De ble en gang mye brukt til all slags programmering. På 1980-tallet (1990-tallet på mikrodatamaskiner ) hadde imidlertid bruken i stor grad blitt erstattet av språk på høyt nivå , [ referanse nødvendig ] i søken etter forbedret programmeringsproduktivitet. I dag, selv om assembly-språk nesten alltid håndteres og genereres av kompilatorer , brukes det fortsatt til direkte maskinvaremanipulering, tilgang til spesialiserte prosessorinstruksjoner eller for å løse kritiske ytelsesproblemer. Typiske bruksområder er enhetsdrivere , innebygde systemer på lavt nivå og sanntidssystemer .

Historisk sett har et stort antall programmer blitt skrevet utelukkende på assemblerspråk. Operativsystemer ble nesten utelukkende skrevet i assemblerspråk frem til den utbredte aksepten av programmeringsspråket C på 1970- og begynnelsen av 1980-tallet. Dessuten ble mange kommersielle applikasjoner skrevet på assemblerspråk, inkludert mye av programvaren skrevet av store selskaper for IBM-stormaskiner. COBOL- og FORTRAN -språkene fortrengte etter hvert mye av dette arbeidet, selv om en rekke store organisasjoner beholdt applikasjonsrammeverket for monteringsspråk langt inn på 1990-tallet.

De fleste tidlige mikrodatamaskiner stolte på håndkodet monteringsspråk, inkludert de fleste operativsystemer og store applikasjoner. Dette var fordi disse systemene hadde alvorlige ressursbegrensninger, påførte idiosynkratisk minne og skjermarkitekturer, og ga begrensede og buggy systemtjenester. Kanskje viktigere var mangelen på førsteklasses kompilatorer av høynivåspråk egnet for bruk på mikrodatamaskinen. En psykologisk faktor kan også ha spilt en rolle: den første generasjonen av mikrodatamaskinprogrammerere beholdt en "tråd og tang" hobbyholdning.

I en mer kommersiell sammenheng var de største grunnene til å bruke assemblerspråk å lage programmer med minimum størrelse, minimum overhead og større hastighet og pålitelighet.

Typiske eksempler på datidens store assembly-språkprogrammer er IBM PC DOS- operativsystemer og tidlige applikasjoner som Lotus 1-2-3 - regnearket , og nesten alle de populære spillene for Atari 800 -familien av personlige datamaskiner. Selv på 1990-tallet ble de fleste konsollvideospill skrevet i assembler, inkludert de fleste spill for Mega Drive/Genesis og Super Nintendo Entertainment System . I følge noen bransjeinnsidere var assemblerspråk det beste programmeringsspråket å bruke for å få mest mulig ut av Sega Saturn , en konsoll som det var notorisk utfordrende å utvikle og programmere spill for. [ 9 ] Det populære arkadespillet NBA Jam (1993) er et annet eksempel. Assembler har lenge vært det primære utviklingsspråket på Commodore 64 , Atari ST , samt ZX Spectrum . Dette var i stor grad slik fordi BASIC -dialektene på disse systemene tilbød utilstrekkelig utførelseshastighet, samt utilstrekkelige funksjoner til å dra full nytte av den tilgjengelige maskinvaren. Noen systemer, spesielt Amiga, har til og med IDE-er med svært avanserte makroer og feilsøkingsfunksjoner, for eksempel freeware ASM-One assembler , som kan sammenlignes med Microsoft Visual Studio (ASM-One går foran Microsoft Visual Studio).

Monteringsmaskinen for VIC-20 ble skrevet av Don French og utgitt av French Silk. Med en lengde på 1639 byte, mener forfatteren at det er den minste symbolske samleren som noen gang er skrevet. Samleren støttet den vanlige symbolske adresseringen og definisjonen av tegnstrenger eller heksadesimale strenger. Det tillot også adresseuttrykk som kunne kombineres med operasjonene addisjon , subtraksjon , multiplikasjon , divisjon , logisk OG , logisk ELLER og eksponentiering . [ 10 ]

Nåværende bruk

Det har alltid vært debatter om nytten og ytelsen til forsamlingsspråk i forhold til språk på høyt nivå. Forsamlingsspråk har spesifikke nisjer der det betyr noe (se nedenfor). Men generelt kan moderne optimeringskompilatorer for å oversette høynivåspråk til kode kjøre like raskt som håndskrevne assembly-språk, til tross for moteksempler som kan finnes. [ 11 ]​ [ 12 ]​ [ 13 ]​ Kompleksiteten til moderne prosessorer og minnedelsystemet gjør effektiv optimalisering stadig vanskeligere for kompilatorer, så vel som for assembler-programmerere. [ 14 ] ​[ 15 ]​ I tillegg, og til forferdelse for elskere av effektivitet, har stadig økende prosessorytelse ført til at de fleste CPU - er er inaktive mesteparten av tiden, med forsinkelser forårsaket av forutsigbare flaskehalser. som input/output- operasjoner og minne personsøking . Dette har gjort utførelseshastigheten for råkode mindre av et problem for mange programmerere.

Det er noen situasjoner der fagfolk kan velge å bruke assemblerspråk. For eksempel når:

  • Det kreves en frittstående binær kjørbar, dvs. en som må kjøres uten ressurser til kjøretidskomponenter eller biblioteker knyttet til et høynivåspråk; dette er kanskje den vanligste situasjonen. De er innebygde programmer som bare lagrer en liten mengde minne, og enheten er ment å utføre oppgaver for et enkelt formål. Eksempler inkluderer telefoner, drivstoff- og tenningssystemer for biler, kontrollsystemer for klimaanlegg, sikkerhetssystemer og sensorer.
  • Samhandle direkte med maskinvare, for eksempel i enhetsdrivere og avbruddsbehandlere.
  • Bruk av prosessorspesifikke instruksjoner som ikke utnyttes eller er tilgjengelige av kompilatoren. Et vanlig eksempel er den bitvise rotasjonsinstruksjonen i kjernen av mange krypteringsalgoritmer.
  • Opprette vektoriserte funksjoner for programmer på høynivåspråk som C. I høynivåspråket blir dette noen ganger hjulpet av kompilatorinnhold som kartlegger direkte til SIMD mnemonics, men resulterer likevel i en en-til-en monteringskonvertering. en tilknyttet vektorprosessor.
  • Ekstrem optimalisering er nødvendig, for eksempel i en indre sløyfe i en prosessorintensiv algoritme. Spillutviklere drar fordel av egenskapene til maskinvarefunksjoner i systemer, slik at spill kan kjøres raskere. Også store vitenskapelige simuleringer krever svært optimaliserte algoritmer, f.eks. lineær algebra med BLAS eller den diskrete cosinustransformasjonen (f.eks. assembler SIMD -versjonen av x264 , [ 16 ] (et bibliotek for koding av videostrømmer).
  • Et system med alvorlige ressursbegrensninger (f.eks. et innebygd system ) må håndkodes for å maksimere bruken av begrensede ressurser; men dette blir mindre vanlig ettersom prosessorprisen synker og ytelsen forbedres.
  • Det er ikke noe språk på høyt nivå, i en ny eller spesialisert prosessor.
  • Skrive sanntidsprogrammer som trenger timing og presise svar, for eksempel flynavigasjonssystemer og medisinsk utstyr. For eksempel, i et fly-by-wire- system, må telemetri tolkes og tiltak må iverksettes innenfor strenge tidsbegrensninger. Slike systemer må eliminere kilder til uforutsigbare forsinkelser, som kan skapes av (noen) tolkede språk, automatisk søppelinnsamling , personsøkingsoperasjoner eller forebyggende multitasking . Noen høynivåspråk inneholder imidlertid kjøretidskomponenter og operativsystemgrensesnitt som kan introdusere slike forsinkelser. Å velge assembly- eller lavnivåspråk for slike systemer gir programmerere større synlighet og kontroll over detaljene i behandlingen.
  • Total kontroll over miljøet kreves, i ekstremt høye sikkerhetssituasjoner der ingenting kan tas for gitt.
  • Datavirus , oppstartslastere , visse enhetsdrivere/drivere eller andre elementer er skrevet i umiddelbar nærhet av maskinvaren eller operativsystemet på lavt nivå.
  • Instruksjonssettsimulatorer er skrevet for overvåking, sporing og feilsøking der ekstra overhead holdes på et minimum.
  • Eksisterende binærfiler som kanskje eller kanskje ikke opprinnelig er skrevet på et høynivåspråk, blir omvendt , for eksempel ved å knekke kopibeskyttelsen til proprietær programvare.
  • Omvendt utvikling og modifikasjon av videospill (også kalt ROM-hacking ), som er mulig gjennom ulike metoder. Den mest implementerte er ved å endre programkoden på assembly-språknivå.
  • Du skriver selvmodifiserende (også kjent som polymorf) kode, noe assembly-språk egner seg godt til.
  • Spill og annen programvare er skrevet for grafiske kalkulatorer . [ 17 ]
  • Kompilatorprogramvare er skrevet som genererer assembly-kode, og derfor må utviklere være assembler-språkprogrammerere.
  • Kryptografiske algoritmer er skrevet som alltid må ta strengt tatt samme tid å utføre, og forhindre timing av angrep.

Imidlertid undervises det fortsatt i monteringsspråk i de fleste informatikk- og elektroniske ingeniørprogrammer . Selv om få programmerere i dag jevnlig jobber med assemblerspråk som verktøy, er de grunnleggende konseptene fortsatt svært viktige. Slike grunnleggende emner som binær aritmetikk , minneallokering , stabelbehandling, tegnsettkoding, avbruddsbehandling og kompilatordesign ville være vanskelig å studere i detalj uten en forståelse av hvordan datamaskinen fungerer på maskinvarenivå. Siden oppførselen til datamaskinen er grunnleggende definert av instruksjonssettet , er den logiske måten å lære slike konsepter på å studere et assemblerspråk. De fleste moderne datamaskiner har et lignende sett med instruksjoner. Derfor er det nok å studere et enkelt samlespråk for å lære: i) de grunnleggende konseptene; ii) gjenkjenne situasjoner der bruk av assemblerspråk kan være hensiktsmessig; og iii) se hvordan effektiv kjørbar kode kan lages av høynivåspråk [ 18 ]

Typiske applikasjoner

Hardkodet assemblyspråk brukes vanligvis i systemets oppstarts-ROM ( BIOS på IBM PC-kompatible systemer ). Denne lavnivåkoden brukes blant annet til å initialisere og teste systemmaskinvaren før du laster operativsystemet , og lagres i ROM . Når et visst nivå av maskinvareinitialisering har funnet sted, overføres kjøringen til annen kode, vanligvis skrevet på høynivåspråk; men koden som kjører umiddelbart etter at strømmen er satt på, er vanligvis skrevet på assemblerspråk. Det samme gjelder for oppstartslastere .

Mange kompilatorer oversetter høynivåspråk til assemblerspråk først, før full kompilering, slik at assemblykoden kan sees for feilsøking og optimaliseringsformål. Relativt lavnivåspråk, som C , gir ofte spesiell syntaks for å bygge inn monteringsspråk på hver maskinvareplattform. Systemets bærbare kode kan deretter bruke disse prosessorspesifikke komponentene gjennom et enhetlig grensesnitt.

Monteringsspråk er også verdifullt i reverse engineering , siden mange programmer bare distribueres i maskinkodeform. Maskinkode er vanligvis lett å oversette til assemblerspråk og deretter nøye undersøkt på denne måten, men det er svært vanskelig å oversette til et språk på høyt nivå. Verktøy som Interactive Disassembler bruker utstrakt bruk av disassembleren til slike formål.

En nisje som bruker assemblerspråk er demoscenen . Enkelte konkurranser krever at deltakerne begrenser sine kreasjoner til en svært liten størrelse (f.eks. 256 byte , 1 KB , 4 KB eller 64 KB), og assembly-språket er det foretrukne språket for å oppnå dette målet. [ 19 ] Når ressurser er et problem, er monteringskoding en nødvendighet, spesielt på systemer begrenset av CPU-behandling, for eksempel tidlige modeller av Amiga og Commodore 64 . Optimalisert monteringskode skrives "for hånd" av programmerere i et forsøk på å minimere antall CPU-sykluser som brukes. CPU-begrensninger er så store at hver syklus teller. Bruk av slike metoder har gjort det mulig for systemer som Commodore 64 å produsere sanntids 3D-grafikk med avanserte effekter, en prestasjon som kan anses som usannsynlig eller til og med umulig for et system med en 0,99 MHz prosessor . [ referanse nødvendig ]

Ytterligere detaljer

For enhver gitt personlig datamaskin, stormaskin, innebygd system og spillkonsoll, både tidligere og nåtid, er det skrevet minst én, og muligens dusinvis av montører. For noen eksempler, se listen over montører .

Unix -systemer kalles assembleren tradisjonelt som , selv om det ikke er en enkel kode, vanligvis skrives en ny for hver port. En rekke Unix-varianter bruker GAS

Innenfor prosessorgruppene har hver assembler sin egen dialekt. Noen ganger kan noen samlere lese en annens dialekt, for eksempel kan TASM lese gammel kode fra MASM , men ikke omvendt. FASM og NASM har lignende syntaks, men hver støtter forskjellige makroer som kan være vanskelige å portere fra den ene til den andre. De grunnleggende tingene er alltid de samme, men de avanserte funksjonene vil være forskjellige [ 20 ]

Dessuten kan monteringsspråk noen ganger være bærbare på tvers av forskjellige operativsystemer på samme type CPU . Ringekonvensjoner mellom operativsystemer varierer ofte litt eller ikke i det hele tatt. og med forsiktighet er det mulig å få portabilitet i assemblerspråk, vanligvis ved å koble til et C-språkbibliotek som ikke endres mellom operativsystemer. En instruksjonssettsimulator (som ideelt sett ville vært skrevet i assemblerspråk) kan i teorien behandle binær- / objektkoden til en hvilken som helst assembler) for å oppnå portabilitet selv på tvers av plattformer (med ikke mer overhead enn en tolk). av typisk bytekode ). Dette er i hovedsak hva mikrokode oppnår når en maskinvareplattform endres internt.

For eksempel avhenger mange ting i libc av at forprosessoren gjør ting med programmet før kompilering som er OS-spesifikke eller C-spesifikke. Faktisk er noen funksjoner og symboler ikke engang garantert å eksistere utenfor forprosessoren. Enda verre er størrelsen og rekkefølgen på feltene med strukturer, så vel som størrelsen på visse typedefs som off_t , ikke tilgjengelig i assemblerspråk uten hjelp av et konfigureringsskript, og varierer selv mellom Linux- versjoner , noe som gjør det umulig å portere funksjonskall i libc andre enn de som tar enkle heltall eller pekere som parametere. For å håndtere disse problemene tilbyr FASMLIB-prosjektet et bærbart assembly-språkbibliotek for Win32- og Linux-plattformene, men det er fortsatt svært ufullstendig. [ 21 ]

Noen språk på svært høyt nivå, som C og Borland/Pascal, støtter inline-montering, der relativt korte deler av monteringskoden kan bygges inn i språkkoden på høyt nivå. Forth - språket inneholder vanligvis en assembler som brukes til å kode ord.

De fleste bruker en emulator for å feilsøke assemblerspråkprogrammene sine.

Eksempler på forsamlingsspråk

Eksempel for x86-arkitekturen

Følgende er et eksempel på det klassiske Hello World- programmet skrevet for x86 -prosessorarkitekturen (under DOS- operativsystemet ).

; ---------------------------------------------------- ; Program som skriver ut en streng på skjermen ; ---------------------------------------------- .modell liten ; minnemodell .stack ; stabelsegment .data ; datasegment String1 DB ' Hello World. ; streng som skal skrives ut (avsluttes i $) .kode ; kodesegment ; ---------------------------------------------------- ; Start av programmet ; ---------------------------------------------- program: ; -------------------------------------------------- -------------------------------------------------- ; start datasegment ; -------------------------------------------------- -------------------------------------------------- MOV AXE , @ data ; laster inn i AX adressen til MOV DS datasegmentet , AX ; flytte adresse til segmentregister via AX ; -------------------------------------------------- -------------------------------------------------- ; Skriv ut en streng på skjermen ; -------------------------------------------------- -------------------------------------------------- MOV DX , offset String1 ; flytt til DX adressen til strengen for å skrive ut MOV AH , 9 ; AH = kode for å fortelle MS DOS å skrive ut strengen i DS:DX INT 21 h på skjermen ; kall til MS DOS for å utføre funksjonen (i dette tilfellet spesifisert i AH) ; -------------------------------------------------- -------------------------------------------------- ; Avslutt programmet ; -------------------------------------------------- -------------------------------------------------- INT 20:00 ; _ ring til MS DOS for å avslutte programmet avslutte programmet

Eksempel for den virtuelle datamaskinen (POCA)

Et utvalg instruksjoner for en virtuell datamaskin [ 22 ] ) med tilhørende minneadresser der instruksjonene vil være plassert. Disse adressene er IKKE statiske. Hver instruksjon er ledsaget av generert assembly-språkkode (objektkode) som samsvarer med den virtuelle datamaskinarkitekturen, eller ISA -instruksjonssettet .

Dir. Merkelapp Instruksjon Maskinkode [ 23 ]
.begynne
.org 2048
a_start .equ 3000
2048 ld [lengde], %r1
2064 bli ferdig 00000010 10000000 00000000 00000110
2068 addcc %r1,-4,%r1 10000010 10000000 01111111 11111100
2072 addcc %r1,%r2,%r4 10001000 10000000 01000000 00000010
2076 ld %r4,%r5 11001010 00000001 00000000 00000000
2080 ba løkke 00010000 10111111 11111111 11111011
2084 addcc %r3,%r5,%r3 10000110 10000000 11000000 00000101
2088 donere: jmpl %r15+4,%r0 10000001 11000011 11100000 00000100
2092 lengde: tjue 00000000 00000000 00000000 00010100
2096 adresse: a_start 00000000 00000000 00001011 10111000
.org a_start
3000 en:

Eksempel for den virtuelle datamaskinen (ARC)

ARC er en undergruppe av den SPARC-prosessorbaserte arkitekturmodellen. ARC (A RISC Computer) inneholder de fleste funksjonene

viktige deler av SPARC-arkitekturen.

Adresse Merkelapp Instruksjon Kommentarer
.begynne
.org 2048
a_start: .equ 3000 ! Array-minneadressen starter på 3000
2048 ld [lengde], %r1 ! Angi lengden på matrisen i posten
2052 ld [adresse], %r2 ! Fiks adresse til
2056 anddcc %r3, %r0, %r3 ! Delsummen settes til null.
2060 Løkke: anddcc %r1, %r1, %r0 ! Jeg sjekker om r1 har gjenværende elementer
2064 bli ferdig
2068 addcc %r1, -4, %r1 ! Reduser størrelsen på matrisen
2072 ld %r1 + %r2, %r4 !Last inn neste element i r4
2076 addcc %r3, %r4, %r3 ! Jeg oppdaterer delsummen i r3
2080 ba løkke ! Kontroller skjæretilstanden på nytt
2084 donere: jmpl %r15 + 4, %r0 ! Gå tilbake til hovedrutinen
2088 lengde: tjue ! Matrisestørrelse i 20 byte, 5 tall
2092 adresse: a_start
.org a_start ! oppstart av arrangement til
en: 25
femten
-tjue
-35
femten
.slutt ! slutten av programmet


Eksempel for Intel 8051 µC

Monteringsspråkkode for µC Intel 80C51 :

ORG 8030 H inkluderer T05SEG: SETB TR0 JNB uSEG , T05SEG ;denne subrutinen brukes CLR TR0 ;for å telle CPL uSEG ; 0,5 sekunder via MOV R1 , DPL ;avbruddstidtaker 0. INVOKE MOV R2 , DPH CJNE R2 , TPH CJNE R2 CJNE R1 , #78 H , T05SEG MOV DPTR , #0 RET

Eksempel for Microchip PIC16F84

Monteringsspråkkode for Microchips 16F84 mikrokontroller :

ORG 0 Start bcf STATUS , RP0 clrf PORTB movlw 0xFF movwf PORTA bsf STATUS , RP0 Main movf PORTA , W movwf Counter movf Counter , F btfsc STATUS , Z goto Desimalpunkt ' lw d ' s 9 STATUS _ _ _

Se også

montører

Demontører

skrubbere

Andre

Operativsystemer skrevet helt i assembler :

Referanser

  1. "DSP: C versus Assembly" , Steven W. Smith, Ph.D. , 2011
  2. David Solomon (1993). Montører og lastere
  3. ^ Beck, Leland L. (1996). "to". Systemprogramvare: En introduksjon til systemprogrammering . Addison Wesley. 
  4. http://www.z80.de/z80/z80code.htm
  5. "Makroer (C/C++), MSDN Library for Visual Studio 2008" . Microsoft Corp. Hentet 22. juni 2010 . 
  6. ^ "Konsept 14 makroer" . MVSSprogramvare . Hentet 25. mai 2009 . 
  7. Answers.com. "monteringsspråk: definisjon og mye mer fra Answers.com" . Hentet 19. juni 2008 . 
  8. NESHLA: The High Level, Open Source, 6502 Assembler for Nintendo Entertainment System
  9. "Eidolon's Inn: SegaBase Saturn" . Arkivert fra originalen 13. juli 2008 . Hentet 25. juli 2008 . 
  10. Jim Lawless (21. mai 2004). "Snakker med Don French: Mannen bak de franske silkemonteringsverktøyene" . Arkivert fra originalen 21. august 2008 . Hentet 25. juli 2008 . 
  11. ^ "Skrive den raskeste koden, for hånd, for moro skyld: En menneskelig datamaskin fortsetter å øke hastigheten på brikker" . New York Times, John Markoff. 28. november 2005 . Hentet 4. mars 2010 . 
  12. ^ "Bit-field-badness" . hardwarebug.org. 30. januar 2010. Arkivert fra originalen 5. februar 2010 . Hentet 4. mars 2010 . 
  13. ^ "GCC lager et rot" . hardwarebug.org. 13. mai 2009. Arkivert fra originalen 16. mars 2010 . Hentet 4. mars 2010 . 
  14. Randall Hyde. "Den store debatten" . Arkivert fra originalen 16. juni 2008 . Hentet 3. juli 2008 . 
  15. "Kodekilde mislykkes igjen" . hardwarebug.org. 30. januar 2010. Arkivert fra originalen 2. april 2010 . Hentet 4. mars 2010 . 
  16. ^ "x264.git/common/x86/dct-32.asm" . git.videolan.org. 29. september 2010. Arkivert fra originalen 4. mars 2012 . Hentet 29. september 2010 . 
  17. ^ "68K programmering i Fargo II" . Hentet 3. juli 2008 . 
  18. ^ Hyde, Randall (30. september 1996). "Forord ("Hvorfor skulle noen lære dette?"), op. cit. » . Arkivert fra originalen 2010-02-22 . Hentet 5. mars 2010 . 
  19. ^ "256bytes demoarkiver" . Hentet 3. juli 2008 . 
  20. Randall Hyde. "Hvilken montør er best?" . Arkivert fra originalen 18. oktober 2007 . Hentet 19. oktober 2007 . 
  21. " vine ". "FASMLIB: Funksjoner" . Hentet 19. oktober 2007 . 
  22. Principles of Computer Architecture (POCA) – ARCTools virtuell datamaskin tilgjengelig for nedlasting og kodekjøring, åpnet 24. august 2005
  23. Murdocca, Miles J. og Heuring, Vincent P.: Principles of Computer Architecture (2000), Prentice Hall, ISBN 0-201-43664-7

Bibliografi

  • Dominic Sweetman: Se MIPS Run . Morgan Kaufmann Publishers, 1999. ISBN 1-55860-410-3
  • Robert Britton: MIPS Assembly Language Programming . Prentice Hall, 2003. ISBN 0-13-142044-5
  • John Waldron: Introduksjon til RISC Assembly Language Programming . Addison Wesley, 1998. ISBN 0-201-39828-1
  • ASM Community Book "En nettbok full av nyttig ASM-informasjon, opplæringsprogrammer og kodeeksempler" av ASM Community
  • Jonathan Bartlett: Programmering fra bunnen av . Bartlett Publishing, 2004. ISBN 0-9752838-4-7
    Også tilgjengelig online som PDF Arkivert 6. februar 2009 på Wayback Machine .
  • Paul Carter: PC Assembly Language . Gratis ebok, 2001.
    Nettsted
  • Jeff Duntemann: Monteringsspråk trinn for trinn . Wiley, 2000. ISBN 0-471-37523-3
  • Randall Hyde: The Art of Assembly Language . No Starch Press, 2003. ISBN 1-886411-97-2 Utkastversjoner
    tilgjengelig online som PDF og HTML
  • Peter Norton, John Socha, Peter Nortons Assembly Language Book for IBM PC , Brady Books, NY: 1986.
  • Michael Singer, PDP-11. Assembler Language Programming and Machine Organization , John Wiley & Sons, NY: 1980.
  • Prinsipper for datamaskinarkitektur - Miles J. Murdocca - Vincent P. Heuring

Eksterne lenker