Assembler

Assembler
Ilustrační obrázek článku Assembler
Datum první verze 1949
Přípona souboru asm and s

Sestavení jazyk nebo sestavení jazyk je v programování počítače , na nejnižší úrovni jazyka , který reprezentuje jazyk stroj v čitelné podoby. Kombinace bitů strojového jazyka jsou reprezentovány takzvanými „ mnemotechnickými “  symboly  , to znamená snadno zapamatovatelnými. Sestava Program převede tyto mnemotechnické pomůcky do strojového jazyka, jakož i hodnoty (psáno v desítkové soustavě) do binární a štítky lokalit do adres, s cílem vytvořit, například soubor objekt nebo spustitelný soubor .

V současné praxi se stejný výraz assembler používá jak k označení montážního jazyka, tak k montážnímu programu, který jej překládá. Mluvíme tedy o „programování v assembleru“.

Překlad jednou a navždy mnoha tlumočníky každého názvu proměnné, se kterým se setkal v (pokročilé) instrukci přidruženou pozicí paměti a každé konstanty (zapsané uživatelem v desítkové soustavě) do binárního souboru, je pro operaci d typický. ' name assembler se v tomto konkrétním případě běžně nepoužívá.

Dějiny

Programy EDSAC (1949), prvního počítače se zaznamenanými programy , byly psány pomocí abecední mnemotechniky jednoho dopisu pro každou instrukci. Překlad poté provedli programátoři ručně, což byla dlouhá, zdlouhavá a na chyby náchylná operace.

První montážní program napsal Nathaniel Rochester pro IBM 701 (první počítač vydaný společností IBM ) v roce 1954.

Montážní jazyky eliminovaly mnoho chyb, kterých se programátoři první generace počítačů dopustili tím, že odpadli nutnost zapamatovat si číselné kódy pokynů a provádět výpočty adres. Programování sestavy bylo poté použito k psaní všech druhů programů.

V letech 1970-1980 bylo použití assembleru k psaní aplikací velmi z velké části nahrazeno používáním programovacích jazyků na vysoké úrovni: Fortran , COBOL , PL / I atd. : výkon strojů to umožňoval a věnovat několik minut počítačového času kompilaci, aby ušetřil několik hodin programátorského času, byla zisková operace, i když tehdejší kompilátoři poskytovali méně efektivní kód (větší a často pomalejší). Tyto jazyky vysoké úrovně navíc umožnily překonat závislost na jediné hardwarové architektuře.

Tyto operační systémy byly psány v jazyce symbolických instrukcí do zavedení MCP do Burroughs v roce 1961, který byl zapsán ESPOL, dialekt Algol .

Assembler se poněkud vrátil ve prospěch prvních mikropočítačů, kde technické vlastnosti (zmenšená velikost paměti, nízký výpočetní výkon, specifická architektura paměti atd.) Ukládaly silná omezení, k nimž se přidává důležitý důležitý psychologický, „fandy“ přístup prvních uživatelů mikropočítačů, kteří nebyli spokojeni s pomalostí programů psaných s interpretovaným BASICem obecně dodávaným s počítačem.

Velké programy byly psaný úplně v sestava pro mikropočítače, jako je například DOS operačního systému na IBM PC (kolem 4000 řádků kódu) a Lotus 1-2-3 tabulky (jeho soupeře Multiplan, která existovala již v CP / M , byl napsáno v C ). V 90. letech to platilo také pro většinu her pro video konzoly (například pro Mega Drive nebo Super Nintendo ).

Zvláštnosti assembleru

Specifický jazyk pro každý procesor

Jazyk stroje je jediný jazyk, který může procesor provádět. Každá rodina procesorů však používá jinou sadu pokynů .

Například procesor rodiny x86 rozpozná instrukci typu:

10110000 01100001

V assembleru je tato instrukce reprezentována ekvivalentem, kterému programátor snáze rozumí:

movb $0x61,%al

(10110000 = movb% al
01100001 = $ 0x61)

To znamená: „zapište číslo 97 (hodnota je uvedena hexadecimálně  : 61 16 = 97 10 ) do registru AL“.

Proto je montážní jazyk, přesné vyjádření strojového jazyka, specifický pro každou architekturu procesoru . Kromě toho pro jednu sadu instrukcí může existovat více skupin mnemotechnických pomůcek nebo syntaxí jazyka sestavení, čímž se vytvoří makro-instrukce .

Demontáž

Transformace kódu sestavy do jazyka stroje se provádí programem zvaným program sestavy . Reverzní provoz , a to nalezení assembler odpovídající část kódu stroje, má název: je demontáž .

Na rozdíl od toho, co by si někdo mohl myslet, mezi kódem sestavení a jazykem stroje není vždy individuální korespondence ( bijekce ). U některých procesorů proto může demontáž vyústit v kód, který je pro člověka velmi obtížné pochopit, zatímco zůstane perfektně kompilovatelný počítačem. Nemožnost demontáže může mít různé důvody: použití samočinně se měnícího kódu, instrukce proměnné velikosti, nemožnost rozlišovat mezi kódem a daty atd. ( neproniknutelný kód )

Navíc se při překladu do strojového jazyka ztratí mnoho prvků obsažených v kódu sestavy. Při vytváření kódu v assembleru může programátor přiřadit názvy pozic v paměti, komentovat jeho kód , použít makro-instrukce nebo použít kód vygenerovaný za podmínek v době sestavení. Všechny tyto prvky jsou během montáže redukovány na to, co je pro stroj bezpodmínečně nutné, a proto se během demontáže neobjevují jasně: například poloha v paměti je označena pouze její číselnou adresou nebo posunem .

Pokyny pro stroj

Některé základní operace jsou k dispozici ve většině sad instrukcí.

  • Výtlak v paměti:
    • načítání hodnoty do registru;
    • přesunutí hodnoty z paměťového místa do registru a naopak;
  • Výpočet:
    • sčítání nebo odčítání hodnot dvou registrů a načítání výsledku do registru;
    • kombinace hodnot dvou registrů po booleovské operaci (nebo bitové operaci);
  • Úprava pořadí programu:
    • přeskočit na jiné místo v programu (obvykle se instrukce provádějí postupně, jeden po druhém);
    • skočit na jiné místo, ale po uložení umístění další instrukce, abyste se na ni mohli vrátit (bod návratu);
    • návrat do posledního bodu návratu;
  • Srovnání:
    • porovnat hodnoty dvou registrů.

A existují konkrétní pokyny s jedním nebo několika pokyny pro operace, které by měly trvat hodně. Příklady:

Direktivy montážního jazyka

Kromě instrukcí pro kódovací stroj mají montážní jazyky další směrnice pro sestavování bloků dat a přiřazování adres k instrukcím definováním značek nebo štítků.

Jsou schopni definovat symbolické výrazy, které se vyhodnocují na každém sestavení, což usnadňuje čtení a porozumění kódu.

Obvykle mají vestavěný makro jazyk, který usnadňuje generování složitých kódů nebo bloků dat.

Jednoduché příklady

Zde je několik jednoduchých příkladů:

$ gcc foo.S -c -o foo.o $ ld foo.o -o foo $ ./foo

Show Hello

(Komentáře jsou za středníky)

str: .ascii "Bonjour\n" .global _start _start: movl $4, %eax movl $1, %ebx movl $str, %ecx movl $8, %edx int $0x80 movl $1, %eax movl $0, %ebx int $0x80 ;Compilation: ;as code.s -o code.o ;ld code.o -o code ;Execution: ;./code

Přečtěte si klávesnici (maximálně 16 znaků) a poté ji zobrazte

# define N 16 .global _start .comm BUFF , N _start: mov $3 , %eax mov $0 , %ebx mov $BUFF , %ecx mov $N , %edx int $0x80 mov %eax , %edx mov $4 , %eax mov $1 , %ebx mov $BUFF , %ecx int $0x80 mov $1 , %eax mov $0 , %ebx int $0x80

Jednoduché příklady, syntaxe Intel x86

Zde jsou stejné příklady s několika rozdíly:

  • v syntaxi Intel x86 , napsané pro assembler NASM  ;
  • pomocí sady instrukcí i386  ;
  • použít následovně:
$ nasm -f elf foo.asm $ ld -o foo foo.o -melf_i386 $ ./foo

Ukázat dobrý večer

(Komentáře jsou za středníky)

section .data ; Variables initialisées Buffer: db 'Bonsoir', 10 ; En ascii, 10 = '\n'. La virgule sert à concaténer les chaines BufferSize: equ $-Buffer ; Taille de la chaine section .text ; Le code source est écrit dans cette section global _start ; Définition de l'entrée du programme _start: ; Entrée du programme mov eax, 4 ; Appel de sys_write mov ebx, 1 ; Sortie standard STDOUT mov ecx, Buffer ; Chaine à afficher mov edx, BufferSize ; Taille de la chaine int 80h ; Interruption du kernel mov eax, 1 ; Appel de sys_exit mov ebx, 0 ; Code de retour int 80h ; Interruption du kernel


Přečtěte si klávesnici (max. 64 znaků) a poté ji zobrazte

section .bss ; Section des variables non-initialisees Buffer: resb 64 ; Reservation de 64 blocs (octets ?) memoire pour la variable où sera stockee l'entree de l'utilisateur BufferSize: equ $-Buffer ; taille de cette variable section .text ; Section du code source global _start _start: ; Entree du programme mov eax, 3 ; Appel de sys_read mov ebx, 0 ; Entree standard STDIN mov ecx, Buffer ; Stockage de l'entree de l'utilisateur mov edx, BufferSize ; Taille maximale int 80h ; Interruption du kernel mov eax, 4 ; Appel de sys_write mov ebx, 1 ; Sortie standard STDOUT mov ecx, Buffer ; Chaine à afficher mov edx, BufferSize ; Taille de la chaine int 80h ; Interruption du kernel mov eax, 1 ; Appel de sys_exit mov ebx, 0 ; Code de retour int 80h ; Interruption du kernel

Použití montážního jazyka

Diskutuje se o užitečnosti montážního jazyka. V mnoha případech mohou kompilátoři - optimalizátoři transformovat jazyk na vysoké úrovni na kód, který běží stejně efektivně jako kód sestavení ručně psaný velmi dobrým programátorem, a přitom je mnohem snazší, rychlejší (a tedy méně efektivní). Nákladné) psát, číst a udržovat .

Efektivita byla v 50. letech znepokojující, stopu po něm najdeme v jazykové příručce Fortran (vydané v roce 1956) pro počítač IBM 704  : Objektové programy produkované Fortranem budou téměř stejně účinné jako programy napsané dobrými programátory .

Překladatelé, kteří mezitím dosáhli obrovského pokroku, je tedy zřejmé, že drtivá většina programů je nyní z ekonomických důvodů napsána v jazycích vysoké úrovně, přičemž dodatečné náklady na program převažují nad ziskem vyplývajícím z očekávaného zlepšení výkonu.

Stále však existují některé velmi konkrétní případy, kdy je použití assembleru stále oprávněné:

  1. Některé složité výpočty psané přímo v assembleru, zejména na masivně paralelních strojích , budou rychlejší, kompilátory nebudou dostatečně sofistikované, aby využily specifičnosti těchto architektur;
  2. Některé rutiny ( ovladače ) se někdy snadněji píší v nízkoúrovňovém jazyce;
  3. Úkoly velmi závislé na systému prováděné v paměťovém prostoru operačního systému jsou někdy obtížné nebo dokonce nemožné psát v jazyce vysoké úrovně. Například pokyny pro sestavení, které systému Windows umožňují spravovat změnu úlohy (LGDT a LLDT) na procesoru i386 a následujícím mikroprocesoru, nelze emulovat ani generovat jazykem na vysoké úrovni. Musí být nutně kódovány v krátkém podprogramu sestavy, který bude vyvolán z programu napsaného v jazyce vysoké úrovně.

Někteří kompilátoři transformují, pokud není povolena jejich nejvyšší optimalizační možnost , programy napsané v jazyce vyšší úrovně na kód sestavy, přičemž každá instrukce na vysoké úrovni má za následek řadu důsledně ekvivalentních pokynů pro sestavení a použití stejných symbolů; to vám umožní zobrazit kód pro účely ladění a profilování , což může někdy ušetřit mnohem více času generální opravou algoritmu . Za žádných okolností nelze tyto techniky uchovat pro finální optimalizaci.

Programování vestavěných systémů , často založené na mikrokontrolérech , je tradičním „výklenkem“ pro programování sestav. Ve skutečnosti jsou tyto systémy často velmi omezené na zdroje (například mikrokontrolér PIC 16F84 je omezen na 1024 14bitových instrukcí a jeho RAM obsahuje 136 bajtů), a proto vyžadují velmi optimalizované programování na nízké úrovni, aby bylo možné využít jeho možností. Díky vývoji hardwaru se však komponenty těchto systémů stávají stále výkonnějšími při stálých nákladech a při konstantní spotřebě energie, investice do programování „jakéhokoli asembleru“ mnohem dražšího v hodinách práce se pak stává investicí nesmysl, pokud jde o úsilí. Programování sestavení je obvykle mnohem delší, delikátnější (protože programátor musí brát v úvahu všechny mikro detaily vývoje, kterých se ve vysokém jazyce zdrží), a proto je podstatně dražší než programování v vysokém jazyce. Mělo by proto být vyhrazeno pouze pro situace, pro které nelze udělat jinak.

Makro-assembler

Mnoho assemblerů podporuje jazyk maker . Jde o seskupení několika instrukcí, aby byly logičtější a méně zdlouhavé.
Například (v Microsoft MASM assembleru ):

putchar Macro car ; Prototype de la macro ifdef car ; si car est défini mov dl,car ; le mettre dans dl endif mov ah,2 ; ah=2 : fonction "putchar" en DOS int 21h ; appel au DOS endm ; fin macro

je makro, které zobrazuje znak v systému MS-DOS . Bude použit například takto:

putchar "X"

A vygeneruje:

mov dl,"X" mov ah,2 int 21h

Pseudonávody

Pseudo-instrukce je speciální typ makro instrukce. Je předdefinován editorem montážního softwaru a jeho funkcí je emulovat chybějící instrukci procesoru nebo usnadnit použití existující instrukce. Vzhledem k tomu, že pseudonávod má velmi podobný název jako skutečná instrukce procesoru, je možné jej na první pohled zaměnit za jeden z druhých. Například procesor RISC nemusí mít instrukci JMP, která vám umožní přeskočit na konkrétní bod v programu a pokračovat v jeho provádění v pořadí. V tomto případě vytvoří softwarový editor pro programátor pseudo-instrukci „JMP <parameter>“, která bude během sestavení nahrazena instrukcí „mov pc , <parameter>“, přičemž pc bude ukazatelová instrukce, která má být popraven. Další příklad, „dodávání <parametr>“ pseudo-instrukce budou nahrazeny skladování <parametr> na adrese, na který ukazuje sp s předem dekrementování posledně uvedeného, sp bytím zásobník ukazatel z procesoru.

Na mikroprocesorech nebo mikroprocesorech RISC, jako jsou například rodiny ARM , neexistuje žádná montážní instrukce umožňující načtení jakékoli okamžité konstanty do registru bez ohledu na její hodnotu. Většina assemblerů má pseudo-instrukci, která umožňuje takové načítání co nejefektivnějším možným způsobem, pokud jde o dobu provedení, což šetří programátorovi tento úkol.

Strukturované programování v assembleru

Podpora strukturovaného programování  : některé prvky strukturovaného programování byly integrovány, aby zakódovaly tok provádění pomocí Dr. HD Mills (Březen 1970), a implementoval Marvin Kessler, který rozšířil makro assembler S / 360 o if / else / endif a dokonce bloky řízení toku. To byl způsob, jak omezit nebo vyloučit použití operací skoku v kódu sestavy.

Poznámky a odkazy

  1. Laurent Bloch , Úvod do programování pomocí Scheme , Éditions TECHNIP,2011( číst online ).

Podívejte se také