Stroj s kódem P. - P-code machine
![]() | Bylo navrženo, aby tento článek byl sloučeny s Bytecode. (Diskutujte) Navrhováno od září 2020. |
v programování, a stroj s p-kódemnebo přenosný kódovací stroj[1] je virtuální stroj navržen k provedení p-kód (dále jen montážní jazyk hypotetického CPU). Tento výraz se obecně vztahuje na všechny takové stroje (např Virtuální stroj Java a MATLAB předkompilovaný kód) a ke konkrétním implementacím, z nichž nejznámější je p-Machine of the Pascal-P systém, zejména UCSD Pascal implementace (mezi jehož vývojáři bylo „p“ v „p-kódu“ vykládáno tak, že znamená „pseudo“ častěji než „přenosný“, „pseudokód“ tedy znamená instrukce pro pseudo-stroj).
Ačkoli byl koncept poprvé zaveden kolem roku 1966 (jako O-kód pro BCPL a P - kód pro Eulerův jazyk ),[2] termín p-kód se poprvé objevil na začátku 70. let. Dva brzy překladače generující p-kód byl překladač Pascal-P v roce 1973, autor: Kesav V. Nori, Urs Ammann, Kathleen Jensen, Hans-Heinrich Nägeli a Christian Jacobi,[3] a Pascal-S překladač v roce 1975, autor Niklaus Wirth.
Programy, které byly přeloženy do p-kódu, mohou být buď interpretován softwarovým programem, který emuluje chování hypotetického CPU, nebo přeloženo do strojového kódu CPU, na kterém má program běžet a poté spuštěn. Pokud existuje dostatečný komerční zájem, může být vytvořena hardwarová implementace specifikace CPU (např Pascal MicroEngine nebo verze Procesor Java ).
Výhody a slabé stránky implementace p-kódu
![]() | Tato část obsahuje toto znění propaguje subjekt subjektivním způsobem bez předávání skutečných informací.Prosince 2014) (Zjistěte, jak a kdy odstranit tuto zprávu šablony) ( |
Ve srovnání s přímým překladem do nativního jazyka strojový kód, dvoustupňový přístup zahrnující překlad do p-kódu a provedení pomocí tlumočník nebo kompilátor just-in-time nabízí několik výhod.
- Je mnohem snazší napsat malý tlumočník p-kódu pro nový stroj, než je upravit kompilátor tak, aby generoval nativní kód pro stejný stroj.
- Generování strojového kódu je jednou ze složitějších částí psaní kompilátoru. Pro srovnání je generování p-kódu mnohem jednodušší, protože při generování kódu není nutné brát v úvahu žádné chování závislé na stroji bytecode. Díky tomu je užitečné pro rychlé uvedení kompilátoru do provozu.
- Vzhledem k tomu, že p-kód je založen na ideálním virtuálním stroji, je program p-kódu často mnohem menší než stejný program přeložený do strojového kódu.
- Při interpretaci p-kódu může tlumočník použít další kontroly běhu které je obtížné implementovat pomocí nativního kódu.
Jednou z významných nevýhod p-kódu je rychlost provádění, kterou lze někdy napravit pomocí a Překladač JIT. P-kód je často také snazší zpětný inženýr než nativní kód.
Na začátku 80. let nejméně dvě operační systémy dosaženo nezávislost stroje díky rozsáhlému používání p-kódu. The Obchodní operační systém (BOS) byl multiplatformní operační systém navržený výhradně pro spouštění programů p-kódu. The UCSD p-systém, vyvinutý na Kalifornské univerzitě v San Diegu, byl kompilace a samoobslužný[je zapotřebí objasnění ] operační systém založený na p-kódu optimalizovaném pro generování Pascal programovací jazyk.
V 90. letech se překlad do p-kódu stal populární strategií pro implementaci jazyků jako např Krajta, Microsoft P-Code v Visual Basic a Bajtový kód Java v Jáva.[4][ověření se nezdařilo ]
The Jděte do programovacího jazyka používá obecnou přenosnou sestavu jako formu p-kódu, implementovanou Ken Thompson jako rozšíření práce na Plán 9 od Bell Labs. Na rozdíl od CLR bytecode nebo JVM bytecode, neexistuje žádná stabilní specifikace a nástroje Go build nevydávají formát bytecode, který by se dal použít později. Go assembler používá obecný jazyk sestavení jako mezilehlé zastoupení a spustitelné soubory Go jsou specifické pro stroj staticky propojeno binární soubory.[5]
UCSD p-stroj
Architektura
Stejně jako mnoho jiných strojů s p-kódem je UCSD p-Machine a stohovací stroj, což znamená, že většina pokynů vezme své operandy ze zásobníku a umístí výsledky zpět do zásobníku. Instrukce „add“ tedy nahradí dva nejvyšší prvky zásobníku jejich součtem. Několik pokynů vyžaduje okamžitou hádku. Stejně jako Pascal je i p-kód silně typizovaný a nativně podporuje typy typu boolean (b), znak (c), integer (i), real (r), set (s) a pointer (a).
Několik jednoduchých pokynů:
Insn. Stack Stack Description before after adi i1 i2 i1 + i2 add two integersadr r1 r2 r1 + r2 add two realsdvi i1 i2 i1 / i2 integer divisioninn i1 s1 b1 set membership; b1 = zda i1 je členem s1ldci i1 i1 načíst celé číslo konstantnímov a1 a2 movenot b1 ~ b1 booleovská negace
životní prostředí
Na rozdíl od jiných prostředí založených na zásobníku (například Forth a Virtuální stroj Java ) ale velmi podobný skutečnému cílovému CPU, p-System má pouze jeden zásobník sdílený rámci zásobníku procedur (za předpokladu zpáteční adresa atd.) a argumenty k místním pokynům. Tři stroje registry přejděte do zásobníku (který roste nahoru):
- SP ukazuje na vrchol hromádky ( ukazatel zásobníku ).
- MP označuje začátek aktivního rámce zásobníku ( označte ukazatel ).
- EP ukazuje na nejvyšší umístění zásobníku použité v aktuálním postupu ( extrémní ukazatel ).
K dispozici je také konstantní oblast a pod ní také halda roste dolů k hromádce. NP (dále jen nový ukazatel ) registr ukazuje na vrchol (nejnižší použitá adresa) haldy. Když je EP větší než NP, paměť zařízení je vyčerpána.
Pátý registr, PC, ukazuje na aktuální instrukci v oblasti kódu.
Konvence volání
Stohové rámečky vypadají takto:
EP -> local stackSP -> ... locals ... parametry ... zpáteční adresa (předchozí PC) předchozí EP dynamický odkaz (předchozí MP) statický odkaz (MP okolní procedury) MP -> návratová hodnota funkce
Sekvence volání procedury funguje následovně: Hovor je zaveden pomocí
mst n
kde n
určuje rozdíl v úrovních vnoření (nezapomeňte, že Pascal podporuje vnořené procedury). Tato instrukce bude označit zásobník, tj. rezervovat prvních pět buněk výše uvedeného rámce zásobníku a inicializovat předchozí EP, dynamický a statický odkaz. Volající poté vypočítá a odešle všechny parametry procedury a poté vydá
pohár n, str
zavolat proceduru uživatele (n
je počet parametrů, p
adresa postupu). Tím uložíte počítač do buňky zpáteční adresy a nastavíte adresu procedury jako nový počítač.
Uživatelské postupy začínají dvěma pokyny
ent 1, i ent 2, j
První nastaví SP na MP + i
, druhý nastaví EP na SP + j
. Tak i
v podstatě určuje prostor vyhrazený pro místní obyvatele (plus počet parametrů plus 5) a j
udává počet položek potřebných lokálně pro zásobník. V tomto okamžiku se kontroluje vyčerpání paměti.
Návrat k volajícímu se provádí prostřednictvím
retC
s C
udávající návratový typ (i, r, c, b, a jako výše a p pro žádnou návratovou hodnotu). Návratová hodnota musí být dříve uložena v příslušné buňce. U všech typů kromě p vrátí návrat tuto hodnotu na zásobníku.
Místo volání uživatelské procedury (kalíšku), standardní procedura q
lze volat pomocí
csp q
Tyto standardní postupy jsou procedury Pascal podobné readln ()
(csp rln
), hřích()
(csp hřích
) atd. Zvláštní eof ()
je místo toho instrukce p-kódu.
Příklad stroje
Niklaus Wirth specifikoval v knize z roku 1976 jednoduchý stroj s p-kódem Algoritmy + datové struktury = programy. Stroj měl 3 registry - a počítadlo programů p, a základní registr ba registr horní části zásobníku t. Bylo zde 8 pokynů:
- svítí 0, A : konstanta zatížení A
- opr 0, A : provést operaci A (13 operací: RETURN, 5 matematických funkcí a 7 srovnávacích funkcí)
- lod l, A : proměnná zatížení Los Angeles
- sto l, A : proměnná obchodu Los Angeles
- CAL l, A : postup volání A na úrovni l
- int 0, A : přírůstek t-registrace od A
- jmp 0, A : skočit do A
- jpc 0, A : skok podmíněně do A[6]
Toto je kód pro stroj napsaný v Pascalu:
konst amax=2047; {maximální adresa} levmax=3; {maximální hloubka vnoření bloku} cxmax=200; {velikost pole kódu}typ fct=(svítí,opr,lod,sto,CAL,int,jmp,jpc); návod=zabaleno záznam F:fct; l:0..levmax; A:0..amax; konec;var kód: pole [0..cxmax] z návod;postup interpretovat; konst stacksize = 500; var p, b, t: celé číslo; {program-, base-, topstack-registers} i: návod; {instrukční registr} s: pole [1..stacksize] z celé číslo; {úložiště dat} funkce základna(l: celé číslo): celé číslo; var b1: celé číslo; začít b1 := b; {najít základní úrovně l} zatímco l > 0 dělat začít b1 := s[b1]; l := l - 1 konec; základna := b1 konec {základna};začít writeln('start pl / 0'); t := 0; b := 1; p := 0; s[1] := 0; s[2] := 0; s[3] := 0; opakovat i := kód[p]; p := p + 1; s i dělat případ F z svítí: začít t := t + 1; s[t] := A konec; opr: případ A z {operátor} 0: začít {vrátit se} t := b - 1; p := s[t + 3]; b := s[t + 2]; konec; 1: s[t] := -s[t]; 2: začít t := t - 1; s[t] := s[t] + s[t + 1] konec; 3: začít t := t - 1; s[t] := s[t] - s[t + 1] konec; 4: začít t := t - 1; s[t] := s[t] * s[t + 1] konec; 5: začít t := t - 1; s[t] := s[t] div s[t + 1] konec; 6: s[t] := ord(zvláštní(s[t])); 8: začít t := t - 1; s[t] := ord(s[t] = s[t + 1]) konec; 9: začít t := t - 1; s[t] := ord(s[t] <> s[t + 1]) konec; 10: začít t := t - 1; s[t] := ord(s[t] < s[t + 1]) konec; 11: začít t := t - 1; s[t] := ord(s[t] >= s[t + 1]) konec; 12: začít t := t - 1; s[t] := ord(s[t] > s[t + 1]) konec; 13: začít t := t - 1; s[t] := ord(s[t] <= s[t + 1]) konec; konec; lod: začít t := t + 1; s[t] := s[základna(l) + A] konec; sto: začít s[základna(l)+A] := s[t]; writeln(s[t]); t := t - 1 konec; CAL: začít {generovat novou značku bloku} s[t + 1] := základna(l); s[t + 2] := b; s[t + 3] := p; b := t + 1; p := A konec; int: t := t + A; jmp: p := A; jpc: začít -li s[t] = 0 pak p := A; t := t - 1 konec konec {with, case} dokud p = 0; writeln('end pl / 0');konec {interpretovat};
Tento stroj byl používán ke spuštění Wirthova PL / 0, kompilátor podmnožiny Pascal používaný k výuce vývoje kompilátoru.[7][ověření se nezdařilo ]
Viz také
- Celé jablko Apple Sweet 16
- Bytecode
- Joel McCormack - návrhář verze stroje p-code NCR Corporation
- LLVM IR
- Microsoft P-Code
- Runtime systém
- Navlékání tokenů
Reference
- ^ Upton, Eben; Duntemann, Jeffrey; Roberts, Ralph; Mamtora, Tim; Everard, Ben (2016-09-13). Učení počítačové architektury s Raspberry Pi. John Wiley & Sons. ISBN 978-1-119-18393-8.
- ^ Wirth, Niklausi; Weber, Helmut (1966). „EULER: zobecnění ALGOLU a jeho formální definice: část II“. Komunikace ACM. New York, USA: Sdružení pro výpočetní techniku (ACM). 9 (2): 89–99. doi:10.1145/365170.365202. S2CID 12124100.
- ^ Nori, Kesav V .; Ammann, Urs; Jensen, Kathleen; Nägeli, Hans-Heinrich; Jacobi, Christian (1975). Poznámky k implementaci kompilátoru Pascal P.. Curych, Švýcarsko: Eidgenössische Technische Hochschule (ETH).
- ^ „Systém p-kódu“.
- ^ Pike, Robert C. (2016). „The Design of the Go Assembler“ (Přednáška na konferenci). Citováno 2017-08-25.
- ^ „Archivy kategorií: Wirth - Euler - Návrh Niklaus Wirth a Helmut Weber“. Pascal pro malé stroje - jazyky Wirth, Pascal, UCSD, Turbo, Delphi, Freepascal, Oberon. 2018-08-02.
- ^ Alpert, Donald (září 1979). „Tlumočník Pascal P-Code pro Stanford Emmy“ (PDF). Laboratoř počítačových systémů, Oddělení Eleotrioal Engineering and Computer Scienoes, Stanford University. Technická poznámka č. 164. Citovat deník vyžaduje
| deník =
(Pomoc)
Další čtení
- Pemberton, Steven; Daniels, Martin. Pascal Implementation: The P4 Compiler and Interpreter. Ellis Horwood / John Wiley. ISBN 0-13-653031-1.
- Pemberton, Steven, vyd. (2011-04-13). „Implementace Pascal: Kniha a zdroje“. (Pozn. Má Pascalovy zdroje P4 překladač a tlumočník, pokyny k použití.)
- Pemberton, Steven, vyd. (2011-04-13). "pcode kompilátoru Pascal, jak je kompilován sám". (Pozn. Má p-kód P4 kompilátor, vygenerovaný sám.)
- „Stránka Jeffersonova počítačového muzea na UCSD p-systému“.
- „Implementace Open Source“., včetně obalů a předkompilovaných binárních souborů; přátelská vidlice Klebsch. „Klebschova implementace“.
- Terry, Pat (2005). Kompilace s C # a Java. p. 624. ISBN 0-321-26360-X.
- Wirth, Niklausi (1975). Algoritmy + datové struktury = programy. ISBN 0-13-022418-9.
- Wirth, Niklausi (1996). Konstrukce kompilátoru. ISBN 0-201-40353-6.
- Liffick, Blaise W., vyd. (1979). Byte Book of Pascal. ISBN 0-07-037823-1.
- Barron, David William, vyd. (1981). PASCAL - Jazyk a jeho implementace. ISBN 0-471-27835-1. (Pozn. Zvláště viz články Poznámky k implementaci Pascal-P a Pascal-S: Podmnožina a její implementace.)