kokoonpanokieli | |
---|---|
Kieliluokka | välttämätöntä |
Toteutustyyppi | koottava |
Esiintyi | 1949 |
Tiedostotunniste _ | .asmtai [1].s |
Mediatiedostot Wikimedia Commonsissa |
Kokoonpanokieli ( englanniksi assembly language ) - prosessorin komentojen esitys ihmisen luettavassa muodossa. Assembly-kieltä pidetään matalan tason ohjelmointikielenä , toisin kuin korkean tason kieliä , jotka eivät ole sidottu tiettyyn tietokonejärjestelmän toteutukseen. Assembly-kielellä kirjoitetut ohjelmat muuntuvat yksiselitteisesti tietyn prosessorin käskyiksi, eikä niitä useimmissa tapauksissa voida siirtää ilman merkittäviä muutoksia toimimaan koneella, jossa on eri käskyt. Assembler on ohjelma, joka muuntaa kokoonpanokielen koodin konekoodiksi; ohjelmaa, joka suorittaa käänteisen tehtävän, kutsutaan disassembleriksi.
Ensimmäiset kokoonpanijat suunnitteli Kathleen Booth vuonna 1947 ARC2 [2] ja David Wheeler vuonna 1948 EDSAC [3] , kun taas termiä "assembler" ei käytetty, vaan kieltä kutsuttiin yksinkertaisesti "perusohjeiden joukoksi". " ( englanninkielinen perusjärjestyssarja ) ja "alkukomennot" ( englanninkieliset aloitusmääräykset ) vastaavasti. Myöhemmissä EDSAC-raporteissa alettiin käyttää ensimmäistä kertaa termiä "assembler" kenttien yhdistämisprosessista ohjaussanaksi.
Myös ohjelmoinnin kehityksen alkuvaiheessa otettiin käyttöön autokoodin käsite - ohjelmointikieli, jonka lauseet ovat rakenteeltaan periaatteessa samanlaisia kuin tietyn konekielen käskyt ja käsitellyt tiedot [4][ tosiasian merkitys? ] . Termiä ei tällä hetkellä varsinaisesti käytetä.
Historiallisesti, jos konekoodeja pidetään ohjelmointikielten ensimmäisen sukupolvena, niin kokoonpanokieltä voidaan pitää ohjelmointikielten toisen sukupolvena. . Assembly-kielen puutteet, esimerkiksi vaikeus kehittää siihen suuria ohjelmistojärjestelmiä, johtivat myöhemmin kolmannen sukupolven kielten - korkean tason ohjelmointikielten (kuten Fortran , Lisp , Cobol , Pascal ) syntymiseen. , C ja muut).
Yleisesti käytettyä kokoonpanokielen syntaksia ei ole. Koska eri prosessorien käskyjärjestelmät eroavat huomattavasti, myös näiden prosessorien kokoonpanokielet eroavat toisistaan. Lisäksi jokainen kokoonpanoohjelma voi käyttää erilaista syntaksia. X86-prosessorien kokoajissa käytetään laajimmin niin kutsuttua Intel-syntaksia ja vähemmässä määrin AT&T-syntaksia .
Assembly-kielen perusrakenne on muistomerkki eli muistokoodi - lyhyt symbolinen esitys prosessorin käskystä. Pääsääntöisesti se koostuu useista merkeistä, jotka osoittavat suoritettavan toimenpiteen (esimerkiksi movsiirtää rekisteristä toiseen, addlisätä arvoja jne.). Muistomerkki voi myös sisältää kohteen, jolle toiminto suoritetaan (rekisteri, muisti, pino) tai muita ominaisuuksia (vaikutus lippurekisteriin , suoritusehdot jne.), mutta muissa murteissa samat ominaisuudet voivat olla määritellään operandeissa.
Pääsääntöisesti kunkin prosessorin assemblerillä on oma perinteinen muistomerkkisarja, mutta on monialustaisia syntaksisia assemblereitä (kuten AT&T-syntaksia), mutta niissä säilyvät vain merkinnät, yhden prosessorin koodi. ei voi siirtää suoraan toiselle.
Rekisterit, vakioarvot, muistisolujen ja I/O-porttien osoitteet , vakiot, etiketit jne. voidaan määrittää operandeiksi. Eri kokoajat voivat vaatia erilaisen operandijärjestyksen: joissakin toteutuksissa operaattori, jossa arvo kirjoitetaan, on ensin, toisissa se tulee viimeiseksi. Operandit erotetaan käskymnemoniikasta pääsääntöisesti välilyönnillä.
Yleisin tietotyyppi , jonka kanssa useimmat prosessorit voivat työskennellä, on konesanaan pakattu kokonaisluku tai yksi tai useampi tavu , harvemmin liukuluku . Assembly-ohjelmissa käytetään paljon useammin eri numerojärjestelmissä annettuja arvoja. Ensinnäkin tietokoneissa, joissa on kahdeksan bitin tavu, käytetään usein heksadesimaalimerkintää , koska kaksi heksadesimaalilukua sijoitetaan yhteen tavuun. Jotkut arvot voidaan kirjoittaa binäärikoodeilla. Varhaisissa tietokoneissa, joissa oli kuusibittinen tavu, havaittiin myös oktaalilukujärjestelmä . Kirjoitusmenetelmät voivat vaihdella eri kokoajissa, esimerkiksi:
Lisäksi joskus on tarpeen määrittää ohjelmakoodin mukana ladattavat tietolohkot, joille kokoaja voi sisältää erityisiä ohjeita. Nykyaikaiset kokoajat voivat myös tukea tiedon organisointia erilaisten rakenteiden muodossa .
Kokoonpanijat voivat tukea erilaisia rakenteita kokoonpanokoodin helpottamiseksi lukea, vapauttaa ohjelmoijan tarpeesta seurata ohjeiden osoitteita ja toteuttaa elementtejä, jotka ovat ominaisia korkean tason kielille.
Kokoonpanokoodi ei yleensä käytä korkean tason kielille ominaisia sisennys- ja operaattorisulkeja . Kokoonpanokoodi kirjoitetaan yleensä useisiin sarakkeisiin, jotka sisältävät:
Tämä kirjoitustapa heijastaa ohjelmien suorittamisen erikoisuutta yleisprosessoreilla: konekoodien tasolla ohjelmat ovat yleensä lineaarisia, niillä ei ole rakennetta ja yhdestä kohdasta ohjelmassa voidaan siirtyä toiseen, riippumatta kohdasta, jossa ohjelmakoodin alku sijaitsee ja ohjelma jatkaa suoritusta siitä kohdasta alkaen paikkaan, jossa siirto tehtiin. Esimerkki kokoonpanokieliohjelmasta PIC16 -arkkitehtuurille :
Jälleen: movf 0x40 , W ;Kopioi sijainti 0x40 (desimaali 64) W-rekisteriin addlw 0x05 ; Lisää vakio 5 W-rekisteriin movwf PORTC ;Kirjoita W-rekisteri mikrokontrollerin PORTC - lähtöporttiin clrw ;Tyhjennä W-rekisteri (tässä ohjeessa ei ole operandeja) Jälleen ;Siirry etikettiin AgainKoska assembler-koodi käännetään yksiselitteisesti tietyn prosessorin konekoodiksi, voit käyttää prosessorin kaikkia ominaisuuksia täydellisemmin, vähentää tarpeettomia "tyhjäkäyntiä" ja käyttää muita ohjelmakoodin optimointimenetelmiä, jotka eivät ole käytettävissä. kääntäjiä käytettäessä optimoivien kääntäjien kehitys johtaa kuitenkin siihen, että niiden tuottaman koodin laatu voi olla korkeampi kuin kohtalaisen taitava assembler-ohjelmoija pystyy kirjoittamaan [5] . Lisäksi, mitä suurempi ohjelman volyymi, sitä pienempi hyöty on kokoonpanokielen käytöstä.
Assembly-kieliohjelmat eivät salli määrittelemätöntä käyttäytymistä , mutta yleensä koodin kirjoittaminen ja virheenkorjaus kokoonpanossa vaatii enemmän vaivaa. Tyyppiohjaus ei ole käytettävissä assemblerissä , minkä vuoksi ohjelmoijan on itse ohjattava tietyn arvon merkitystä ja siihen liittyviä sallittuja toimia. Assembly-kielisiä ohjelmia kirjoitettaessa on käytettävä jatkuvasti pinoa ja rajoitettua määrää yleiskäyttöisiä rekistereitä sekä osoittimia, mikä edellyttää ohjelmoijalta tarkkaavaisuutta ja hyvää muistia.
Kokoonpanokieliohjelmia on lähes mahdotonta siirtää koneelle, jolla on erilainen arkkitehtuuri tai käskysarja kirjoittamatta ohjelmaa uudelleen, vaikka kirjoitettaessa olisi käytetty "alustojen välistä" kokoonpanokielen murretta: eri prosessoriarkkitehtuureissa on erilaiset rekisterit, liput, eri konesanojen kokoja, ja niissä voi myös olla erittäin erikoistuneita komentoja, joita ei ole saatavilla muilla alustoilla.
Assembler - ohjelmalla on enemmän mahdollisuuksia olla vuorovaikutuksessa laitteiston ja käyttöjärjestelmän ytimen kanssa . Esimerkiksi varhaisissa kodin tietokoneissa ja pelikonsoleissa ei ehkä ollut sisäänrakennettua riittävän korkearesoluutioista ajastinta , mutta samaan aikaan prosessorin kellotaajuus oli vakio kaikille samantyyppisille laitteille, mikä mahdollisti sen. käyttää prosessoria ajastimena, laskemalla jaksojen lukumäärää tiettyjen komentojen suorittamiseksi ja lisäämällä tyhjiä operaatioita oikeisiin paikkoihin. Nykyaikaisissa prosessoreissa, jotka käyttävät sisäänrakennettuja suorituskyvyn optimointipiirejä, dynaamisia kellotaajuuden muutoksia ja monimutkaisia keskeytysjärjestelmiä, ja vielä enemmän moniajokäyttöjärjestelmän hallinnassa , tällaiset tekniikat ovat tulleet mahdottomaksi, mutta niitä käytetään edelleen joissakin mikro -ohjaimissa .
Kokoonpanijoiden tulo helpotti suuresti varhaisten tietokoneiden ohjelmointia, mutta melko nopeasti sovellettujen ongelmien monimutkaisuus vaati korkean tason kielten käyttöä. Nämä kielet suoritettiin kuitenkin melko hitaasti, ja lisäksi heillä ei aina ollut pääsyä kaikkiin tietokoneen laitteistoominaisuuksiin. Kun keskustietokoneiden ja minitietokoneiden suorituskyky kasvoi ja kielten, kuten C :n , ilmaantumisen myötä kokoonpanokielen merkitys alkoi laskea, mutta nousi jälleen mikrotietokoneiden myötä . Varhaisilla mikroprosessoreilla oli pääsääntöisesti heikko suorituskyky ja pieni määrä käytettävissä olevaa RAM -muistia , ja lisäksi korkealaatuisia kielikääntäjiä korkean tason kielille ei heti ilmestynyt heille. Usein kotitietokoneiden ohjelmat, mukaan lukien pelit, kirjoitettiin kokonaan assemblerilla. Kuitenkin 2000-luvun alussa tietokoneiden kasvavaan suorituskykyyn lisättiin optimoivia kääntäjiä , jotka tuottivat konekoodia, joka oli optimaalisempaa kuin keskivertoohjelmoija pystyi kirjoittamaan. Lisäksi kysymys siirrettävyydestä eri alustojen välillä on noussut tärkeäksi.
Assembly-kieltä käytetään myös virheenkorjauksessa ja käänteisessä suunnittelussa käyttämällä disassembler -ohjelmia . Disassemblerin avulla voit ohjata ohjelman suorittamista konekäskyjen tasolla, mikä on hyödyllistä esimerkiksi etsittäessä paikkoja, joissa on määrittelemätön toiminta tai virheitä, joita ilmenee osoittimien kanssa työskennellessä.
Kehityksen helpottamiseksi käytettiin seuraavaa lähestymistapaa: suurin osa koodista on kirjoitettu korkean tason kielellä ja vain osat, joiden suorituskyky on kriittistä tai jotka vaativat suoran pääsyn tietokoneen laitteistoresursseihin, kirjoitetaan assemblerilla.
Tämä ohjelma lähettää takaisin UART-sarjaportin kautta vastaanotetun merkin ("Echo"):
mov SCON , #50 h mov TH1 , #0 FDh orl TMOD , #20 h setb TR1 taas: clr RI jnb RI , $ mov A , SBUF jnb RI , $ clr TI mov SBUF , A jnb TI , jälleen $ sjmp Esimerkkejä C :n kääntämisestä kokoonpanokieleksi ARM-arkkitehtuurilleBittitoiminnot:
C:
z = ( a << 2 ) | ( b & 15 );Kokoaja:
ADR r4 , a ; hanki osoite LDR :lle r0 ,[ r4 ] ; hanki MOV :n arvo r0 , r0 , LSL #2 ; suorittaa vaihto ADR r4 , b ; hanki osoite b LDR r1 ,[ r4 ] ; saada arvo b JA r1 , r1 , #15 ; suorittaa JA ORR r1 , r0 , r1 ; suorittaa TAI ADR r4 , z ; hanki osoite z STR r1 ,[ r4 ] ; tallenna z:n arvoOksat:
C:
jos ( i == 0 ) { i = i + 10 ; }Kokoaja:
@(muuttuja i on rekisterissä R1 ) SUBS R1 , R1 , #0 ADDEQ R1 , R1 , # 10Syklit:
C:
for ( i = 0 ; i < 15 ; i ++ ) { j = j + j _ }Kokoaja:
SUB R0 , R0 , R0 ; i -> R0 ja i = 0 aloittaa CMP R0 , #15 ; olenko <15? ADDLT R1 , R1 , R1 ; j = j + j ADDLT R0 , R0 , #1 ; i++ BLT käynnistyy Ohjelma PIC16F628A-mikro-ohjaimelle ( PIC -arkkitehtuuri )Jos mikro-ohjaimen PORTB-porttiin on kytketty 8 LEDiä, ohjelma sytyttää ne yhden jälkeen:
LIST p = 16 F628A __CONFIG 0309 H STATUS equ 0x003 RP0 equ 5 TRISB equ 0x086 PORTB equ 0x006 ORG 0x0000 ;Aloitusvektori aloitti ;Siirry pääkoodin alkuun aloitus: bsf STATUS , RP0 ;Valitse pankki 1 clrf TRISB ; Kaikki PORTB:n bitit ovat lähtöjä bcf STATUS , RP0 ;Valitse pankki 0 led: movlw .170 ;Kirjoita binääriarvo "10101010" PORTB : hen PORTB movwf ; LOPPU Ohjelma MSP430G2231-mikro-ohjaimelle ( MSP430 -arkkitehtuuri ) Code Composer Studiossa .cdecls C , LIST , "msp430g2231.h" ;--------------------------------------- -------------- ------------------------------------- ---- .teksti ; Ohjelma aloitetaan ;----------------------------------------------- ------ -------------------------------- RESET mov.w #0280 h , SP ; Alusta pinoosoitin StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Pysäytä WDT SetupP1 bis.b #001 h , & P1DIR ; P1.0 lähtö ; Mainloop bit.b #010 h , & P1IN ; P1.4 hi/low? jc ON ; jmp--> P1.4 on asetettu ; OFF bic.b #001 h , & P1OUT ; P1.0 = 0 / LED POIS jmp Mainloop ; ON bis.b #001 h , & P1OUT ; P1.0 = 1 / LED PÄÄLLÄ jmp Mainloop ; ; ;------------------------------------------------- ----------------------------- ; Keskeytysvektorit ;------------------------------------------------ ------ -------------------------------- .sect ".reset" ; MSP430 RESET Vector .short RESET ; .endkokoonpanokieli | |
---|---|
IDE | |
Kääntäjät | |
Syntaksimuodot _ |
Ohjelmointikielet | |
---|---|
|