Asennussisäke

Ohjelmoinnissa inline assembler tarkoittaa kääntäjän kykyä upottaa assemblerillä kirjoitettua matalan tason koodia korkean tason kielellä kirjoitettuun ohjelmaan , kuten C tai Ada . Kokoonpano-osien käytöllä voidaan saavuttaa seuraavat tavoitteet:

Esimerkki optimoinnista ja prosessoriohjeiden käytöstä

Tämä esimerkki assemblerin lisäyksestä D -ohjelmointikielellä , joka toteuttaa x:n tangentin laskennan, käyttää x86 FPU - käskyjä . Tämä koodi toimii nopeammin kuin se koodi, jonka kääntäjä voisi tuottaa. Myös tässä olevaa käskyä käytetään fldpi, joka lataa lähimmän numerolikiarvon x86-arkkitehtuurille.

// Laske tangentin x real tan ( todellinen x ) { asm { fld x [ EBP ] ; // lataa x fxam ; // testaa parittomat arvot fstsw AX ; sahf ; jc trigerr ; // x on NAN, ääretön tai tyhjä // 387:t voivat käsitellä denormaaleja SC18 : fptan ; fstp ST ( 0 ) ; // tyhjennä X, joka on aina 1 fstsw AX ; sahf ; jnp Lret ; // C2 = 1 (x on alueen ulkopuolella) // Suorita argumentin pelkistys tuodaksesi x alueelle fldpi ; fxch ; SC17 : fprem1 ; fstsw AX ; sahf ; jp SC17 ; fstp ST ( 1 ) ; // poista pi pinosta jmp SC18 ; } trigerr : palauta real . nan ; Lret : ; }

Järjestelmäkutsuesimerkki

Käyttöjärjestelmään pääsy suoraan ei yleensä ole mahdollista suojatulla muistilla. Käyttöjärjestelmä toimii etuoikeutetuimmalla tasolla (ydintila) kuin käyttäjä (käyttäjätila). Pyyntöjen tekemiseksi käyttöjärjestelmälle käytetään ohjelmistokeskeytyksiä. Harvoin korkean tason kielet tukevat tätä ominaisuutta, joten järjestelmäkutsuliitännät kirjoitetaan inline assemblerilla [1] .

Seuraava C-esimerkki sisältää järjestelmäkutsuliittymän, joka on kirjoitettu käyttäen AT&T :n GNU Assembler -syntaksia . Katsotaanpa ensin assembler-inserttimuotoa yksinkertaisella esimerkillä:

asm ( "movl %ecx, %eax" ); /* siirtää ecx:n sisällön eax:hen */

Tunnisteet asmja __asm__ovat vastaavia. Toinen yksinkertainen lisäysesimerkki:

__asm__ ( "movb %bh, (%eax)" ); /* siirtää tavun bh:sta eax:n osoittamaan muistiin */

Esimerkki toteutuksesta järjestelmäkutsuliittymästä:

extern int errno ; int funktionimi ( int arg1 , int * arg2 , int arg3 ) { int res ; __asm__ epävakaa ( "int $0x80" /* tee pyyntö käyttöjärjestelmälle */ : "=a" ( res ), /* palauttaa tuloksen eax:ssa ("a") */ "+b" ( arg1 ), /* läpäise arg1 in ebx ("b") */ "+c" ( arg2 ), /* läpäise arg2 ecx:ssä ("c") */ "+d" ( arg3 ) /* pass arg3 in edx ("d") */ : "a" ( 128 ) /* järjestelmän kutsunumero eax:ssa ("a") */ : "muisti" , "cc" ); /* ilmoittaa kääntäjälle, että muisti- ja ehtokoodeja on muutettu */ /* Käyttöjärjestelmä palauttaa negatiivisen arvon virheen sattuessa; * kääreet palauttavat virheen -1 ja asettavat errno globaalin muuttujan */ if ( -125 <= res && res < 0 ) { errno = -res ; _ res = -1 ; } return res ; }

Kritiikki

2000-luvun alusta lähtien kokoonpanoelementtien käyttö on tuomittu yhä enemmän useista syistä [2] [3] :

  • Nykyaikaiset optimoivat kääntäjät pystyvät luomaan parempaa kokoonpanokoodia kuin tavallinen ohjelmoija pystyy kirjoittamaan. Assembler-lisäkkeet voivat itsessään häiritä koodin muiden osien optimointia. Jotkut temput, jotka mahdollistivat koodin suorituskyvyn optimoinnin 1980-90-luvun prosessoreissa myöhemmissä prosessoreissa, voivat johtaa suoritusten huomattavaan hidastumiseen laskennan erilaisen organisoinnin vuoksi. Kuten mikä tahansa optimointi , kokoajien lisäosat on testattava , jotta voidaan testata hypoteesi niiden tehokkuudesta. Tietojenkäsittelyjärjestelmien suorituskyvyn kasvun vuoksi monet optimoinnit voivat olla merkityksettömiä, ja koodin luettavuus, ylläpidon helppous ja virheiden estäminen tulevat etusijalle.
  • Kokoonpanokoodin kirjoittaminen vie enemmän aikaa. Kokoonpanokappaleessa on helppo tehdä virhe, jota on vaikea havaita. Esimerkiksi kokoonpanokieli ei tue tyypin tarkistusta . Jo luotua kokoonpanokoodia on vaikeampi ylläpitää .
  • Kokoonpanokoodi ei ole kannettava. Asennusosat ovat perusteltuja päästäkseen käsiksi alustakohtaisiin mekanismeihin. Käytettäessä assembler-inserttejä cross-platform-ohjelmissa , on välttämätöntä monistaa assembler-insertit eri alustoille ja myös mahdollisuuksien mukaan säilyttää vaihtoehtoinen toteutus korkean tason kielellä - mutta tämä käytäntö aiheuttaa ongelmia ohjelman ylläpidossa, koska täytyy tehdä muutoksia rinnakkain useisiin eri kielillä kirjoitetun koodin osiin, kieliin ja eri alustoihin.

Muistiinpanot

  1. 1 2 "Linux-ohjelmointi" Luku 5. Kuinka järjestelmäkutsut toimivat . Opennet. Käyttöpäivä: 29. syyskuuta 2013. Arkistoitu alkuperäisestä 2. lokakuuta 2013.
  2. Assembler-inserttien käytön analyysi avoimien projektien koodissa . opennet . Haettu 3. toukokuuta 2022. Arkistoitu alkuperäisestä 3. toukokuuta 2022.
  3. Syyt, miksi ÄLÄ käytä inline asm . Haettu 3. toukokuuta 2022. Arkistoitu alkuperäisestä 28. huhtikuuta 2022.

Linkit