Web 51 P-Code Interpreter |
Web 51 používá v části programu služeb interpretru P-kódu. Interpretr umožňuje dosáhnou dvou věcí:
- Obejit nemožnost vykonávání programu odjinud, než z vnitřní paměti programu, tj. umožnit vykonávat program např. i z vnější sériové I2C paměti.
- Zmenšení kódu
Struktura P-kódu vychází vychází z několika požadavků:
- Adresace příkazů je přímá, bez indexační tabulky, tj. v instrukci je obsažena adresa vstupního bodu výkonné procedury.
- Parametry příkazů je možno zadávat jak v pořadí MSB-LSB tak LSB-MSB
- Parametry je možno zadávat i nepřímo - pomocí odkazu do RAM
- Příkaz obsahuje max. 3 parametry o délce 16ti bitů
Vyjdeme-li z výše uvedených požadavků, docházíme k následující struktuře:
AAAAAAAA adresa procedury MSB AAAAAAAA -"- LSB __SSSIII option: (S)prohození LSB/MSB, (I)nepřímá adresace parametru 11111111 parametr 1 MSB (MSB1) 11111111 -"- LSB (LSB1) 22222222 parametr 2 MSB (MSB2) 22222222 -"- LSB (LSB2) 33333333 parametr 3 MSB (MSB3) 33333333 -"- LSB (LSB3)Celkem by P-kód měl 9 bytů na instrukci, což je poměrně hodně, vzhledem k tomu, že poměrně mnoho příkazů nepoužívá všechny 3 parametry. Často je nevyužita i možnost daná 16ti bitovým parametrem, velká část používaných parametrů je pouze 8mi bitová. Jak z toho ven? Cesta je jednoduchá, strukturu P-kódu doplníme o 6 bitů, udávajících zda je příslušný parametr MSB1 až LSB3 nenulový. Doplněné bity nám umožňují zavést proměnou délku P-kódu vynecháním celých nulových parametrů, či jejich MSB/LSB části. Omezíme-li mírně možnosti P-kódu o možnost prohození LSB/MSB u parametru 2 a adresaci procedury na 13 bitů, docházíme k výsledné struktuře:
IIIAAAAA adresa procedury MSB, (I)nepřímá adresace parametru AAAAAAAA -"- LSB abcdefSS option: (S)prohození LSB/MSB, parametr MSB1..LSB3 uveden 11111111 parametr 1 MSB (MSB1 - a) 11111111 -"- LSB (LSB1 - b) 22222222 parametr 2 MSB (MSB2 - c) 22222222 -"- LSB (LSB2 - d) 33333333 parametr 3 MSB (MSB3 - e) 33333333 -"- LSB (LSB3 - f)Výsledný P-kód má proměnou délku od 3 do 9 bytů. Jeho generování je možno ukázat na makru používaném ve starších verzích vývojového systému:
; ; pcode EQU ; blank equ 0 none EQU 0000h IND1 EQU 8000h ;par1 INDirect IND2 EQU 4000h ;par2 INDirect IND3 EQU 2000h ;par3 INDirect SWAP1 EQU 8002h ;always Indirect & Swap SWAP3 EQU 2001h ; DP MACRO fce, option, par1, par2, par3 DW fce + (option and 0E000h) btk1 SET 0 btk2 SET 0 btk3 SET 0 btk4 SET 0 btk5 SET 0 btk6 SET 0 if (par1 SHR 8) <> 0 btk1 SET 10000000b endif if (par1 AND 0FFh) <> 0 btk2 SET 01000000b endif if (par2 SHR 8) <> 0 btk3 SET 00100000b endif if (par2 AND 0FFh) <> 0 btk4 SET 00010000b endif if (par3 SHR 8) <> 0 btk5 SET 00001000b endif if (par3 AND 0FFh) <> 0 btk6 SET 00000100b endif DB btk1 or btk2 or btk3 or btk4 or btk5 or btk6 or (option and 0003h) if (par1 SHR 8) <> 0 DB high(par1) endif if (par1 AND 0FFh) <> 0 DB low(par1) endif if (par2 SHR 8) <> 0 DB high(par2) endif if (par2 AND 0FFh) <> 0 DB low(par2) endif if (par3 SHR 8) <> 0 DB high(par3) endif if (par3 AND 0FFh) <> 0 DB low(par3) endif ENDMZ úvodní definice parametrů je vidět, že parametry SWAP mají smysl pouze ve spojení s příslušným parametrem IND (pořadí LSB/MSB u literární proměné je možno prohodit už ve fázi překladu zdrojového textu). V úvodní definici adresace procedury P-kódu je uvedeno, že je možno pomocí P-kódu adresovat strojový kód v rozsahu 13ti bitů, ale není to tak zcela pravda. Je zde ještě jedno omezení. Pro ukončení činosti interpretru P-kódu a přechod do režimu strojového kódu je použita zarážka, často používaná i při definici ASCIIZ textů. To znamená, že definici P-kódu ukončíme uvedením binární nuly za konec části v P-kódu, např. pomocí .byte 0 (resp. DB 0 pro Intel/Keil). Tato binární nula však koliduje s definicí adresy procedury v P-kódu, je-li použitá instrukce bez modifikace INDirect. MSB část adresy proto nesmí být nulová. Vyjdeme-li z těchto dvou omezení, vychází použitelný rozsah adres 100h...1FFFh. Na toto omezení je nutno pamatovat především při linkování a zabezpečit, aby žádná vstupní adresa strojové P-procedury nebyla v rozsahu 0000..00FFh.
Přejděme nyní k předávání parametrů z interpretru P-kódu do vlastních strojových P-procedur. Parametry se předávají pomocí registrů a to přes:
- R6(MSB)R7(LSB) v případě 1. parametru
- R4(MSB)R5(LSB) v případě 2. parametru
- R2(MSB)R3(LSB) v případě 3. parametru
Pokud je v parametrech P-kódu instrukce zadáno méně než 6 byte, jsou nezadané hodnoty parametrů vynulovány. Po případném načtení parametrů do registrů je provedeno vyhodnocení INDirect příznaků. Je-li příslušný příznak uveden, je pomocí LSB části dvoj-registru, tj. registrem R7/R5/R3 naadresována vnitřní RAM procesoru a zní je vždy vyzvednuto 16bitů parametru v pořadí MSB - LSB, jak je vidět z následujího fragmentu kódu:
NoOpt2: JNB token.7,noI1 MOV A,R7 MOV R0,A MOV A,@R0 MOV R6,A INC R0 MOV A,@R0 MOV R7,A noI1: JNB token.6,noI2Po vyhodnocení INDirect příznaků jsou následně vyhodnoceny příznaky SWAP, prohazující mezi sebou MSB a LSB část dvojregistru. Vyhodnocení objasníme nejlépe fragmentem kódu:
noI3: jnb pcodeOption.1,NoOpt1 MOV A,R6 ;swap1 XCH A,R7 MOV R6,A NoOpt1: jnb pcodeOption.0,NoOpt0Výše uvedené makro DP je univerzální, automaticky zjišťuje velikost (a přítomnost) parametrů. Nicméně je nutné vzhledem k možnosti rozdělit program do modulů, mít možnost explicitně udat velikost BYTE/WORD parametrů 1 až 3. K tomu složí sada maker DPB__, ..., DP__B, ..., DPW__, kde písmeno B či W na příslušné pozici znamená, že velikost parametru je napevno nastavena na BYTE či WORD, popř. _ znamená, že velikost se zjišťuje automaticky.
Současná verze vývojového systému využívá nativní podporu zabudovanou v překladači assembleru mcs51-as.
Syntaxe příkazu .pcode je obdobná syntaxi standartního instrukčního kódu MCS51. Pro adresaci používá příkaz .pcode tři hlavní adresní módy:
- přímou konstantu - uvedenou prefixem #, např.
.pcode xmit_frame #SIZE_OF_ETH_PKT_HDR+SIZE_OF_ARP- proměnnou - bez jakéhokoliv prefixem, např.
.pcode paddwi IPlen, #(IP_HEADER_LEN+TCP_HEADER_LEN)- nepřímou proměnnou - uvedenou prefixem @, např.
.pcode paddwi BYTE data_addr, @(buf+(TCP_SEQ-IP_LEN)+2)Čím se jednotlivé způsoby adresace od sebe liší?
Přímá konstanta a proměnná ničím, obě předají volané proceduře zadanou hodnotu. Odlišný způsob zápisu konstanty a proměnné je zvolen jen pro lepší čitelnost zdrojového kódu. Co se ve skutečnosti s předaným parametrem stane, tj. bude-li použit jako konstanta, nebo zda ve skutečnosti reprezentuje adresu proměnné závisí pouze na proceduře, která je volána.
Nepřímá konstanta vloží do pkódu příznak nepřímé adresace, takže interpretr pkódu při vykonávání, tak jak bylo uvedeno výše, načte hodnotu předávanou volané proceduře z adresy, udané jako parametr.
Předávání parametrů je možno ovlivnit několika dalšími modifikátory:
P-Code Interpreter, část 2
- #BYTE, BYTE - nezná-li překladač při překladu skutečnou velikost předávaného parametru, zvolí implicitně velikost 2 byte. Víme-li, že parametr bude maximálně 1 bytový (např. adresa do paměti RAM procesoru) můžeme překlad ovlivnit modifikátorem BYTE. Skutečnou velikost parametru překladač/linker kontroluje a při neshodě vyvolá chybové hlášení.
- #WORD, WORD - vypne u překladače detekci zda se předávaná hodnota vejde do osmibitového čísla a zvolí předání šestnáctibitové hodnoty.
- #SWAP, SWAP - vloží do kódu příznak swap, tj. u zadané hodnoty je je před předáním volané proceduře prohozen vyšší a nižší byte. #SWAP a SWAP očekávají jako parametr šestnáctibitovou hodnotu.
- @BYTE, @WORD - Nejprve je do pomocné proměnné načtena hodnota osmibitového parametru a pomocí ní je z paměti RAM procesoru vybrána šestnáctibitová hodnota a ta je předána volané proceduře. Rozlišení BYTE/WORD zohledňuje to, že nepřímá adresace načítá jako první vyšší byte. Používáme-li ve volané proceduře pouze pouze osmibitovou hodnotu, je potřeba počítat s tím, že adresa odkud se má začít načítat nepřímá hodnota je o jedničku nižší (na této adrese je uložena nepoužitá vyšší hodnota). Překladač tuto korekci zabezpečuje sám, uvedeme-li modifikátor @BYTE.
- @SWAP - vloží do kódu příznak swap, tj. nejprve je do pomocné proměnné načtena předaná osmibitová hodnota a pomocí ní je z paměti RAM procesoru vybrána šestnáctibitová hodnota, která je po prohození vyššího a nižšího byte předána volané proceduře
- Posledním možným modifikátorem ja #SHL8, SHL8 očekávající jako parametr osmibitovou hodnotu, kterou předá jako vyšší byte volané proceduře (nižší je automaticky, stejně jako ostatní implicitní, tj. nezadané parametry vynulován).
POPIS Web51 | NOVINKY | FAQ | OBJEDNÁVKA | DOWNLOAD |
(c)Copyright 2000, 2001, HW server & Radek Benedikt
Web51@HW.cz, Web51.HW.cz Final applications of the Web51 : www.HWgroup.cz |