Programátor při své činnosti potřebuje nejen přesuny dat. V každém programu jsou nutné i výpočty a to s běžnými daty, nebo s adresami. Ty se v assembleru provádějí jen s celými čísly. Operace s desetinnými čísly jsou zdlouhavé, i když jsou proveditelné pomocí určitých algoritmů. ASM86 pro ně ale nemá instrukce. Většina matematických operací se provádí s čísly v registrech nebo v paměti. Označení operandů je shodné jako při přesunech. Zároveň tyto instrukce nastavují indikátory registru F. Umožní tak větvit program. Informace o nastavovaných indikátorech najdeme v tabulce instrukcí (+).
Při tvorbě programu si musíme ujasnit, jestli chceme k cílovému místu přičíst 1, nebo jiné číslo. Podle toho volíme instrukci:
Příklady:
INC AX - přičti
k registru AX hodnotu 1
INC WORD PTR
[BX] - přičti k slovu na adrese určené DS:BX hodnotu 1
INC BYTE PTR
CS:[adresa] - přičti k slabice na adrese určené CS:adresa
(konstantní) 1
SEGES INC BYTE
[DI + 2] - přičti k slabice na adrese ES:DI + 2 hodnotu 1
ADD AX, BX - ke slovu v registru AX přičti
obsah registru BX (slovo)
ADD AH, 8 - k slabice v registru AH přičti
číslo 8}
SEGCS ADD DX, WORD
PTR [BX] - k registru DX přičti slovo na
adrese CS:BX
ADD promenna, 5 - k deklarované proměnné
přičti 5
ADD BYTE PTR
[SI], 30 - k slabice na adrese DS:SI přičti 30}
ADD BYTE PTR
ES:[BP], AL - k slabice na adrese ES:BP přičti obsah registru
AL
Pokud při těchto operacích dojde k přeplnění cíle, nastaví se registr OF do log. 1. Aby při odlaďování vašich programů nedošlo ke zbytečným hádkám s překladačem, uvědomte si, že zdroj i cíl musí mít stejný počet bitů (tzn. 8, nebo 16).
Instrukce sloužící k odčítání jsou zápisem operandů shodné s instrukcemi pro sčítání. Proto si uvedeme jen jejich seznam:
Přesto jsou zde specifické instrukce:
Instrukce CMP porovnává dvě čísla odečtením. Protože ale nedojde k jejich změně, použijeme tuto instrukci před větvením programu. Za CMP totiž většinou následu+jí instrukce skoku závislé na stavu příznaků registru F.
Příklad:
uses crt;
var a,b,s,r:integer;
begin
clrscr; {vymaž obrazovku}
write ('a=');
readln(a); {vstup hodnoty a}
write ('b=');
readln(b); {vstup hodnoty b}
asm {začátek bloku asm}
MOV
AX, a
{do AX vlož hodnotu proměnné a (z paměti)}
ADD
AX,b
{k AX přičti hodnotu proměnné b}
MOV
s, AX
{do proměnné s vlož součet z registru AX}
MOV
AX,a
{znovu naber a}
SUB
AX,b
{odečti od AX hodnotu b}
MOV
r,AX
{do proměnné r vlož rozdíl z registru AX}
INC
a
{k a přičti 1}
DEC
b
{od b odečti 1}
end; {konec bloku asm}
writeln ('a+b=',s,' a-b=',r);{vypiš obsahy proměnných}
writeln ('a+1=',a,' b-1=',b);
end.
Uvedený příklad ukazuje nejjednodušší použití instrukcí ADD, SUB, INC, DEC. Všimněte si, že se zápisy adres proměnných si nemusí programátor ani moc lámat hlavu. V tom mu totiž pomáhá překladač Pascalu.
I když programátoři neradi používají instrukce násobení a dělení pro jejich dlouhou dobu provádění (na procesoru 8086, u jiných procesorů je už rychlé), ASM86 je má. Někdy dokonce neexistuje jiná možnost než je použít. I tyto operace jsou definovány jen na celých číslech. Rozlišujeme také, jestli je provádíme se znaménkem, nebo bez znaménka.
POZOR!, o kolikabitové násobení se jedná určuje označení místa zdroje.
Tato operace je jednou z nejzdlouhavějších. Její provádění trvá (na 8086) až 190 period hodin (sčítání trvá kolem 3 period). Jeho výhodou je ale to, že je možné zjistit jak výsledek po celočíselném dělení (DIV), tak i zbytek po celočíselném dělení (MOD). A to všechno jen jednou instrukcí.
Příklad:
uses crt;
var a,b,d,z:byte;
s:word;
begin
clrscr;
write ('a=');
readln (a);
write ('b=');
readln (b);
asm
MOV
AL,a {do AL
vlož hodnotu a}
MUL
b
{vynásob hodnotou b (v paměti)}
MOV
s,AX {do
proměnné s vlož součin z registru AX}
MOV
AH,0 {nuluj AH
(číslo je jen 8 bitové)}
MOV
AL,a {do AL
vlož hodnotu a}
DIV
b
{vyděl proměnnou b}
MOV
d,AL
{výsledek vlož do proměnné d}
MOV
z,AH {zbytek
po dělení vlož do proměnné z}
end;
writeln ('a*b=',s);
writeln ('a div b=',d,' a mod b=',z);
readkey;
end.
Často potřebujeme opravit šestnáctibitové číslo na osmibitové a naopak. Při této změně může ale dojít ke ztrátě informace v případě úbytku bitů. Převod čísel bez znaménka provedeme nejjednodušeji využitím půlení registrů.
var b:byte;
w:word;
begin
b:=10;
asm
MOV
AL,
b {do AL osm bitů z proměnné b}
MOV
AH, 0
{nuluj AH}
MOV
w, AX
{do proměnné w vlož všech šestnáct bitů}
end;
end.
Čísla v BCD kódu mohou být uložena v těchto formátech: