Lekce 8 - Assembler - Instrukce pro práci s čísly
V minulé lekci, Assembler - Datové typy a proměnné, jsme si řekli o datových typech, které se používají při programování v Assembleru, a o práci s řetězci.
V dnešní lekci se budeme věnovat instrukcím pro výpočty s celými čísly.
Aritmetické operace
Asi není nutné zmiňovat, že aritmetické instrukce pracují s hodnotou v registru nebo proměnné jako s jedním číslem. Počítají tedy podobně, jako jsme to dělali my třeba ve škole.
Všechny instrukce se dají použít v kombinaci s 8-bitovými, 16-bitovými, 32-bitovými nebo 64-bitovými registry. Ale 64-bitové registry není možné používat v 16-bitových ani v 32-bitových aplikacích.
Instrukce INC
a DEC
Instrukce INC
(INCrement) a DEC
(DECrement)
slouží k přičtení nebo k odečtení hodnoty 1
v registru, či v námi vytvořené proměnné. Instrukce mají pouze jeden
operand (jsou tedy unární).
Příklad
Jako jednoduchý příklad si můžeme uvést kód:
xor ax, ax ; Vynuluj registr AX inc ax ; Přičti k registru AX hodnotu 1 mov bx, 1 ; Přesuň hodnotu 1 do registru BX dec bx ; Odečti z registru BX hodnotu 1 inc y ; Přičti 1 k proměnné y (kompilátor MASM) inc word [y] ; Přičti 1 k proměnné y (kompilátor NASM) dec i ; Odečti 1 od proměnné i (kompilátor MASM) dec word [i] ; Odečti 1 od proměnné i (kompilátor NASM)
U kompilátoru NASM se musí před proměnnou psát její typ. Kompilátor MASM je chytřejší a typ si zjistí z definice proměnné.
Akumulační registr AX
se často používá pro vstupy/výstupy
a aritmetické operace.
Všimněte si vynulování registru pomocí instrukce
XOR
.
Instrukce ADD
a SUB
Oproti instrukcím INC
a DEC
mají instrukce
ADD
(ADD) a SUB
(SUBtract) dva operandy. Prvním
operandem je registr nebo námi vytvořená proměnná a druhým je registr,
proměnná nebo hodnota, kterou chceme přičíst, nebo kterou
chceme odečíst. Není povoleno, aby oba dva operandy byly
proměnné. Pokud chceme k jedné proměnné přičíst hodnotu jiné
proměnné, musíme si jednu z proměnných nejdříve načíst do registru.
Příklad
Ukažme si příklad:
xor ax, ax ; Vynuluj registr AX add ax, 5 ; Přičti k registru AX hodnotu 5 mov bx, 5 ; Přesuň hodnotu 5 do registru BX sub bx, 5 ; Odečti z registru BX hodnotu 5 add bx,cx ; Přičti registr CX k registru BX add dx,m ; Přičti proměnnou m k registru DX (kompilátor MASM) add dx,[m] ; Přičti proměnnou m k registru DX (kompilátor NASM) add j,ax ; Přičti registr AX k proměnné j (kompilátor MASM) add [j],ax ; Přičti registr AX k proměnné j (kompilátor NASM) add i,5 ; Přičti 5 k proměnné i (kompilátor MASM) add word [i],5 ; Přičti 5 k proměnné i (kompilátor NASM)
Další aritmetické instrukce (ADC
,
SBB
, MUL
, DIV
, IMUL
,
IDIV
) zatím vynecháme.
Logické operace
Nyní přejdeme k instrukcím pracujícím s čísly na úrovni jednotlivých bitů, tedy nul a jedniček, ze kterých jsou poskládaná. Použít můžeme zas registry nebo námi vytvořenou proměnnou.
Instrukce AND
Instrukce AND
má dva parametry, mezi kterými provede
logický součin. Výsledek se ukládá do prvního
operandu.
Tabulka hodnot
Hodnoty na jednotlivých bitech se zpracují následujícím způsobem:
A | B | Y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
Jinými slovy, jednička bude na výsledném bitu jen tehdy, pokud ji měla obě čísla na těchto vstupních bitech.
Příklad
Ukažme si příklad:
mov al, 1100b ; Do registru AL přesuň hodnotu 1100b (sufix b znamená, že číslo je ve dvojkové soustavě) mov bl, 1010b ; Do registru BL přesuň hodnotu 1010b and al, bl ; Proveď logický součin - AL = 1000b
Instrukce OR
Instrukce pro logický součet - OR
má opět
dva operandy. Výsledek se ukládá do prvního operandu.
Tabulka hodnot
Níže je vidět tabulka hodnot logického součtu:
A | B | Y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
Pokud je alespoň jeden z bitů na dané pozici 1
, bude ve
výsledném čísle tento bit také 1
.
Příklad
Zkusme si to:
mov al, 1100b ; Do registru AL přesuň hodnotu 1100b mov bl, 1010b ; Do registru BL přesuň hodnotu 1010b or al, bl ; Proveď logický součet - AL = 1110b
Instrukce XOR
Instrukce XOR
má dva operandy, mezi kterými provede
logickou non-ekvivalenci - vrátí 1
pouze tehdy,
kdy každý operand nabývá unikátní hodnoty - a výsledek uloží opět do
prvního operandu. Instrukci můžeme využít k vynulování registrů, jak
jsme si již ukazovali výše. Registr se vynuluje, protože oba operandy mají
stejnou hodnotu, a tudíž je navrácena 0
.
Tabulka hodnot
Následuje tabulka logické non-ekvivalence:
A | B | Y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
Stejně jako u OR
, pokud je alespoň jeden z bitů na dané
pozici 1
, bude ve výsledném čísle tento bit také
1
. Pokud jsou ovšem oba 1
, výsledek je
0
.
Příklad
Instrukci si vyzkoušejme:
mov al, 1100b ; Do registru AL přesuň hodnotu 1100b mov bl, 1010b ; Do registru BL přesuň hodnotu 1010b xor al, bl ; Proveď logickou non-ekvivalenci - AL = 0110b xor al, al ; Vynuluj registr AL / Proveď logickou non-ekvivalenci - AL = 0 (1 ⊕ 1)
Instrukce NEG
Jak už napovídá název, instrukce NEG
(NEGation) slouží k
negování (invertování hodnoty z kladné na zápornou a
naopak, tedy jako znaménko -
). Funguje téměř stejně jako
instrukce NOT
, s tím rozdílem, že po invertování všech bitů
přičte jedničku (možná ji znáte pod pojmem "dvojkový doplněk").
Instrukce má jen jeden operand a tím je registr nebo námi vytvořená proměnná.
Příklad
Opět si ukažme příklad:
mov al, 00000010b ; Do registru AL přesuň hodnotu 2 neg al ; Proveď negaci - AL = -2 (00000010⌝ + 00000001 = 11111110)
Instrukce NOT
Instrukce NOT
má pouze jediný operand a stejně jako instrukce
NEG
neguje (invertuje jednotlivé bity). Použít
můžeme registr nebo námi vytvořenou proměnnou. Instrukci NOT
se často říká "jedničkový doplněk".
Tabulka logické negace:
A | Y |
---|---|
0 | 1 |
1 | 0 |
Příklad
Zkusme si NOT
:
mov al, 00000010b ; Přesuň do registru AL hodnotu 2 not al ; Proveď negaci - AL = -3 (00000010⌝ = 11111101)
Tento článek byl spíše teoretický, ale znát tyto instrukce je nezbytné při programování v Assembleru. Vývoji zdar!
V příští lekci, Assembler - Další instrukce pro práci s čísly, se naučíme násobení, dělení a také sčítání a odčítání velkých čísel.