Kurs Assembleru - Celočíselné dělení

Raster/C.P.U., 2004

Při programování v Assembleru se dříve či později setkáte s potřebou provádět operaci dělení. Na složitost řešení tohoto problému má zásadní vliv, zda dělitel je vždy stejná (konstantní) hodnota či zda může nabývat různých hodnot, dále pak záleží na konkrétní hodnotě dělitele.

  1. Dělení konstantní hodnotou kdy dělitel je mocnina dvou

    Zde je situace nejjednodušší, neboť pro takové dělení můžeme použít přímo instrukce posunu:

       LDA dělenec
       LSR @        ;/2
       LSR @        ;/2/2 => /4
       LSR @        ;/2/2/2 => /8
       LSR @        ;/2/2/2/2 => /16
    ;atd.

    Pokud by bylo posunů příliš mnoho, lze v kritických případech výpočet urychlit použitím rotace na opačnou stranu. Přitom je nutno si uvědomit, že instrukce pro rotaci se provádí přes Carry bit.

    Například mějme dělení hodnotou 64, pro kterou by bylo třeba provést 6 posunů vpravo. Máme však i tuto možnost:

       LDA dělenec  ;76543210 C=_
       ROL @        ;6543210_ C=7bit
       ROL @        ;543210_7 C=6bit
       ROL @        ;43210_76 C=5bit
       AND #$03     ;------76

    Vzhledem k tomu, že instrukce AND #$03 potřebuje 2 cykly stejně jako posun, úspora je v tomto případě celkem 4 cykly, což se může zdát zanedbatelné. Ovšem provádíte-li dělení velkého množství čísel (stovek či tisíců), je každý uspořený takt dobrý.

  2. Dělitel není konstantní nebo není mocnina dvou

    Zde doporučuji použít rutinu uvedenou v samostatném souboru DIVIDE.ASM. Dle velikosti dělence a dělitele (BYTE - tj. 8bitový rozsah, nebo WORD - tj. 16bitový rozsah) jsou tam dvě rutiny nazvané deleni_wbbb nebo deleni_wwww. Způsob jejich použití je názorně demonstrován též v samostatném příkladu PRIKLDIV.ASM. Syntaxe je QuickAsm.

  3. Tipy a triky

    V případě potřeby rychlého dělení konstantní hodnotou lze také využít triku s tabulkou předpočítaných výsledků. Řekněme, že dělenec je 8bitové číslo a chceme jej dělit třeba hodnotou 27. Pak si předpřipravíme tabulku dlouhou 256 bytů, ve které vždy použijeme dělenec jako index a přímo získáme výsledek.

    Tabulka předpočítaných výsledků:

    DELENI27
       dta 0,0,...,0 ;27krát hodnota 0
       dta 1,1,...,1 ;27krát hodnota 1
       ...
       dta 9,9,...,9 ;27krát hodnota 9
       dta 10,10,...,10 ;13krát hodnota 10

    Pak stačí vždy provést:

       LDY dělenec
       LDA DELENI27,Y
    

    Poznámka: Samozřejmě není problém tabulku výsledků upravit libovolným způsobem - například tak, abychom vždy obdrželi výsledek zaokrouhlený na celá čísla.