Učebnice Assembleru 86

Aritmetické instrukce

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í (+).

Sčítání

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).

Odčítání

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.

Násobení

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.

Dělení

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.

Změna počtu bitů

Č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ů.

Práce s čísly v kódu BCD

Čísla v BCD kódu mohou být uložena v těchto formátech:

Směr