BLACK FRIDAY! Slevy až 80 % jsou všude. Tak je nepropásni a přejdi do rostoucího IT oboru!
The real BF 2020

Lekce 12 - Assembler - Rejstřík instrukcí procesoru

V minulé lekci, Assembler - Registry procesoru, jsme si ukázali skoro všechny registry procesorů x86 a x64.

Procesor má velké množství instrukcí, ve kterých se není snadné vyznat. Proto si dnes ukážeme jejich stručný přehled, abychom měli představu, co všechno procesor dokáže. Ani zdaleka to není kompletní seznam. Jednotlivé instrukce budou podrobněji vysvětleny v dalších lekcích.

Tato lekce slouží k zopakování instrukcí, které již známe, jako ochutnávka instrukcí nových, a jako záchytný bod, ke kterému se můžete kdykoli vrátit a instrukce si zopakovat.

Přesun dat

Pro přesun dat můžeme použít:

  • MOV - přiřazení hodnoty do registru, přesun hodnot mezi dvěma registry nebo mezi registrem a pamětí
  • MOVZX, MOVSX - přesun a zároveň rozšíření na větší typ, doplnění nulami nebo znaménkem
  • CMOVcc - podmíněné přiřazení
  • LEA - výpočet adresy
  • PUSH, POP - uložení a vyzvednutí hodnoty ze zásobníku
  • PUSHA, POPA - uložení všech registrů na zásobník
  • XCHG - prohození dvou hodnot

Větvení programu

Následující instrukce souvisejí s větvením programu:

  • JMP - nepodmíněný skok
  • Jcc - podmíněný skok (cc je příznak nebo podmínka, např. C, Z, G, LE)
  • CALL - volání funkce
  • RET, RETN - návrat z funkce a případně také odstranění parametrů ze zásobníku
  • INT - vyvolání přerušení
  • IRET - návrat z přerušení
  • SYSCALL - volání funkce operačního systému
  • SYSRET - návrat z funkce operačního systému

Příznaky

S příznaky pracujeme následujícími instrukcemi:

  • PUSHF, POPF - uložení všech příznaků na zásobník
  • LAHF, SAHF - uložení příznaků SF, ZF, AF, PF, CF do registru AH
  • SETcc - uložení jednoho příznaku do libovolného registru nebo do paměti
  • CLC, STC, CMC - vynulování, nastavení nebo změna CF (Carry)
  • CLD, STD - vynulování nebo nastavení DF (Direction)

Aritmetické operace

Pro aritmetické operace máme k dispozici instrukce:

  • ADD, ADC, SUB, SBB - sčítání, odčítání
  • INC, DEC - zvětšení o jedna, zmenšení o jedna
  • MUL, IMUL, DIV, IDIV - násobení, dělení, bez znaménka nebo se znaménkem
  • CMP - porovnání
  • NEG - změna znaménka
  • CBW, CWD, CWDE, CDQ - konverze AL na AX, AX na DX:AX, AX na EAX, EAX na EDX:EAX
  • XADD, CMPXCHG - součet s výměnou, porovnání s výměnou

Logické operace

Nyní si ukažme, jak voláme logické operace:

  • AND, OR, XOR, NOT - logický součin, součet, exkluzivní součet, negace
  • TEST - podobné jako AND, ale pouze nastaví příznaky

Bitové operace

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Pracovat můžeme i s jednotlivými bity:

  • ROL, ROR, RCL, RCR - rotace vlevo/vpravo, přes příznak CF
  • SHL, SHR, SAL, SAR - posuny vlevo/vpravo, logické/aritmetické
  • SHLD, SHRD - posuny přes dva registry
  • BSF, BSR - hledání bitu dopředu/dozadu
  • BT, BTC, BTR, BTS - testování jednoho bitu, se změnou/vynulo­váním/nastave­ním

Práce s řetězci

Pomocí instrukcí můžeme pracovat s textovými řetězci:

  • REP MOVS - kopie řetězce
  • REPE CMPS - porovnání dvou řetězců
  • REPNE SCAS - vyhledání znaku v řetězci

Výpočty s reálnými čísly

S desetinnými čísly pracujeme těmito instrukcemi:

  • FLD, FILD - načtení reálného nebo celého čísla z paměti
  • FSTP, FISTP - uložení výsledku
  • FXCH - prohození dvou registrů
  • FLDZ, FLD1, FLDPI - konstanty 0, 1, Pi
  • FADD, FSUB, FMUL, FDIV, FDIVR, FSQRT - sčítání, odčítání, násobení, dělení, inverzní dělení, druhá odmocnina
  • FSIN, FCOS, FPTAN - goniometrické funkce
  • FABS, FCHS, FRNDINT - absolutní hodnota, změna znaménka, zaokrouhlení
  • FCOM, FCOMI, FTST - porovnání

MMX (Multi Media Extension)

MMX instrukce provádějí výpočty s 64-bitovými registry MM0MM7, z nichž každý může obsahovat několik celých čísel. Pracujeme tedy s několika čísly současně. Tyto registry jsme si již popsali v lekci Assembler - Registry procesoru.

Aritmetické instrukce mají suffixy D, W, B podle toho, jestli počítají se dvěma 32-bitovými čísly, čtyřmi 16-bitovými čísly, nebo osmi 8-bitovými čísly:

  • MOVD, MOVQ - přesuny
  • PADD, PADDS, PADDUS, PMADD, PMULH, PMULL, PSUB, PSUBS, PSUBUS - aritmetické operace
  • PAND, PANDN, POR, PXOR - logické operace
  • PCMPEQ, PCMPGT - porovnání
  • PACKSSDW, PACKSSWB, PACKUSWB, PUNPCKH, PUNPCKL - konverze
  • PSLL, PSRA, PSRL - bitové posuny
  • EMMS - přepnutí z MMX na x87 FPU

SSE (Streaming SIMD Extensions)

SSE instrukce provádějí výpočty se 128-bitovými registry XMM0XMM15. Na rozdíl od MMX mohou obsahovat nejen celá čísla, ale také reálná čísla.

Poslední písmeno názvu většiny instrukcí je D nebo S podle toho, jestli počítají se dvěma 64-bitovými reálnými čísly (Double) nebo se čtyřmi 32-bitovými reálnými čísly (Single). Předposlední písmeno je P nebo S podle toho, jestli se počítá s vektorem (Packed) nebo s jedinou hodnotou (Single):

  • MOVSS, MOVAPS, MOVUPS, MOVLPS, MOVHPS, MOVLHPS, MOVHLPS - přesuny
  • ADDSS, SUBSS, MULSS, DIVSS, RCPSS, MAXSS, MINSS, SQRTSS, RSQRTSS - aritmetické operace
  • CMPSS, COMISS, UCOMISS - porovnání
  • CVTSI2SS, CVTSS2SI, CVTTSS2SI - konverze
  • SHUFPS, UNPCKHPS, UNPCKLPS - zamíchání

AVX (Advanced Vector eXtensions)

AVX instrukce pracují s 256-bitovými registry YMM0-YMM15 nebo s 512-bitovými registry ZMM0-ZMM15. Instrukce jsou podobné jako u SSE, ale začínají písmenem V.

Privilegované instrukce

Tyto instrukce může používat jen operační systém:

  • STI, CLI - povolení a zakázání hardwarových přerušení
  • LIDT, LGDT, LLDT - nastavení adresy tabulky přerušení, globálních segmentů nebo lokálních segmentů
  • IN, OUT - vstup a výstup (komunikace s hardwarem)
  • HLT - zastavení programu
  • INVD - vymazání cache

Ostatní instrukce

Ukažme si ještě několik dalších užitečných instrukcí:

  • BOUND - test jestli je číslo v daném intervalu
  • BSWAP - konverze mezi little endian a big endian
  • CPUID - detekce typu procesoru
  • RDTSC - počítadlo cyklů (Time-Stamp Counter)
  • NOP - tato instrukce znamená no operation a nedělá vůbec nic

Nepoužívané instrukce

Následující instrukce jsou v procesoru jen kvůli kompatibilitě se staršími aplikacemi.

V dnešní době se prakticky nepoužívají, protože jsou pomalé.

Zde si pouze ukážeme, jakými jinými instrukcemi je můžeme nahradit:

  • ENTER - push rbp; mov rbp,rsp; sub rsp,n
  • LEAVE - mov rsp,rbp; pop rbp
  • LOOP - dec rcx; jnz label
  • LOOPZ - jnz label2; dec rcx; jnz label; label2:
  • LOOPNZ - jz label2; dec rcx; jnz label; label2:
  • XLATB - mov al,[rbx+rax]
  • LODSB - mov al,[rsi]; inc rsi
  • LODSW - mov ax,[rsi]; inc rsi
  • LODSD - mov eax,[rsi]; inc rsi
  • LODSQ - mov rax,[rsi]; inc rsi
  • STOSB - mov [rdi],al; inc rdi
  • STOSW - mov [rdi],ax; inc rdi
  • STOSD - mov [rdi],eax; inc rdi
  • STOSQ - mov [rdi],rax; inc rdi

BCD aritmetika

Zkratka BCD (Binary Coded Decimal) znamená binární kódování čísel v desítkové soustavě. Ve formátu packed jsou v každém bajtu dvě číslice. Ve formátu ASCII neboli unpacked je v každém bajtu pouze jedna číslice (buď hodnota 09, nebo hodnoty 30h39h, což v ASCII tabulce náleží znakům '0''9').

Tyto instrukce v dnešní době nikdo nepoužívá. Prvních šest z nich už dokonce ani nefungují v 64-bitových aplikacích (způsobují výjimku illegal instruction).

Instrukce jsou:

  • DAA (Decimal Adjust after Addition) - použije se po instrukci ADD ve formátu packed
  • DAS (Decimal Adjust after Subtraction) - použije se po instrukci SUB ve formátu packed
  • AAA (ASCII Adjust after Addition) - použije se po instrukci ADD ve formátu unpacked
  • AAS (ASCII Adjust after Subtraction) - použije se po instrukci SUB ve formátu unpacked
  • AAM (ASCII Adjust for Multiplication) - použije se po instrukci MUL ve formátu unpacked, ale je možné takto vynásobit pouze jednociferná čísla
  • AAD (ASCII Adjust before Division) - použije se před instrukcí DIV ve formátu unpacked, ale operandy musí být menší než 100
  • FBLD - z paměti načte 10 bajtů, které obsahují 18 číslic. V posledním bajtu je v nejvyšším bitu znaménko. Hodnotu uloží do FPU registru ST(0).
  • FBSTP - reálné číslo z registru ST(0) zaokrouhlí a do paměti zapíše 10 bajtů ve stejném formátu jako instrukce FBLD

V příští lekci, Funkce v MASM, budeme vytvářet funkce s parametry a lokálními proměnnými.


 

Předchozí článek
Assembler - Registry procesoru
Všechny články v sekci
Základy assembleru
Článek pro vás napsal Petr Laštovička
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje vývoji webových aplikací v ASP.NET a aplikací pro Windows v C++ nebo C#.
Aktivity (3)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!