Jazyk montáže - Assembly language

Jazyk montáže
Motorola 6800 Assembly Language.png
Typický sekundární výstup z assembleru - ukazuje původní jazyk sestavení (vpravo) pro Motorola MC6800 a sestavený formulář
Paradigma Imperativní , nestrukturované
Poprvé se objevil 1949 ; Před 72 lety ( 1949 )

V počítačovém programování je montážní jazyk (nebo také assemblerový jazyk ), někdy zkráceně asm , jakýkoli nízkoúrovňový programovací jazyk, ve kterém existuje velmi silná shoda mezi pokyny v jazyce a pokyny ke strojovému kódu architektury . Protože sestavení závisí na pokynech ke strojovému kódu, je každý jazyk sestavení navržen přesně pro jednu konkrétní architekturu počítače. Jazyku sestavení lze také říkat symbolický strojový kód .

Sestavovací kód je převeden na spustitelný strojový kód pomocí obslužného programu označovaného jako assembler . Proces přeměny se označuje jako montáž , stejně jako v montáži na zdrojový kód . Jazyk sestavení má obvykle jeden příkaz na strojovou instrukci (1: 1), ale obecně jsou podporovány také konstanty, komentáře , direktivy assembleru , symbolické popisky umístění programu a paměti a makra .

Termín „assembler“ je obecně přisuzován Wilkesovi , Wheelerovi a Gillovi v jejich knize Příprava programů pro elektronický digitální počítač z roku 1951 , kteří však tento termín používali ve smyslu „programu, který sestavuje další program sestávající z několika sekcí do jeden program “.

Každý jazyk sestavení je specifický pro konkrétní počítačovou architekturu a někdy i pro operační systém . Některé jazyky sestavení však neposkytují specifickou syntaxi pro volání operačního systému a většinu jazyků sestavení lze použít univerzálně s jakýmkoli operačním systémem, protože jazyk poskytuje přístup ke všem skutečným schopnostem procesoru , na kterém nakonec spočívají všechny mechanismy systémového volání . Na rozdíl od montážních jazyků je většina programovacích jazyků na vysoké úrovni obecně přenosná napříč více architekturami, ale vyžadují interpretaci nebo kompilaci , což je mnohem složitější úkol než sestavování.

Výpočetní krok, když assembler zpracovává program, se nazývá čas sestavení .

Syntaxe jazyka sestavení

Jazyk sestavení používá mnemotechnickou pomůcku k reprezentaci každé strojové instrukce nebo operačního kódu nízké úrovně , obvykle také každého architektonického registru , vlajky atd. Mnoho operací vyžaduje k vytvoření úplné instrukce jeden nebo více operandů . Většina assemblerů povoluje pojmenované konstanty, registry a popisky pro umístění programu a paměti a umí vypočítat výrazy pro operandy. Programátoři jsou tedy osvobozeni od únavných opakujících se výpočtů a programy assembleru jsou mnohem čitelnější než strojový kód. V závislosti na architektuře mohou být tyto prvky také kombinovány pro konkrétní instrukce nebo režimy adresování pomocí offsetů nebo jiných dat, stejně jako pevných adres. Mnoho assemblerů nabízí další mechanismy, které usnadňují vývoj programu, řídí proces montáže a pomáhají ladit .

Terminologie

  • Makro assembler je assembler, který obsahuje makroinstrukce zařízení tak, aby (parametrizovat) Text assembleru mohou být reprezentovány názvem, a že název lze použít k vložení rozšířený text do jiného kódu.
  • Kříž assembler (viz také kompilátor kříže ) je montér, který je spuštěn na počítači nebo operačního systému (dále jen hostitelský systém) z jiného druhu, v systému, na které je výsledný kód je spustit (na cílový systém ). Cross-assembling usnadňuje vývoj programů pro systémy, které nemají prostředky na podporu vývoje softwaru, jako je vestavěný systém nebo mikrokontrolér . V takovém případě musí být výsledný kód objektu přenesen do cílového systému prostřednictvím paměti jen pro čtení (ROM, EPROM atd.), Programátoru (když je v zařízení integrována paměť pouze pro čtení, jako v mikrokontrolérech) , nebo datový odkaz využívající buď přesnou bitovou kopii kopie objektového kódu, nebo textovou reprezentaci tohoto kódu (například hexadecimální Intel nebo záznam S Motorola ).
  • A assembler na vysoké úrovni je program, který poskytuje jazykové abstrakce častěji spojené s jazyky na vysoké úrovni, jako jsou pokročilé řídicí struktury ( IF/THEN/ELSE , DO CASE atd.) A abstraktní datové typy na vysoké úrovni, včetně struktur/ záznamy, svazy, třídy a sady.
  • Microassembler je program, který pomáhá připravit mikroprogram , nazvaný firmware , aby řídit provoz nízké úrovni počítače.
  • Meta-assembler je „program, který přijímá syntaktickou a sémantickou popis a jazyk sestavy, a generuje assembler pro daný jazyk.“ Montéry „Meta-Symbol“ pro počítače řady SDS 9 a SDS Sigma jsou meta-assemblery. Sperry Univac také poskytl Meta-Assembler pro řadu UNIVAC 1100/2200 .
  • inline assembler (nebo embedded assembler ) je kód assembleru obsažený v jazykovém programu vyšší úrovně. To se nejčastěji používá v systémových programech, které vyžadují přímý přístup k hardwaru.

Klíčové koncepty

Montér

Assembler program vytvoří objektový kód by překlady kombinace mnemotechnické pomůcky a syntaxe pro operace a adresování režimy do jejich číselné ekvivalenty. Tato reprezentace obvykle obsahuje operační kód („ operační kód “) a další řídicí bity a data. Assembler také vypočítává konstantní výrazy a řeší symbolické názvy pro umístění v paměti a další entity. Použití symbolických odkazů je klíčovou vlastností assemblerů, což šetří zdlouhavé výpočty a ruční aktualizace adres po úpravách programu. Většina assemblerů také obsahuje makra pro provádění textové substituce - např. Ke generování běžných krátkých sekvencí instrukcí jako vložených , namísto nazývaných podprogramů .

Někteří montéři mohou být také schopni provádět některé jednoduché typy optimalizací specifických pro sadu instrukcí . Jedním konkrétním příkladem toho mohou být všudypřítomné montéry x86 od různých prodejců. Říká se jim velikost skoku , většina z nich je schopna na požádání provést náhradu instrukcí skoku (dlouhé skoky nahrazené krátkými nebo relativními skoky) v libovolném počtu průchodů. Jiní mohou dokonce provést jednoduché přeskupení nebo vložení instrukcí, například některé assemblery pro architektury RISC, které mohou pomoci optimalizovat rozumné plánování instrukcí tak, aby bylo možné co nejefektivněji využívat potrubí CPU .

Assemblery jsou k dispozici od padesátých let minulého století, jako první krok nad strojovým jazykem a před programovacími jazyky na vysoké úrovni, jako jsou Fortran , Algol , COBOL a Lisp . Existuje také několik tříd translátorů a poloautomatických generátorů kódu s vlastnostmi podobnými jak jazykům sestavení, tak jazyků na vysoké úrovni, přičemž Speedcode je možná jedním z známějších příkladů.

Pro konkrétní architekturu CPU nebo sady instrukcí může existovat několik assemblerů s různou syntaxí . Například instrukce pro přidání paměťových dat do registru v procesoru rodiny x86 může být v původní syntaxi Intel , zatímco tato by byla zapsána v syntaxi AT&T používané GNU Assemblerem . Přes různé podoby obecně generují různé syntaktické formy stejný číselný strojový kód . Jeden assembler může mít také různé režimy, aby podporoval variace v syntaktických formách a také jejich přesné sémantické interpretace (jako je FASM -syntax, TASM -syntax, ideální režim atd., Ve zvláštním případě programování sestavení x86 ). add eax,[ebx]addl (%ebx),%eax

Počet průchodů

Existují dva typy assemblerů podle toho, kolik průchodů zdrojem je potřeba (kolikrát assembler čte zdroj) k vytvoření souboru objektu.

  • Jednoprůchodové assemblery procházejí zdrojovým kódem jednou. Jakýkoli symbol použitý před definováním bude vyžadovat „errata“ na konci kódu objektu (nebo alespoň ne dříve, než je definován symbol), který řekne linkeru nebo zavaděči, aby se „vrátili“ a přepsali zástupný symbol, který byl ponechán tam, kde byl použit dosud nedefinovaný symbol.
  • Víceprůchodové assemblery vytvoří tabulku se všemi symboly a jejich hodnotami v prvních průchodech, poté tabulku použijí v pozdějších průchodech ke generování kódu.

V obou případech musí být assembler schopen určit velikost každé instrukce na počátečních průchodech, aby mohl vypočítat adresy následujících symbolů. To znamená, že pokud velikost operace odkazující na operand definovaný později závisí na typu nebo vzdálenosti operandu, sestavitel provede pesimistický odhad při prvním setkání s operací a v případě potřeby jej vyplní jedním nebo více „ ne-operační “pokyny v pozdějším průchodu nebo chybách. V assembleru s optimalizací kukátka mohou být adresy přepočítány mezi průchody, aby bylo možné nahradit pesimistický kód kódem přizpůsobeným na přesnou vzdálenost od cíle.

Původním důvodem pro použití jednoprůchodových assemblerů byla velikost paměti a rychlost montáže-druhý průchod často vyžadoval uložení tabulky symbolů do paměti (pro zpracování dopředných odkazů ), přetočení a opětovné načtení zdroje programu na pásku nebo opětovné načtení balíček karet nebo děrný papír . Pozdější počítače s mnohem většími pamětmi (zejména diskové úložiště) měly prostor k provedení veškerého nezbytného zpracování bez takového opětovného čtení. Výhodou víceprůchodového assembleru je, že absence errata zrychluje proces propojení (nebo načítání programu, pokud assembler přímo produkuje spustitelný kód).

Příklad: v následujícím fragmentu kódu by jednoprůchodový assembler dokázal určit adresu zpětné reference BKWD při sestavování příkazu S2 , ale nebyl by schopen určit adresu dopředného referenčního FWD při sestavování větvového příkazu S1 ; ve skutečnosti může být FWD nedefinováno. Dvouprůchodový assembler by určil obě adresy v průchodu 1, takže by byly známy při generování kódu v průchodu 2.

S1   B    FWD
  ...
FWD   EQU *
  ...
BKWD  EQU *
  ...
S2    B   BKWD

Montéři na vysoké úrovni

Sofistikovanější montéry na vysoké úrovni poskytují jazykové abstrakce, jako například:

Další podrobnosti viz Jazykový design níže.

Jazyk montáže

Program napsaný v jazyce sestavení se skládá ze série instrukcí mnemotechnického procesoru a meta-prohlášení (různě známých jako směrnice, pseudo-instrukce a pseudo-ops), komentářů a dat. Pokyny pro jazyk sestavení obvykle sestávají z mnemotechnického kódu opcode následovaného operandem , kterým může být seznam dat, argumentů nebo parametrů. Některé instrukce mohou být „implikované“, což znamená, že data, na kterých instrukce funguje, jsou implicitně definována samotnou instrukcí - taková instrukce nebere operand. Výsledný příkaz je přeložen assemblerem do instrukcí strojového jazyka, které lze načíst do paměti a spustit.

Níže uvedená instrukce například říká procesoru x86 / IA-32, aby přesunul okamžitou 8bitovou hodnotu do registru . Binární kód pro tuto instrukci je 10110 a následně 3-bitovým identifikátorem pro které registrovat k použití. Identifikátor pro AL registr je 000, takže následující strojový kód načte AL registr s daty 01100001.

10110000 01100001

Tento binární počítačový kód může být lépe čitelný pro člověka jeho vyjádřením v hexadecimální podobě následujícím způsobem.

B0 61

Zde B0znamená „Přesunout kopii následující hodnoty do AL a 61je hexadecimálním vyjádřením hodnoty 01100001, která je 97 v desítkové soustavě . Jazyk sestavení pro rodinu 8086 poskytuje mnemotechnické pomůcky MOV (zkratka tahu ) pro takovéto pokyny, takže výše uvedený strojový kód lze v jazyce sestavení zapsat následovně, v případě potřeby doplnit vysvětlujícím komentářem za středníkem. To se mnohem snáze čte a pamatuje.

MOV AL, 61h       ; Load AL with 97 decimal (61 hex)

V některých jazycích sestavení (včetně tohoto) lze použít stejnou mnemotechnickou pomůcku, například MOV, pro řadu souvisejících pokynů pro načítání, kopírování a přesouvání dat, ať už se jedná o okamžité hodnoty, hodnoty v registrech nebo umístění paměti, na která ukazuje hodnoty v registrech nebo okamžitými (aka přímými) adresami. Jiní montéři mohou používat samostatné mnemotechnické pomůcky, jako je L pro „přesun paměti do registru“, ST pro „přesun registru do paměti“, LR pro „přesun registru do registru“, MVI pro „přesun bezprostředního operandu do paměti“ atd.

Pokud je pro různé instrukce použita stejná mnemotechnická pomůcka, znamená to, že mnemotechnická pomůcka odpovídá několika různým binárním kódům instrukcí, vyjma dat (např. 61hV tomto příkladu), v závislosti na operandech, které mnemotechnické pomůcky následují. Například u procesorů x86/IA-32 syntaxe montážního jazyka Intel MOV AL, AHpředstavuje instrukci, která přesouvá obsah registru AH do registru AL . Hexadecimální forma této instrukce je:

88 E0

První bajt, 88h, identifikuje přesun mezi registrem velikosti bajtu a buď jiným registrem nebo pamětí, a druhý byte, E0h, je zakódován (se třemi bitovými poli), aby se určilo, že oba operandy jsou registry, zdrojem je AH , a cíl je AL .

V případě, jako je tento, kde stejná mnemotechnická pomůcka může představovat více než jednu binární instrukci, assembler určí, kterou instrukci vygeneruje, prozkoumáním operandů. V prvním příkladu je operand 61hplatnou hexadecimální číselnou konstantou a není platným názvem registru, takže B0lze použít pouze instrukci. V druhém příkladu je operandem AHplatný název registru a nikoli platná číselná konstanta (hexadecimální, desítková, osmičková nebo binární), takže 88lze použít pouze instrukci.

Sestavovací jazyky jsou vždy navrženy tak, aby tento druh jednoznačnosti byl univerzálně vynucován jejich syntaxí. Například v sestavovacím jazyce Intel x86 musí hexadecimální konstanta začínat číslicí, aby hexadecimální číslo 'A' (rovné desítkové desítce) bylo zapsáno jako 0Ahnebo 0AHne AH, konkrétně tak, aby se nezdálo, že je název registru AH . (Stejné pravidlo také zabraňuje nejednoznačnosti s názvy registrů BH , CH a DH , stejně jako s jakýmkoli uživatelem definovaným symbolem, který končí písmenem H a jinak obsahuje pouze znaky, které jsou hexadecimální číslice, například slovo „BEACH ".)

Vrátíme-li se k původnímu příkladu, zatímco operační kód x86 10110000 ( B0) zkopíruje 8bitovou hodnotu do registru AL , 10110001 ( B1) ji přesune do CL a 10110010 ( B2) učiní do DL . Následují příklady jazyka sestavení.

MOV AL, 1h        ; Load AL with immediate value 1
MOV CL, 2h        ; Load CL with immediate value 2
MOV DL, 3h        ; Load DL with immediate value 3

Syntaxe MOV může být také složitější, jak ukazují následující příklady.

MOV EAX, [EBX]	  ; Move the 4 bytes in memory at the address contained in EBX into EAX
MOV [ESI+EAX], CL ; Move the contents of CL into the byte at address ESI+EAX
MOV DS, DX        ; Move the contents of DX into segment register DS

V každém případě je MOV mnemonic převeden přímo do jednoho z operačních kódů 88-8C, 8E, A0-A3, B0-BF, C6 nebo C7 pomocí assembleru a programátor normálně nemusí vědět ani si pamatovat jaké.

Transformace montážního jazyka na strojový kód je úkolem assembleru a obrácení lze alespoň částečně dosáhnout pomocí disassembleru . Na rozdíl od jazyků vyšší úrovně existuje individuální korespondence mezi mnoha jednoduchými prohlášeními o sestavení a pokyny ke strojovému jazyku. V některých případech však může assembler poskytovat pseudoinstrukce (v podstatě makra), které se rozšiřují do několika instrukcí strojového jazyka, aby poskytovaly běžně potřebné funkce. Například pro stroj, kterému chybí instrukce „větev, pokud je větší nebo stejná“, může assembler poskytnout pseudoinstrukci, která se rozšíří na „sadu, pokud je menší než“ a „větev, pokud je nulová (na základě nastavené instrukce)“ . Většina plně vybavených assemblerů také poskytuje bohatý makro jazyk (popsaný níže), který používají prodejci a programátoři ke generování složitějších kódových a datových sekvencí. Protože informace o pseudoinstrukcích a makrech definovaných v prostředí assembleru nejsou v objektovém programu k dispozici, disassembler nemůže rekonstruovat vyvolání maker a pseudoinstrukce, ale může pouze rozebrat skutečné strojové instrukce, které assembler vygeneroval z těchto abstraktních entit jazyka sestavení. Podobně, protože komentáře ve zdrojovém souboru jazyka assembleru jsou ignorovány a nemají žádný vliv na generovaný kód objektu, disassembler není vždy schopen obnovit zdrojové komentáře.

Každá počítačová architektura má svůj vlastní strojový jazyk. Počítače se liší počtem a typem operací, které podporují, různými velikostmi a počty registrů a reprezentací dat v úložišti. Zatímco většina počítačů pro všeobecné použití je schopna provádět v podstatě stejnou funkcionalitu, způsoby, jak to dělají, se liší; odpovídající montážní jazyky odrážejí tyto rozdíly.

Pro jednu sadu instrukcí může existovat více sad mnemotechnik nebo syntaxe jazyka sestavení, obvykle vytvořených v různých programech assembleru. V těchto případech je nejoblíbenější obvykle ten, který dodává výrobce CPU a používá se v jeho dokumentaci.

Dva příklady CPU, které mají dvě různé sady mnemotechnických pomůcek, jsou rodina Intel 8080 a Intel 8086/8088. Protože Intel nárokoval autorská práva na mnemotechniku ​​svého montážního jazyka (alespoň na každé stránce jejich dokumentace publikované v 70. a na začátku 80. let), některé společnosti, které nezávisle vyráběly CPU kompatibilní s instrukčními sadami Intel, vynalezly vlastní mnemotechniku. Z80 CPU, povznesení na Intel 8080A , podporuje všechny pokyny 8080A a navíc mnoho dalších; Zilog vynalezl zcela nový montážní jazyk, nejen pro nové instrukce, ale také pro všechny instrukce 8080A. Například tam, kde Intel používá pro různé instrukce přenosu dat mnemotechnické pomůcky MOV , MVI , LDA , STA , LXI , LDAX , STAX , LHLD a SHLD , montážní jazyk Z80 používá pro všechny mnemotechnické pomůcky LD . Podobným případem jsou procesory NEC V20 a V30 , vylepšené kopie procesorů Intel 8086, respektive 8088. Stejně jako Zilog se Z80, NEC vynalezl novou mnemotechniku ​​pro všechny instrukce 8086 a 8088, aby se vyhnul obviněním z porušení autorských práv společnosti Intel. (Je sporné, zda taková autorská práva mohou být platná, a později společnosti vyrábějící CPU, jako jsou AMD a Cyrix, znovu zveřejnily mnemotechniku ​​instrukcí Intel x86/IA-32 přesně bez povolení a bez zákonných sankcí.) Je sporné, zda v praxi mnoho lidí, kteří programovali V20 a V30 ve skutečnosti psal spíše v jazyce sestavení NEC než v jazyce Intel; protože jakékoli dva montážní jazyky pro stejnou architekturu instrukční sady jsou izomorfní (něco jako angličtina a prasečí latina ), není zde žádný požadavek na použití vlastního publikačního jazyka výrobce s produkty tohoto výrobce.

Jazykový design

Základní prvky

Existuje značná míra rozmanitosti ve způsobu, jakým autoři assemblerů kategorizují výroky, a v nomenklatuře, kterou používají. Někteří zejména popisují pseudo-operaci (pseudo-op) cokoli jiného než strojní mnemotechniku ​​nebo rozšířenou mnemotechnickou pomůcku. Typický jazyk sestavení se skládá ze 3 typů příkazů instrukcí, které se používají k definování operací programu:

  • Mnemotechnika opcode
  • Definice dat
  • Montážní směrnice

Mnemotechnické pomůcky a rozšířené mnemotechnické pomůcky

Pokyny (příkazy) v jazyce sestavení jsou obecně velmi jednoduché, na rozdíl od pokynů v jazycích vyšší úrovně . Obecně je mnemotechnická pomůcka symbolický název pro jedinou spustitelnou instrukci strojového jazyka ( opcode ) a pro každou instrukci strojového jazyka je definován alespoň jeden mnemotechnický kód opcode. Každá instrukce se obvykle skládá z operace nebo operačního kódu plus nula nebo více operandů . Většina pokynů se týká jedné hodnoty nebo dvojice hodnot. Operandy mohou být okamžité (hodnota kódovaná v samotné instrukci), registry specifikované v instrukci nebo implikované, nebo adresy dat umístěných jinde v úložišti. To je určeno základní architekturou procesoru: assembler pouze odráží, jak tato architektura funguje. Rozšířené mnemotechnické pomůcky se často používají ke specifikaci kombinace operačního kódu s konkrétním operandem, např. Montéry System/360 používají Bjako rozšířené mnemotechnické pomůcky pro BCs maskou 15 a NOP(„NO OPeration“ - nedělejte nic pro jeden krok) pro BCs maska ​​0.

Rozšířené mnemotechnické pomůcky se často používají k podpoře specializovaného použití instrukcí, často pro účely, které nejsou zřejmé z názvu instrukce. Například mnoho CPU nemá explicitní instrukci NOP, ale má instrukce, které lze pro tento účel použít. V 8086 CPU je instrukce použita pro , přičemž je to pseudo-opcode pro kódování instrukce . Někteří disassembleri to rozpoznají a dekódují instrukci jako . Podobně používají assemblery IBM pro System/360 a System/370 rozšířenou mnemotechniku a pro a s nulovými maskami. Pro architekturu SPARC jsou tyto známé jako syntetické pokyny . xchg ax,axnopnopxchg ax,axxchg ax,axnopNOPNOPRBCBCR

Někteří assembleri také podporují jednoduché vestavěné makro pokyny, které generují dva nebo více strojových pokynů. Například u některých assemblerů Z80 je instrukce ld hl,bcrozpoznána a ld l,cpoté následuje ld h,b. Někdy se jim říká pseudo-opcodes .

Mnemotechnické pomůcky jsou libovolné symboly; v roce 1985 IEEE publikovalo standard 694 pro jednotnou sadu mnemotechnických pomůcek, kterou mají používat všichni montéři. Norma byla od té doby stažena.

Datové směrnice

Existují instrukce používané k definování datových prvků pro uložení dat a proměnných. Definují typ dat, délku a zarovnání dat. Tyto pokyny mohou také definovat, zda jsou data k dispozici externím programům (programy sestavené samostatně) nebo pouze programu, ve kterém je definována datová sekce. Někteří montéři je klasifikují jako pseudoopy.

Montážní směrnice

Direktivy sestavení, nazývané také pseudo-opcodes, pseudo-operace nebo pseudo-ops, jsou příkazy dané assembleru „směřující k provádění jiných operací než k sestavování instrukcí“. Směrnice ovlivňují fungování assembleru a „mohou ovlivnit kód objektu, tabulku symbolů, soubor se seznamem a hodnoty interních parametrů assembleru“. Někdy je termín pseudo-opcode vyhrazen pro směrnice, které generují objektový kód, jako jsou ty, které generují data.

Názvy pseudooperací často začínají tečkou, aby se odlišily od pokynů ke stroji. Pseudo-operace mohou sestavení programu záviset na parametrech zadaných programátorem, takže jeden program lze sestavit různými způsoby, třeba pro různé aplikace. Nebo lze k manipulaci s prezentací programu použít pseudoop, aby bylo snazší číst a udržovat. Dalším běžným využitím pseudooperací je rezervace úložných oblastí pro data za běhu a volitelně inicializace jejich obsahu na známé hodnoty.

Symbolické assemblery umožňují programátorům spojovat libovolná jména ( popisky nebo symboly ) s paměťovými místy a různými konstantami. Obvykle je každé konstantě a proměnné přidělen název, takže instrukce mohou na tato místa odkazovat jménem, ​​čímž podporují kód pro vlastní dokumentaci . V spustitelném kódu je název každého podprogramu spojen s jeho vstupním bodem, takže všechna volání podprogramu mohou používat jeho název. Uvnitř podprogramů jsou cíle GOTO označeny štítky. Někteří assembleri podporují místní symboly, které se často lexikálně liší od normálních symbolů (např. Použití „10 $“ jako cíle GOTO).

Některé assemblery, jako například NASM , poskytují flexibilní správu symbolů, umožňují programátorům spravovat různé obory názvů , automaticky počítat offsety v datových strukturách a přiřazovat popisky, které odkazují na doslovné hodnoty nebo výsledek jednoduchých výpočtů prováděných assemblerem. Štítky lze také použít k inicializaci konstant a proměnných s přemístitelnými adresami.

Jazyky sestavení, jako většina ostatních počítačových jazyků, umožňují přidávat komentáře do zdrojového kódu programu, které budou během sestavování ignorovány. Uvážlivé komentáře jsou v programech sestavovacího jazyka zásadní, protože význam a účel sekvence instrukcí binárních strojů může být obtížné určit. "Surový" (nekomentovaný) sestavovací jazyk generovaný kompilátory nebo disassemblery je docela obtížné přečíst, když je nutné provést změny.

Makra

Mnoho assemblerů podporuje předdefinovaná makra a další podporují programátorem definovaná (a opakovaně znovu definovatelná) makra zahrnující sekvence textových řádků, ve kterých jsou vloženy proměnné a konstanty. Definice makra je nejčastěji směsí příkazů assembleru, např. Směrnic, symbolických strojních instrukcí a šablon pro příkazy assembleru. Tato sekvence textových řádků může obsahovat operační kódy nebo směrnice. Jakmile je makro definováno, jeho název může být použit místo mnemotechnické pomůcky. Když assembler zpracuje takový příkaz, nahradí příkaz textovými řádky přidruženými k tomuto makru a poté je zpracuje, jako by existovaly v souboru zdrojového kódu (včetně, v některých assemblerech, rozšíření všech maker existujících v náhradním textu) . V tomto smyslu se makra datují k automatickým kodérům IBM z 50. let minulého století.

V jazyce sestavení termín „makro“ představuje komplexnější koncept než v některých jiných kontextech, jako je například předprocesor v programovacím jazyce C , kde se jeho direktiva #define obvykle používá k vytváření krátkých jednořádkových maker. Makro instrukce Assembleru, jako makra v PL/I a některých dalších jazycích, mohou být samy o sobě zdlouhavými „programy“, prováděnými interpretací assemblerem během montáže.

Protože makra mohou mít „krátká“ jména, ale mohou se rozšířit na několik nebo skutečně mnoho řádků kódu, lze je použít k tomu, aby programy v jazyce sestavení vypadaly mnohem kratší a vyžadovaly méně řádků zdrojového kódu, jako u jazyků vyšší úrovně. Lze je také použít k přidání vyšších úrovní struktury do montážních programů, volitelně zavést vložený ladicí kód pomocí parametrů a dalších podobných funkcí.

Sestavovatelé maker často umožňují makrům přijímat parametry . Některé assemblery obsahují docela propracované jazyky jazyků makra, zahrnující prvky jazyka na vysoké úrovni, jako jsou volitelné parametry, symbolické proměnné, podmíněné výrazy, manipulace s řetězci a aritmetické operace, všechny použitelné během provádění daného makra, a umožňující makru ukládat kontext nebo vyměňovat informace . Makro tedy může na základě argumentů makra generovat četné instrukce v jazyce sestavení nebo definice dat. Toho lze využít například ke generování datových struktur ve stylu záznamu nebo „ rozvinutých “ smyček nebo k vygenerování celých algoritmů na základě komplexních parametrů. Například makro „sort“ by mohlo přijmout specifikaci komplexního klíče řazení a generovat kód vytvořený pro tento konkrétní klíč, aniž by bylo nutné provádět běhové testy, které by byly vyžadovány pro obecný postup interpretující specifikaci. Organizace využívající jazyk sestavení, která byla výrazně rozšířena pomocí takové sady maker, lze považovat za organizaci pracující v jazyce vyšší úrovně, protože tito programátoři nepracují s koncepčními prvky nejnižší úrovně počítače. Podtržení tohoto bodu, makra byla použita k implementaci raného virtuálního stroje v SNOBOL4 (1967), který byl napsán v SNOBOL Implementation Language (SIL), což je montážní jazyk pro virtuální počítač. Cílový počítač by to přeložil do svého nativního kódu pomocí makro assembleru . To umožnilo vysoký stupeň přenositelnosti po určitou dobu.

Makra byla použita k přizpůsobení rozsáhlých softwarových systémů konkrétním zákazníkům v éře sálových počítačů a byla také používána zákaznickým personálem k uspokojení potřeb jejich zaměstnavatelů vytvářením konkrétních verzí operačních systémů výrobce. To provedli například programátoři systémů pracující s IBM Conversational Monitor System / Virtual Machine ( VM / CMS ) a s doplňky IBM „zpracování transakcí v reálném čase“, CICS Customer Information Control System a ACP / TPF , letecký/finanční systém, který začal v 70. letech minulého století a dodnes provozuje mnoho velkých počítačových rezervačních systémů (CRS) a systémů kreditních karet.

Je také možné použít výhradně schopnosti makra pro zpracování assembleru ke generování kódu napsaného ve zcela odlišných jazycích, například ke generování verze programu v COBOLu pomocí programu čistého makro assembleru obsahujícího řádky kódu COBOL uvnitř operátorů času montáže instruování assembleru ke generování libovolného kódu. IBM OS/360 používá k generování systému makra . Uživatel určuje možnosti kódováním řady maker assembleru. Shromážděním těchto maker se generuje tok úloh pro sestavení systému, včetně jazyka pro řízení úloh a příkazů pro ovládání nástrojů .

Důvodem je, že jak bylo realizováno v šedesátých letech minulého století, koncept „makro zpracování“ je nezávislý na konceptu „shromáždění“, přičemž první z nich je v moderních pojmech více zpracování textu, zpracování textu než generování objektového kódu. Koncept zpracování makra se objevil a objevuje v programovacím jazyce C, který podporuje "instrukce preprocesoru" pro nastavení proměnných a provádění podmíněných testů na jejich hodnotách. Na rozdíl od určitých předchozích makro procesorů uvnitř assemblerů není preprocesor C Turingově úplný, protože postrádá schopnost buď smyčky, nebo „přejít na“, což umožňuje programům smyčku.

Navzdory síle zpracování makra se v mnoha jazycích vysoké úrovně (hlavní výjimky jsou C , C ++ a PL/I) přestal používat, a přesto zůstal trvalkou pro assemblery.

Náhrada parametru makra je striktně podle názvu: v době zpracování makra je hodnota parametru textově nahrazena jeho názvem. Nejslavnější třídou chyb, které z toho vyplynuly, bylo použití parametru, který sám byl výrazem a ne jednoduchým názvem, když zapisovatel maker očekával název. V makru:

foo: macro a
load a*b

záměrem bylo, aby volající poskytl název proměnné a „globální“ proměnná nebo konstanta b by byla použita k vynásobení „a“. Pokud je s parametrem voláno foo a-c, dojde k rozšíření makra o load a-c*b. Aby se předešlo případné nejednoznačnosti, uživatelé procesorů maker mohou v definicích maker definovat v závorkách formální parametry, nebo volající mohou zadat parametry v závorkách.

Podpora strukturovaného programování

Byly napsány balíčky maker poskytující strukturované programovací prvky pro kódování toku provádění. Nejčasnější příklad tohoto přístupu byl v sadě maker Concept-14 , původně navržené Harlanem Millsem (březen 1970) a implementované Marvinem Kesslerem z divize Federal Systems Division společnosti IBM, která poskytovala IF/ELSE/ENDIF a podobné řídicí bloky toku pro OS /360 assemblerových programů. To byl způsob, jak omezit nebo eliminovat používání operací GOTO v kódu sestavy, což je jeden z hlavních faktorů způsobujících kód špaget v jazyce sestavení. Tento přístup byl široce přijímán na začátku 80. let (v posledních dnech používání rozsáhlého montážního jazyka). IBM High Level Assembler Toolkit takový balíček maker obsahuje.

Kuriózním návrhem byl A-natural , „ proudově orientovaný“ assembler pro 8080/ Z80 , procesory od společnosti Whitesmiths Ltd. (vývojáři operačního systému Idris podobného Unixu a který byl údajně prvním komerčním kompilátorem C ). Jazyk byl klasifikován jako assembler, protože pracoval s nezpracovanými strojovými prvky, jako jsou operační kódy , registry a odkazy na paměť; ale zahrnovalo syntaxi výrazu k označení pořadí provedení. Závorky a další speciální symboly spolu s blokově orientovanými strukturovanými programovacími konstrukty řídily posloupnost generovaných instrukcí. A-natural byl postaven jako objektový jazyk kompilátoru C, nikoli pro ruční kódování, ale jeho logická syntax si získala některé fanoušky.

Od úpadku rozsáhlého vývoje jazyka assembleru existuje jen malá zjevná poptávka po sofistikovanějších assemblerech. Navzdory tomu jsou stále vyvíjeny a používány v případech, kdy omezení zdrojů nebo zvláštnosti v architektuře cílového systému brání účinnému používání jazyků vyšší úrovně.

Assemblery se silným modulem maker umožňují strukturované programování pomocí maker, jako je například makro přepínače dodávané s balíčkem Masm32 (tento kód je kompletní program):

include \masm32\include\masm32rt.inc	; use the Masm32 library

.code
demomain:
  REPEAT 20
	switch rv(nrandom, 9)	; generate a number between 0 and 8
	mov ecx, 7
	case 0
		print "case 0"
	case ecx				; in contrast to most other programming languages,
		print "case 7"		; the Masm32 switch allows "variable cases"
	case 1 .. 3
		.if eax==1
			print "case 1"
		.elseif eax==2
			print "case 2"
		.else
			print "cases 1 to 3: other"
		.endif
	case 4, 6, 8
		print "cases 4, 6 or 8"
	default
		mov ebx, 19		     ; print 20 stars
		.Repeat
			print "*"
			dec ebx
		.Until Sign?		 ; loop until the sign flag is set
	endsw
	print chr$(13, 10)
  ENDM
  exit
end demomain

Použití montážního jazyka

Historická perspektiva

Jazyky sestavení nebyly v době zavedení počítače s uloženým programem k dispozici . Kathleen Booth „se jí připisuje vynalézání montážního jazyka“ na základě teoretické práce, kterou začala v roce 1947, když pracovala na ARC2 na Birkbeck, University of London po konzultaci Andrewa Bootha (pozdějšího manžela) s matematikem Johnem von Neumannem a fyzikem Hermanem Goldstinem na Institute for Advanced Study .

Na konci roku 1948 měla elektronická kalkulačka zpoždění úložiště (EDSAC) integrovaný assembler (pojmenovaný „počáteční objednávky“) do svého bootstrap programu. Používala jednopísmennou mnemotechniku ​​vyvinutou Davidem Wheelerem , který je zásluhou IEEE Computer Society jako tvůrce prvního „assembleru“. Zprávy o EDSAC zavedly termín „shromáždění“ pro proces kombinování polí do instrukčního slova. SOAP ( Symbolic Optimal Assembly Program ) byl montážní jazyk pro počítač IBM 650 napsaný Stanem Poleyem v roce 1955.

Sestavovací jazyky eliminují velkou část chyb náchylných, únavných a časově náročných programování první generace, potřebných pro nejranější počítače, osvobození programátorů od únavy, jako je zapamatování si číselných kódů a výpočet adres.

Montážní jazyky byly kdysi široce používány pro všechny druhy programování. V 80. letech (90. léta na mikropočítačích ) však jejich používání do značné míry vytlačily jazyky vyšší úrovně při hledání lepší produktivity programování . Jazyk sestavení se dnes stále používá pro přímou manipulaci s hardwarem, přístup ke specializovaným instrukcím procesoru nebo pro řešení kritických problémů s výkonem. Typickým použitím jsou ovladače zařízení , vestavěné systémy nízké úrovně a systémy v reálném čase .

Historicky bylo mnoho programů napsáno výhradně v jazyce sestavení. Burroughs MCP (1961) byl první počítač, pro který operační systém nebyl vyvinut úplně v jazyce symbolických instrukcí; bylo napsáno v algolském dialektu Executive Systems Problem Oriented Language (ESPOL). Mnoho komerčních aplikací bylo napsáno také v montážním jazyce, včetně velkého množství mainframového softwaru IBM napsaného velkými korporacemi. COBOL , FORTRAN a některé PL/I nakonec vytlačily velkou část této práce, přestože řada velkých organizací si do 90. let 20. století zachovala aplikační infrastrukturu v jazyce sestavení.

Většina raných mikropočítačů spoléhala na ručně kódovaný jazyk sestavení, včetně většiny operačních systémů a velkých aplikací. Důvodem bylo, že tyto systémy měly vážná omezení zdrojů, ukládaly výstřední architektury paměti a zobrazení a poskytovaly omezené systémové služby typu buggy. Možná důležitější byl nedostatek prvotřídních překladačů jazyka na vysoké úrovni vhodných pro použití s ​​mikropočítači. Svou roli mohl sehrát i psychologický faktor: první generace mikropočítačových programátorů si zachovala fandy, přístup „dráty a kleště“.

V komerčnějším kontextu byly největšími důvody pro použití assembleru minimální nadýmání (velikost), minimální režie, vyšší rychlost a spolehlivost.

Typickými příklady velkých shromáždění jazykových programů z této doby jsou IBM PC DOS operační systémy, Turbo Pascal kompilátor a začátkem aplikace, jako je například tabulkového programu Lotus 1-2-3 . Pro získání nejlepšího výkonu ze Sega Saturn , konzoly, jejíž vývoj a programování her pro notoricky náročné hry bylo použito, byl použit montážní jazyk . Arkádová hra NBA Jam z roku 1993 je dalším příkladem.

Jazyk sestavení je již dlouhou dobu primárním vývojovým jazykem mnoha populárních domácích počítačů 80. a 90. let (například MSX , Sinclair ZX Spectrum , Commodore 64 , Commodore Amiga a Atari ST ). To bylo z velké části proto, že interpretované ZÁKLADNÍ dialekty na těchto systémech nabízely nedostatečnou rychlost provedení a také nedostatečná zařízení k plnému využití výhod dostupného hardwaru v těchto systémech. Některé systémy mají dokonce integrované vývojové prostředí (IDE) s vysoce pokročilými nástroji pro ladění a makra. Některé kompilátory dostupné pro Radio Shack TRS-80 a jeho nástupce měly schopnost kombinovat vložený zdroj sestavení s programovými prohlášeními na vysoké úrovni. Při kompilaci vytvořil vestavěný assembler vložený strojový kód.

Aktuální využití

Vždy se vedly debaty o užitečnosti a výkonu montážního jazyka ve srovnání s jazyky vyšší úrovně.

Ačkoli jazyk sestavení má specifické specializované použití tam, kde je to důležité (viz níže), existují další nástroje pro optimalizaci.

V červenci 2017 řadí index popularity programovacího jazyka TIOBE jazyk sestavení na 11, například před Visual Basic . Assembler lze použít k optimalizaci rychlosti nebo optimalizaci velikosti. V případě optimalizace rychlosti se tvrdí , že moderní optimalizační kompilátory vykreslují jazyky na vysoké úrovni do kódu, který lze spustit stejně rychle jako ručně psané sestavení, a to navzdory protikladům, které lze nalézt. Složitost moderních procesorů a paměťových subsystémů ztěžuje efektivní optimalizaci jak pro překladače, tak pro programátory sestav. Zvýšení výkonu procesoru navíc znamenalo, že většina procesorů většinu času nečinně pracovala se zpožděním způsobeným předvídatelnými překážkami, jako jsou vynechání mezipaměti, I/O operace a stránkování . To způsobilo, že rychlost provádění surového kódu není problémem mnoha programátorů.

Existují určité situace, ve kterých se vývojáři mohou rozhodnout použít jazyk sestavení:

  • Psací kód pro systémy se staršími procesory, které mají omezené jazykové možnosti na vysoké úrovni, jako jsou Atari 2600 , Commodore 64 , a grafové kalkulačky . Programy pro tyto počítače 70. a 80. let jsou často psány v kontextu demoscénních nebo retrogamingových subkultur.
  • Kód, který musí interagovat přímo s hardwarem, například v ovladačích zařízení a obslužných programech přerušení .
  • Ve vestavěném procesoru nebo DSP přerušení s vysokým opakováním vyžadují nejkratší počet cyklů na přerušení, například přerušení, které nastane 1 000 nebo 10 000krát za sekundu.
  • Programy, které potřebují používat pokyny specifické pro procesor, nejsou implementovány v kompilátoru. Běžným příkladem je bitová rotační instrukce v jádru mnoha šifrovacích algoritmů a také dotazování na paritu bajtu nebo 4bitové přenášení přídavku.
  • Je vyžadován samostatný spustitelný soubor kompaktní velikosti, který se musí spustit bez použití běhových komponent nebo knihoven spojených s jazykem na vysoké úrovni. Mezi příklady patří firmware pro telefony, automobilové palivové a zapalovací systémy, řídicí systémy klimatizace, zabezpečovací systémy a senzory.
  • Programy s vnitřními smyčkami citlivými na výkon, kde jazyk sestavení poskytuje možnosti optimalizace, kterých je v jazyce vysoké úrovně obtížné dosáhnout. Například lineární algebra s BLAS nebo diskrétní kosinovou transformací (např. Verze sestavy SIMD od x264 ).
  • Programy, které vytvářejí vektorizované funkce pro programy ve vyšších jazycích, jako je C. V jazyce vyšší úrovně tomu někdy pomáhají vnitřní funkce kompilátoru, které mapují přímo na mnemotechnické pomůcky SIMD, ale přesto mají za následek specifickou konverzi sestavení individuální. pro daný vektorový procesor.
  • Programy v reálném čase, jako jsou simulace, letové navigační systémy a lékařské vybavení. Například v systému fly-by-wire musí být telemetrie interpretována a musí se s ní jednat v přísných časových omezeních. Takové systémy musí eliminovat zdroje nepředvídatelných zpoždění, která mohou být vytvářena (některými) interpretovanými jazyky, automatickým sběrem odpadu , stránkovacími operacemi nebo preemptivním multitaskingem . Některé jazyky vyšší úrovně však obsahují běhové komponenty a rozhraní operačního systému, které mohou taková zpoždění zavést. Výběr sestavení nebo jazyků nižší úrovně pro takové systémy dává programátorům větší viditelnost a kontrolu nad detaily zpracování.
  • Kryptografické algoritmy, jejichž provedení musí vždy trvat přesně stejnou dobu, aby se zabránilo útokům s načasováním .
  • Upravte a rozšiřte starší kód napsaný pro počítače sálových počítačů IBM.
  • Situace, kde je vyžadována úplná kontrola nad prostředím, v situacích extrémně vysokého zabezpečení, kde nelze nic považovat za samozřejmost .
  • Počítačové viry , zavaděče , ovladače určitých zařízení nebo jiné položky velmi blízké hardwaru nebo nízkoúrovňovému operačnímu systému.
  • Instrukční sada simulátorů pro monitorování, trasování a ladění, kde jsou další režie omezeny na minimum.
  • Situace, kde neexistuje žádný jazyk na vysoké úrovni, na novém nebo specializovaném procesoru, pro který není k dispozici žádný křížový překladač .
  • Zpětné inženýrství a úpravy programových souborů, jako jsou:
    • stávající binární soubory, které mohou nebo nemusí být původně napsány v jazyce vysoké úrovně, například při pokusu o znovuvytvoření programů, pro které není k dispozici nebo byl ztracen zdrojový kód, nebo ochrana proti kopírování proprietárního softwaru.
    • Videohry (také nazývané ROM hacking ), které je možné několika způsoby. Nejrozšířenější metodou je změna programového kódu na úrovni jazyka sestavení.

Montážní jazyk se stále vyučuje ve většině programů počítačové vědy a elektronického inženýrství . Ačkoli dnes několik programátorů pravidelně pracuje s montážním jazykem jako nástrojem, základní koncepty zůstávají důležité. Taková základní témata, jako je binární aritmetika , alokace paměti , zpracování zásobníku , kódování znakové sady , přerušení zpracování a návrh kompilátoru, by bylo těžké detailně prostudovat bez pochopení toho, jak počítač funguje na hardwarové úrovni. Protože chování počítače je zásadně definováno jeho sadou instrukcí, logickým způsobem, jak se takové koncepty naučit, je studium montážního jazyka. Většina moderních počítačů má podobné sady instrukcí. Proto studium jednoho montážního jazyka stačí k osvojení: I) základních pojmů; II) rozpoznat situace, kdy by použití montážního jazyka mohlo být vhodné; a III), abychom zjistili, jak lze z vysoce kvalitních jazyků vytvořit účinný spustitelný kód.

Typické aplikace

  • Jazyk sestavení se obvykle používá v zaváděcím kódu systému, v kódu nízké úrovně, který inicializuje a testuje hardware systému před spuštěním operačního systému a je často uložen v paměti ROM . ( BIOS na počítačových systémech kompatibilních s IBM a CP/M je příkladem.)
  • Pro nízkoúrovňový kód se často používá assembler, například pro jádra operačních systémů , která se nemohou spoléhat na dostupnost již existujících systémových volání a musí je skutečně implementovat pro konkrétní architekturu procesoru, na které bude systém spuštěn.
  • Některé kompilátory překládají jazyky vysoké úrovně do sestavení před úplným kompilací, což umožňuje zobrazit kód sestavení pro účely ladění a optimalizace.
  • Některé kompilátory pro jazyky relativně nízké úrovně, například Pascal nebo C , umožňují programátorovi vložit jazyk sestavení přímo do zdrojového kódu (tzv. Vložené sestavení ). Programy využívající taková zařízení pak mohou vytvářet abstrakce pomocí odlišného jazyka sestavení na každé hardwarové platformě. Přenosný kód systému pak může používat tyto komponenty specifické pro procesor prostřednictvím jednotného rozhraní.
  • Jazyk montáže je užitečný v reverzním inženýrství . Mnoho programů je distribuováno pouze ve formě strojového kódu, který lze snadno přeložit do jazyka sestavení pomocí disassembleru , ale obtížněji přeložit do jazyka vyšší úrovně pomocí dekompilovače . Nástroje jako Interactive Disassembler hojně využívají pro tento účel demontáž. Tuto techniku ​​používají hackeři k prolomení komerčního softwaru a konkurenti k výrobě softwaru s podobnými výsledky od konkurenčních společností.
  • Jazyk sestavení se používá ke zvýšení rychlosti provádění, zejména u starších osobních počítačů s omezeným výpočetním výkonem a pamětí RAM.
  • Assemblery lze použít ke generování bloků dat, bez režie jazyka na vysoké úrovni, z formátovaného a komentovaného zdrojového kódu, které mají být použity jiným kódem.

Viz také

Poznámky

Reference

Další čtení

externí odkazy