RPN32 - Instrukční sada



Instrukční sada  •  Seznam instrukcí  •  Funkce API  •  Header  •  Příklady  •  Download




Úvod

Dříve než se oko čtenářovo pohrouží do seznamu všech dostupných RPN instrukcí, je zde několik vysvětlujících řádků. Seznam by patrně byl srozumitelný i bez těchto vysvětlivek, ale nebude ke škodě, bude-li tento popis úplný a konzistentní.

Pozn.: I když se tato dokumentace na řadě míst odvolává na předchozí řešení interpreteru RPN instrukcí RPNPROC, bude tento popis instrukční sady zhusta obsahovat informace stejné (někdy doslovně převzaté) jako stejnojmenná kapitola RPNPROC. Není to známka roztržitosti autorovy (natož známka punku :-), ale snaha o systematičnost. Pouhé odkazy ve specifických případech by srozumitelnost tohoto textu zbytečně snižovaly.


Názvosloví

Sloupce Mnemonický tvar a Popis tabulky seznamu instrukcí obsahují různé zástupné symboly zjednodušující další text. Zde je jejich výčet:

x y z t     Hodnoty ve stejnojmenných registrech RPN stacku.
l     Hodnota v registru LASTx (je to malé L).
s     Jméno kteréhokoliv registru RPN stacku včetně registru LASTx (tedy cokoliv ze sortimentu X Y Z T L).
r     Číslo paměťového registru (obecného i lokálního) v rozsahu 0..32767.
b     Číslo návěští (label) v rozsahu 0..32767.
f     Číslo flag v rozsahu 0..31.
n     Číselný operand direktiv.
F     Znak „F“ je identifikátorem registru flags. Použitelný je pouze u instrukcí STO F a RCL F.

Jména registrů X Y Z T L nebo čísla paměťových registrů r mohou být předznamenány znakem indirekce @. Nepřímou adresaci (indirekci) obsahu paměťových registrů pěkně ilustruje (na typických instrukcích) následující příklad:

Obsah paměťového
registru č. 17
Instrukce
prováděná ekvivalentní
4 RCL @17 RCL 4
GTO @17 GTO 4
-5 RCL @17 RCL .4

Je důležité si uvědomit, že nezáporný obsah paměťového registru č. 17 (zde konkrétně 4) rozlišuje pokaždé jiný objekt. Poprvé paměťový registr, podruhé návěští. Oba objekty identifikované číslem 4 nemají žádnou souvislost. Liší se významově i výskytem v paměti počítače.


Registr LASTx

Tento pátý registr čtyřúrovňového RPN stacku uchovává hodnotu řečenou Last X. Tím „posledním iks“ je obsah X-registru RPN stacku před provedením instrukcí opatřených značkou ve sloupci Last X tabulky seznamu instrukcí. Úžasná vlastnost, jejíž přednosti se těžko popisují - to se musí zažít!

(Slovní spojení „pátý registr čtyřúrovňového RPN stacku“ připomíná starou známou vojenskou průpovídku: „Samopal má čtyři části. Jsou to tyto tři: pažba a hlaveň“ :-)


Manipulace s RPN stackem

S registry RPN stacku lze (nebo spíše je nutno) provádět některé základní operace měnící obsahy registrů RPN stacku. Těmito operacemi/manipulacemi jsou myšleny různé přesuny, náhrady případně kopie hodnot v registrech RPN stacku. Z následujících schemat/tabulek je pohyb hodnot v registrech RPN stacku zcela zřejmý. Přesto jsou (v rámci zachování čistoty stylu :-) doprovázeny příslušnými slovními popisy.

Registry mají ve všech případech manipulací stejné výchozí hodnoty: t=5, z=4, y=3 a x=2.

 Šrafovaná pole  vyznačují registry, jejichž hodnoty se při manipulaci nemění resp. nepoužívají.

Swap

Registr Před...po
T 5 5
Z 4 4
Y 3 2
X 2 3
Prostá záměna obsahů X- a Y-registru RPN stacku.

Drop

Registr Před...po
T 5 5
Z 4 5
Y 3 4
X 2 3
RPN stack po provedení této operace poklesne o jednu pozici dolů. Registr z vrcholu RPN stacku - tedy T-registr - je tím, který se v tomto případě nemění a jehož obsah je navíc zkopírován do Z-registru. Hodnota x je po uskutečněné operaci nenávratně ztracena.

V hlavičce tabulky seznamu instrukcí je sloupec Drop. Od ostatních instrukcí odlišuje ty, které ukládají výsledek své činnosti do Y-registru. Ten se po provedení operace Drop dostane tam, kam patří: do X-registru.

Lift

Registr Před...po
T 5 4
Z 4 3
Y 3 2
X 2 2
Lift, neboli zdvih, skutečně zdvihne čtveřici hodnot směrem k pomyslnému vrcholu. X-registr nedozná změny, navíc je „rozmnožen“ do Y-registru. Naopak hodnota t (obsah T-registru) je po uskutečněné operaci nenávratně ztracena.

I tato operace má své stejnojmenné zastoupení v hlavičce tabulky seznamu instrukcí. Je to sloupec Lift. Má význam vnitřního příznaku, který některé instrukce nastavují. Při vkládání nové číselné hodnoty do RPN stacku je stav tohoto příznaku zohledněn eventuálním automatickým posunutím RPN stacku směrem vzhůru před vložení nové hodnoty do jeho X-registru (v originále: The automatic lifting of the stack's contents).

Roll down

Registr Před...po
T 5 2
Z 4 5
Y 3 4
X 2 3
Manipulaci Roll up lze nazvat nejen „bezeztrátovou“, ale také „bezpřírůstkovou“. Všechny hodnoty v registrech si pouze vymění svoje „bydliště“ ve směru t→z→y→x→t.

Roll up

Registr Před...po
T 5 4
Z 4 3
Y 3 2
X 2 5
Stejná situace jako v předchozím případě, pouze směr je opačný: x→y→z→t→x.


Větvení programu

Změna v pořadí prováděných instrukcí je u většiny počítačů (i kalkulátorů) řešena takřka stejným postupem. Je-li splněna/nesplněna nějaká podmínka (hodnoty registrů/proměnných v určitých mezích, stavy různých bitů/příznaků, ...) je typicky následující instrukce provedena/neprovedena. Následující instrukcí je často instrukce skoku, ale není to podmínkou. Podmíněnou instrukcí může být cokoliv. (Odlišná situace je u kalkulátorů TI-58/59. U těchto strojů je kód instrukce, která následuje za instrukcí testu, chápán jako číslo návěští pro přenesení programového toku. Kalkulátory z produkce HP, které jsou předobrazem tohoto interpreteru, toto omezení nemají.)

Koncepce test-přeskok je vlastní i této programové vrstvě. Pro větvení RPN programu jsou k dispozici tři skupiny instrukcí pro test splnění podmínky:

1. Porovnání x s nulou resp. s y x==0?   x!=0?   x<0?   x<0=?   x>0?   x>=0?
x==y?   x!=y?   x<y?   x<=y?   x>y?   x>=y?
2. Testy stavů bitů y a flags BS?   BS?C   BC?   BC?C
FS?   FS?C   FC?   FC?C
3. Realizace programové smyčky ISG   DSE
ISZ   DSZ

Pozn.: Instrukce pro realizaci programové smyčky vyhodnocují podmínku obráceně.


Loop Control-number

Programový blok, který je prováděn opakovaně tak dlouho, dokud hodnota nějaké proměnné nedosáhne požadovanou hodnotu, ilustruje konstrukce známá z jazyka BASIC:

FOR variable=counter TO final STEP interval
 :
 :
NEXT variable
Proměnná variable s počáteční hodnotou counter je inkrementována o interval tak dlouho, dokud se nerovná (a nepřevýší) hodnotu final. Mezi příkazy FOR a NEXT je (místo dvojteček) opakovaně prováděný programový blok.

Trojice hodnot z příkazu FOR je ve stejném významu se stejnými názvy použita jako základ realizace programové smyčky i v tomto interpreteru RPN instrukcí. Sdruženy do 32-bitové hodnoty jsou obsahem kteréhokoliv z paměťových registrů a operují s nimi instrukce DSE (decrement; skip if less than or equal to) a ISG (increment; skip if greater than).

1. Counter Aktuální/počáteční hodnota. Je měněna přírůstkem resp. úbytkem interval.
2. Final Hodnota, se kterou je v jednotlivých iteracích porovnávána okamžitá hodnota counter pro stanovení podmínky pro ukončení činnosti programové smyčky. (Hodnota se činností instrukce nemění.)
3. Interval Přírůstek resp. úbytek. (Hodnota se činností instrukce nemění.)

Rozložení těchto tří částí v 32-bitové hodnotě je následující:

Interval Final Counter
31 30 29 28 27 26
25 24 23 22 21 20 19 18 17
16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
1 . . . 64 -256 . . . 255 -65536 . . . 65535

POZOR!
Bitové šíře jednotlivých částí (zde 6-9-17) se liší od původního rozdělení ve vrstvě RPNPROC (8-8-16). Důvodem pro tuto změnu je rozšíření hodnot counter a final na úkor hodnoty interval. Rozšířené hodnoty jsou chápány jako znaménkové.


Immediate operand

Instrukcí, kterou seznam instrukcí neobsahuje, je také přímý operand. Je to instrukce obsahující hodnotu/číslo vstupující do X-registru RPN stacku. Je to stejné jako při provádění instrukce RCL r, pouze číslo není bráno z nějakého paměťového registru, ale přímo z instrukce.

Tvar přímého operandu může být dvojí:

Pozn.: Je-li Loop Control-number určen pouze dvojicí COUNTER,FINAL, je na postu nezadané hodnoty INTERVAL uvažováno číslo 1.


Pseudoinstrukce

Jsou tu ještě dvě zvláštní instrukce (tzv. pseudoinstrukce), které by zvědavec marně v seznamu instrukcí hledal: ?REG a ?RTN. Obě pseudoinstrukce doplňuje číselný operand a poslání obou souvisí s tabulkou parametrů této programové vrstvy.


?REG - Skutečný počet paměťových registrů

Celkový počet paměťových registrů je určen nejvyšším číslem, které se vyskytuje na postu operandu příslušných instrukcí. Děje se tak při vytváření binární formy RPN programu. Tak se získá nejvyšší číslo (index) registru adresovaného pouze přímo. Při použití indirekce je číslo paměťového registru dáno okamžitou hodnotou registrů RPN stacku nebo jiného paměťového registru. Okamžitá hodnota pochopitelně může převyšovat nejvyšší číslo dané přímou adresací a na problém je zaděláno. Provádění takového RPN programu typicky končí předčasně: funkce provádějící instrukce (lhostejno zda rpn32_run() či rpn32_now()) vrátí chybovou hodnotu RPN32_RTNVAL_REGOVF. Použití pseudoinstrukce ?REG informuje překladač/kompilátor o skutečném množství paměťových registrů. Pokud přesto dojde ke zmíněné chybě, jedná se o chybně navržený RPN program.


?RTN - Skutečný počet návratových adres

Situace s velikostí zásobníku návratových adres je velmi podobná té předchozí s paměťovými registry. Velikost zásobníku je při sestavování binární formy RPN programu dána prostým počtem výskytu instrukce XEQ bez ohledu na možnost vnoření podprogramu. Při určení velikosti zásobníku návratových adres se tím získá dostatečná rezerva. Další rezerva (např. pro eventuální rekurzivní volání) je explicitně určena právě pseudoinstrukci ?RTN s příslušným operandem.

Jak je psáno v úvodu, lokální registry se o paměťový prostor dělí se zásobníkem návratových adres. Skončí-li běh programu s chybou, kterou reprezentuje návratová hodnota RPN32_RTNVAL_RTNOVF, příčina může být dvojí. Kapacita zásobníku návratových adres je vyčerpána

  1. mnohonásobným vnořením jednotlivých volání podprogramů (jak napovídá symbol návratové hodnoty), nebo
  2. průběžně vznikajícími (PUSH resp. IPUSH) a neuvolňovanými (POP resp. RTN) lokálními registry.
Každopádně lékem na obojí je použití této pseudoinstrukce.


Poznámky platné pro obě pseudoinstrukce

1) Jak název napovídá, pseudoinstrukce (na rozdíl od skutečných instrukcí v seznamu) nejsou obsaženy v binární formě RPN programu. Jsou pouze parametrem ovlivňujícím podobu vnitřních paměťových struktur vytvářených funkcí rpn32_init().

2) Při opakovaném výskytu pseudoinstrukcí je výsledný počet paměťových registrů resp. volných položek zásobníku návratových adres dán pravidlem vyšší bere. Příklad.: Program v různých částech (typicky pro rezervaci místa pro lokální registry) obsahuje trojici pseudoinstrukcí ?RTN 2, ?RTN 6 a ?RTN 3. Aplikována je nejvyšší hodnota, tedy 6. Pokud je ale v tomto programu zároveň sedmnáctkrát obsažena instrukce XEQ, je po ukončení inicializace vyhrazeno v zásobníku návratových adres místo pro 17 vnořených volání (nebo pro 68 lokálních registrů).

3) Číselné operandy obou pseudoinstrukcí ?REG i ?RTN je třeba užívat s rozvahou. Celková kapacita paměti potřebná pro vnitřní proměnné vrstvy RPN32 - tedy i tabulky návěští, paměťových registrů i zásobníku návratových adres - je omezena na 2GB (což je naprosto nesmyslně vysoká hodnota, ale nešť). Pokus o překročení této hranice použitím pseudoinstrukcí je indikován chybovou hodnotou RPN32_RTNVAL_MEMREQ, kterou funkce rpn32_init() určitě vrátí.