| FORTH | |
|||||
| Úvod | Výukové lekce | 01 02 03 | ||||
|
Lekce 2 - Aritmetické operace
Mezi
základní aritmetické operace
patří
sčítání,
odčítání,
násobení, dělení. Operandy jsou
16-bitová
nebo 32-bitová čísla, se znaménkem
nebo bez.
16-bitové číslo bez znaménka má rozsah 0 až 65535 (0 až FFFFh). Se znaménkem 0 až 32767 (0 až 7FFFh), záporné -32768 až -1 (ukládá se do paměti jako 8000h až FFFFh). Záporné číslo se vytvoří dvojkovým doplňkem - znegují se bity a přičte se 1. Např. -3 je FFFCh+1=FFFDh. 32-bitové číslo bez znaménka má rozsah 0 až 4 294 967 295 (0 až FFFF FFFFh). Se znaménkem 0 až 2 147 483 647 (0 až 7FFF FFFFh), záporné -2 147 483 648 až -1 (ukládá se do paměti jako 8000 0000h až FFFF FFFFh). Při násobení a dělení je třeba odlišovat, jestli počítáme se znaménkem nebo bez. Absolutní hodnoty se zpracují zvlášť a znaménka také zvlášť. Příklad 3:
Na
následujícím Obr. 3 jsou
prakticky
vyzkoušeny některé
aritmetické operace v F-PC
.
![]() Obr. 3 |
|||
|
+
|
(x1
x2
-- x3) stav zásobníku před a po operaci, x1 - libovolné 16b číslo |
plus | x1+x2=x3 sečte
dvě 16-bitová čísla, se
znaménkem nebo bez, výsledek je
16-bitové číslo. x1 a x2 se vyčtou ze zásobníku, na TOS se uloží x3. Např. -1 3 + . provede -1+3, zobrazí 2. Záporné číslo -1 je vytvořeno dvojkovým doplňkem (znegovat bity čísla 1 a přičíst 1), tedy FFFEh+1=FFFFh. Přičtením 3 dostáváme výsledek 2, přetečení se ignoruje. Např. 10000 30000 + . zobrazí -25536. Výsledek je větší než 32767, takže je číslo zobrazeno jako záporné. Pokud místo tečky použijeme U. , pak se výsledek zobrazí bez znaménka, tedy 40000. U čísel bez znaménka je maximální hodnota 65535. ![]() |
| M+ | (d1
n -- d2) (x1 x2 x3 -- x4 x5) d1-dvojnásobný rozsah, 32b |
m-plus | d1+n=d2
přičte 16-bitové číslo k 32-bitovému,
výsledek je
32-bitové číslo. x1 až x3 se vyčtou ze zásobníku, na TOS je vyšších 16b, na NOS nižších 16b. Např. 2 1 30000 M+ D. provede (2+1*65536) + 30000, zobrazí 95538. Na TOS je 1, na NOS je 30002. Když místo D. napíšeme U. U. zobrazí se 1 30002 . ![]() |
| D+ | (d1
d2 -- d3) (x1 x2 x3 x4 -- x5 x6) d1 - dvojnásobný rozsah, 32b |
d-plus | d1+d2=d3
sečte dvě
32-bitová čísla,
se
znaménkem nebo bez, výsledek je
32-bitové číslo. x1 až x4 se vyčtou ze zásobníku, na TOS je vyšších 16b, na NOS nižších 16b. Např. -5 -1 3 0 D+ D. provede -5+3, zobrazí -2. Nuly doplňují vyšších 16 bitů. Záporné číslo -5 je vytvořeno dvojkovým doplňkem (znegovat 5 a přičíst 1), tedy FFFF FFFAh+1=FFFF FFFBh. Přičtením 3 dostáváme výsledek -2 (FFFF FFFEh). Např. 2 1 30000 0 D+ D. provede (2+1*65536) + (30000+0*65536), zobrazí 95538. Na TOS je 1, na NOS je 30002. Když místo D. napíšeme U. U. zobrazí se 1 30002 . |
| 1+ | (x1 -- x2) | one-plus | x1+1=x2
přičte k 16-bitovému číslu na
TOS číslo
jedna, výsledek je 16-bitové číslo. Na TOS je číslo zvětšené o 1. Např. -3 1+ . zobrazí -2 . Na TOS přečte -3, přičte 1 a uloží výsledek -2 na TOS. ![]() |
| +! | (x1 a-addr -- ) | plus-store | (a-addr)+1=>a-addr
přičte k obsahu adresy číslo x1. Na TOS je adresa a-addr, přečte se její obsah, přičte se x1 a výsledek se uloží zpět na adresu a-addr. Slouží k přičtení čísla k proměnné (ta dává na TOS adresu, ne svoji hodnotu). x1 a-adr jsme vyčetli ze zásobníku. Např. 6 BASE +! zvýší obsah proměnné BASE o 6 (z původních 10 na 16). Tímto se přepnete do šestnáctkové soustavy (příkazem DECIMAL zpátky do desítkové), viz. níže. ![]() |
| - | (x1 x2 -- x3) | minus | x1-x2=x3 odečte dvě
16-bitová čísla,
se
znaménkem nebo bez, výsledek je
16-bitové číslo. x1 a x2 se vyčtou ze zásobníku, provede se NOS-TOS, na TOS se uloží x3. Např. -1 3 - . provede -1-3, zobrazí se výsledek -4. ![]() |
| D- | (d1
d2 -- d3) (x1 x2 x3 x4 -- x5 x6) |
d-minus | d1-d2=d3
odečte dvě
32-bitová čísla,
se
znaménkem nebo bez, výsledek je
32-bitové číslo. x1 až x4 se vyčtou ze zásobníku, na TOS je vyšších 16b, na NOS nižších 16b. Např. 2 1 30000 0 D- D. od čísla (2+1*65536) odečte (30000+0*65536), výsledek je 35538. ![]() |
| 1- | (x1 -- x2) | one-minus | x1-1=x2
odečte od 16-bitového čísla na
TOS
číslo jedna, výsledek je
16-bitové
číslo. Na TOS je číslo zmenšené o 1. Např. -3 1- . zobrazí -4 . Na TOS vezme -3, odečte 1 a uloží výsledek -4 na TOS. ![]() |
| * | (n1
n2 -- n3) n1-16b se znaménkem |
star | n1*n2=n3
vynásobí dvě 16-bitová
čísla
se
znaménkem, výsledek je
16-bitové číslo. n1 a n2 se vyčtou ze zásobníku, na TOS se uloží n3. Např. 2 -3 * . provede 2*(-3), zobrazí výsledek -6 . Např. 200 -300 * . provede 200*(-300), zobrazí 5536. Výsledkem násobení 200*300 je 60000, čemuž odpovídá číslo -5536, pro 200*(-300) tedy 5536. ![]() |
| M* | (n1 n2 -- d1) | m-star | n1*n2=d1
vynásobí dvě 16-bitová
čísla
se
znaménkem, výsledek je 32-bitové
číslo. n1 a n2 se vyčtou ze zásobníku, na TOS se uloží vyšších 16b d1, na NOS nižžších 16b. Např. 200 -3000 M* D. provede 200*(-3000), zobrazí výsledek -600000. ![]() |
| UM* | (u1
u2 -- ud1) u1-16b bez znaménka ud1-32b bez znaménka |
u-m-star | u1*u2=ud1
vynásobí dvě 16-bitová
čísla
bez
znaménka, výsledek je 32-bitové
číslo. u1 a u2 se vyčtou ze zásobníku, na TOS se uloží vyšších 16b ud1, na NOS nižžších 16b. Např. 200 3000 UM* D. provede 200*3000, zobrazí výsledek 600000. Např. 200 -3000 UM* D. provede 200*62536, zobrazí výsledek 12507200 (-3000 bere jako 62536, ne 3000 a minus). ![]() |
| / | (n1
n2 -- n3) |
slash | n1/n2=n3
vydělí dvě 16-bitová
čísla
se
znaménkem, výsledek
je 16-bitové číslo. n1 a n2 se vyčtou ze zásobníku, provede se NOS/TOS, na TOS se uloží n3, zbytek není. Např. 100 3 / . provede 100/3, zobrazí výsledek 33. Zbytek se do zásobníku neukládá. Např. 100 -3 / . provede 100/(-3), zobrazí výsledek -33 (-34 F-PC, Win32Forth). ![]() |
| MOD | (n1 n2 -- n3) | mod | n1 mod n2=n3
zbytek po dělení dvou 16b čísel
se
znaménkem, výsledek
je 16-bitové číslo. n1 a n2 se vyčtou ze zásobníku, provede se NOS mod TOS, na TOS se uloží zbytek n3. Např. 100 3 MOD . provede 100/3, zobrazí výsledek 1 (100/3=33+1) Např. 100 -3 MOD . provede 100/(-3), zobrazí výsledek 1 (-2 F-PC, Win32Forth). ![]() |
| /MOD | (n1 n2 -- n3 n4) | slash-mod | n1/n2=n3 + n4
vydělí dvě 16-bitová
čísla
se
znaménkem, výsledek je 2x 16-bitové
číslo. n1 a n2 se vyčtou ze zásobníku, provede se NOS/TOS, na TOS se uloží podíl n4, na NOS zbytek n3. Např. 100 3 /MOD . . provede 100/3, zobrazí výsledek 33 1. Např. 100 -3 /MOD . . provede 100/(-3), zobrazí výsledek -33 1 (-34 -2 F-PC, Win32Forth). ![]() |
| UM/MOD | (ud1
u1 -- u2 u3) u1-16b bez znaménka ud1-32b bez znaménka |
u-m-slash-mod | ud1/u1=u2 + u3
vydělí 32-bitové číslo 16-bitovým
číslem,
bez
znamének, výsledek je 2x 16-bitové
číslo. ud1 a u1 se vyčtou ze zásobníku, provede se NOS/TOS, na TOS se uloží podíl u3, na NOS zbytek u2. Např. 100 0 3 UM/MOD . . provede 100/3, zobrazí výsledek 33 1. Např. 100 1 3 UM/MOD . . provede (100+1*65536)/3, zobrazí výsledek 21878 2. ![]() |
| */ | (n1 n2 n3 -- n4) | star-slash | (n1*n2)/n3
vynásobí dvě 16-bitová
čísla
se
znaménkem, výsledek je 32-bitové
číslo, to vydělí 16-bitovým
číslem, výsledek
je 16-bitové číslo. n1 n2 n3 se vyčtou ze zásobníku, na TOS se uloží podíl n4. Např. 33 200 100 */ . provede 33*200/100, zobrazí výsledek 66, což je 33% z 200. ![]() |
| */MOD | (n1 n2 n3 -- n4 n5) | star-slash-mod | (n1*n2)/n3
vynásobí dvě 16-bitová
čísla
se
znaménkem, výsledek je 32-bitové
číslo, to vydělí 16-bitovým
číslem, výsledek
je 2x 16-bitové číslo. n1 n2 n3 se vyčtou ze zásobníku, na TOS se uloží podíl n5, na NOS zbytek n4. Např. 33 201 100 */MOD . . provede 33*201/100, zobrazí výsledek 66 33. ![]() |
| M*/ | (d1
n1 +n2 -- d2) +n2-nenulové kladné |
m-star-slash | (d1*n1)/n2
vynásobí 32-bitové
číslo 16-bitovým,
se
znaménky, výsledek je 48-bitové
číslo, to vydělí 16-bitovým
číslem, výsledek
je 32-bitové číslo. d1 n1 n2 se vyčtou ze zásobníku, na TOS se uloží d2. Např. 60000 33 100 M*/ . provede 60000*33/100, zobrazí výsledek 19600 (Win32Forth - 32-bitové výpočty). ![]() |
| 2* | (x1 -- x2) | two-star | <--0
posune 16b o jeden bit vlevo, nejnižší
bit je nula, hodnota se zvětší na
dvojnásobek. Na TOS je 16-bitové číslo. Např. -15000 2* . zobrazí výsledek -30000. Např. 32767 2* . přesun do záporných čísel, nejnižší bit doplní nulou, zobrazí -2. ![]() |
| D2* | (d1 -- d2) | d-two-star | <--0
posune 32b o jeden bit vlevo, nejnižší
bit je nula, hodnota je dvojnásobná. Na TOS, NOS je 32-bitové číslo. Např. -15000 -1 D2* D. (-1 je vyšších 16b) zobrazí výsledek -30000. Např. 32767 1 D2* D. provede (32767+1*65536)*2, zobrazí výsledek 196606. ![]() |
| 2/ | (x1 -- x2) | two-slash | s-->
posune 16b o jeden bit vpravo,
nejvyšší bit
zůstává, hodnota je poloviční. Na TOS je 16-bitové číslo. Např. -15000 2/ . zobrazí výsledek -7500. Např. 40000 2/ U. zkopíruje bit 15, proto zobrazí 52768 (20000+32768). ![]() |
| D2/ | (d1 -- d2) | d-two-slash | s-->
posune 32b o jeden bit vpravo,
nejvyšší bit
zůstává, hodnota je poloviční. Na TOS, NOS je 32-bitové číslo. Např. -15000 -1 D2/ D. (-1 je vyšších 16b) zobrazí výsledek -7500. Např. 40000 0 D2/ D. zobrazí 20000 (bit 31 je 0). ![]() |
| ABS | (n
-- u) n-16b se znaménkem u-16b bez znaménka |
abs | | n |
absolutní hodnota z 16-bitového čísla
se znaménkem (odstraní minus). Na TOS je 16-bitové číslo, u záporného čísla provedl dvojkový doplněk. Např. -2 ABS . zobrazí 2. ![]() |
| DABS | (d
-- ud) d-32b se znaménkem ud-32b bez znaménka |
d-abs | | d |
absolutní hodnota z 32-bitového čísla
se znaménkem (odstraní minus). Na TOS, NOS je 32-bitové číslo. Např. -2 -1 DABS D. zobrazí 2. ![]() |
| NEGATE | (n1 -- n2) | negate | Negace - změna
znaménka +/- , dvojkový doplněk (negace bitů a přičte 1). Na TOS je 16-bitové číslo. Např. -2 NEGATE . 3 NEGATE . zobrazí 2 -3. ![]() |
| DNEGATE | (d1 -- d2) | d-negate | Negace - změna
znaménka +/- , dvojkový doplněk. Na TOS, NOS je 32-bitové číslo. Např. -2 0 NEGATE D. 3 0 NEGATE D. zobrazí 2 -3. ![]() |
| BASE | ( -- a-addr) | base | Základ
číselné soustavy - proměnná
určující, v jaké soustavě se
zobrazují čísla, desítková,
hexadecimální, binární,
atd. Na TOS se uloží adresa proměnné. Např. 2 BASE ! do proměnné BASE uloží 2, nastaví binární soustavu. Např. 1001 0011 * . zobrazí 11011 (9*3=27) ![]() |
| DECIMAL | ( -- ) | decimal | Desítková soustava
- čísla budou zobrazována v
desítkové soustavě. Např. HEX 1A 1B DECIMAL . . zobrazí 27 26. |
| HEX | ( -- ) | hex | Hexadecimální
soustava - čísla budou zobrazována v
hexadecimální soustavě. Např. DECIMAL 26 27 HEX . . zobrazí 1B 1A. |
| ____________________________________________________________________________________________________________________ 22.11.2007 -
Luboš Pěkný, čerpáno z
X3J14 dpANS-6.
|
|||