2. cvičení
Literatura
- Keprt, A. Assembler
- Brandejs M. Mikroprocesory Intel Pentium. Brno: Fakulta informatiky, Masarykova univerzita, 2010.
- Přehled všech operací procesorů rodiny x86. (Není potřeba znát.)
Registry
Registr je speciální paměťové místo přímo v procesoru. Práce s nimi je tedy mnohem rychlejší než s pamětí. Procesor v nich uchovává hodnoty, s kterými právě pracuje.
-
datové registry - mají všeobecná použití (jsou univerzální), níže uvedené
jsou jejich vyžadovaná použití při některých operacích, 32-bitové, ke spodním 16 bitům lze
přistupovat pod jménem bez E, a tuto 16-bitovou část je možné ještě rozdělit na
poloviny po osmi bitech, dolních osm bitů označuje jméno
končící L, horních pak jméno končící H. Horních 16 bitů z
celého 32-bitového registru nelze přímo adresovat (nejsou
přístupné přes nějaké jméno). Např. EAX je
32-bitový registr, ke spodním 16 bitům lze přistupovat pod
jménem AX, a z těchto 16 bitů dolních 8 označujeme jako registr AL,
horních pak AH.
- EAX, AX, AH ,AL (Accumulator) - střadač pro násobení a dělení, vstupně-výstupní operace
- EBX, BX, BH, BL (Base) - nepřímá adresace paměti
- ECX, CX, CH, CL (Counter) - počitadlo při cyklech, posuvech a rotacích
- EDX, DX, DH, DL (Data) - nepřímá adresace vstupů/výstupů
-
ukazatele a indexregistry - používají se pro umístění
adresy, 32-bitové, spodních 16 bitů označuje jméno bez E a
nelze je dále dělit (na rozdíl od předchozích
univerzálních registrů):
- EBP, BP (Base Pointer) - bázový registr, adresace parametrů funkcí a lokálních proměnných na zásobníku (adresa dna zásobníku), není rozumné jej libovolně měnit
- ESP, SP (Stack Pointer) - ukazatel na vrchol zásobníku (adresa vrcholu zásobníku), tento také není rozumné libovolně měnit
- EDI, DI (Destination Index) - adresa cíle
- ESI, SI (Source Index) - adresa zdroje
- EIP, IP (Instruction Pointer) - ukazatel na aktuální místo programu, adresa instrukce následující za právě prováděnou instrukcí, není možné jej přímo měnit (jen patřičnými instrukcemi)
Numerické operace
- INC cíl - k cíli přičti jedna (registr, paměť)
- DEC cíl - od cíle odečti jedna (registr, paměť)
- ADD cíl, zdroj - k cíli přičti zdroj (registr - hodnota, paměť - hodnota, registr - registr, paměť - registr, registr - paměť)
- SUB cíl, zdroj - od cíle odečti zdroj (registr - hodnota, paměť - hodnota, registr - registr, paměť - registr, registr - paměť)
- NEG cíl - otoč znaménko v cíli (registr, paměť)
- MUL zdroj - registr AL vynásob se zdrojem (osmibitový registr, nebo paměť) a výsledek zapiš do registru AX (osmibitové násobení).
- MUL zdroj - registr AX vynásob se zdrojem (šestnáctibitový registr, nebo paměť) a výsledek (32 bitů) zapiš do registrového páru DX, AX za sebou (šestnáctibitové násobení).
- MUL zdroj - registr EAX vynásob se zdrojem (32-bitový registr, nebo paměť) a výsledek (64 bitů) zapiš do registrového páru EDX, EAX za sebou (32-bitové násobení).
- IMUL zdroj - jako MUL, ale násobení se znaménkem
- IMUL zdroj, konstanta - jako IMUL, zdroj se vynásobí s konstantou a uloží do zdroje
- IMUL cíl, zdroj - do cíle vlož součin zdroje a cíle (16,32-bitový registr - 16,32-bitový registr, 16,32-bitový registr - paměť)
- IMUL cíl, zdroj, konstanta - do cíle vlož součin zdroje, konstanty (16,32-bitový registr - 16,32-bitový registr - hodnota, 16,32-bitový registr - paměť - hodnota)
- DIV zdroj - registr AX vyděl zdrojem (osmibitový registr, nebo paměť) a podíl ulož do AL, zbytek po dělení ulož do AH (osmibitové dělení)
- DIV zdroj - dvojslovo v registrech DX, AX vyděl zdrojem (šestnáctibitový registr, nebo paměť) a podíl ulož do AX, zbytek po dělení ulož do DX (šestnáctibitové dělení)
- DIV zdroj - čtyřslovo v registrech EDX, EAX vyděl zdrojem (dvaatřicetibitový registr, nebo paměť) a podíl ulož do EAX, zbytek po dělení ulož do EDX (dvaatřicetibitové dělení)
- IDIV zdroj - jako DIV ale dělení se znaménkem
Úkoly
- Napište v assembleru funkci
int obvod_obdelnika(int a, int b)
, která spočítá obvod obdélníka. - Napište v assembleru funkci
int obsah_obdelnika(int a, int b)
, která spočítá obsah obdélníka. - Napište v assembleru funkci
int obvod_ctverce(int a)
, která spočítá obvod čtverce. - Napište v assembleru funkci
int obsah_ctverce(int a)
, která spočítá obsah čtverce. - Napište v assembleru funkci
int obvod_trojuhelnika(int a, int b, int c)
, která spočítá obvod trojúhelníka. - Napište v assembleru funkci
int obvod_trojuhelnika2(int a)
, která spočítá obvod rovnostranného trojúhelníka. - Napište v assembleru funkci
int obsah_trojuhelnika2(int a, int b)
, která spočítá obsah pravoúhlého trojúhelníka. - Napište v assembleru funkci
int obsah_trojuhelnika3(int a, int va)
, která spočítá obsah trojúhelníka z velikosti strany a příslušné výšky. - Napište v assembleru funkci
int objem_krychle(int a)
, která spočítá objem krychle. - Napište program, který vypočítá obsah trojúhelníka podle Heronova vzorce:
P = sqrt(s*(s-a)*(s-b)*(s-c)), s = (a+b+c)/2.
Programu zadáte strany a, b, c (v jazyce C), pak se výpočet provede v Assembleru až po závěrečnou odmocninu, kterou provedete pomocí funkce sqrt v C (musíte vložit hlavičkový soubor math.h). Výsledek vypište (pomocí funkce printf v C).