p-kod makinesi - p-code machine
Olarak bilgisayar programlama , bir p-kod makinesi ( taşınabilir kod makine ) a, sanal makine çalıştırmak için tasarlanmış , p-kodu ( montaj dili ya da makine kodu varsayımsal bir merkezi işlem birimi (CPU)). Bu terim hem genel olarak tüm bu tür makinelere ( Java sanal makinesi (JVM) ve MATLAB önceden derlenmiş kodu gibi) hem de en ünlüsü Pascal-P sisteminin p-Makinesi , özellikle UCSD Pascal olan belirli uygulamalara uygulanır. Geliştiriciler arasında, p-kodundaki p'nin , taşınabilirden daha sık sözde anlamına geldiği , dolayısıyla sözde kod , bir sözde makine için talimatlar anlamına gelen uygulama.
Konsept ilk olarak 1966 dolaylarında ( Temel Kombine Programlama Dili ( BCPL ) için O-kodu ve Euler dili için P kodu olarak ) uygulanmış olsa da, p-kodu terimi ilk olarak 1970'lerin başında ortaya çıktı. P kodu üreten iki erken derleyici , 1973'te Kesav V. Nori, Urs Ammann, Kathleen Jensen, Hans-Heinrich Nägeli ve Christian Jacobi tarafından Pascal-P derleyicisi ve 1975'te Niklaus Wirth tarafından Pascal-S derleyicisiydi .
p-koduna çevrilen programlar ya varsayımsal CPU'nun davranışını taklit eden bir yazılım programı tarafından yorumlanabilir ya da programın üzerinde çalışacağı ve daha sonra yürütüleceği CPU'nun makine koduna çevrilebilir . Yeterli ticari ilgi varsa, CPU spesifikasyonunun bir donanım uygulaması oluşturulabilir (örneğin, Pascal MicroEngine veya bir Java işlemci sürümü ).
p-kodunu uygulamanın yararları ve zayıflıkları
Yerel makine koduna doğrudan çeviri ile karşılaştırıldığında , p-koduna çeviri ve yorumlayarak veya tam zamanında derleme (JIT) ile yürütmeyi içeren iki aşamalı bir yaklaşım çeşitli avantajlar sunar.
- Yeni bir makine için küçük bir p kodu yorumlayıcısı yazmak, bir derleyiciyi aynı makine için yerel kod üretecek şekilde değiştirmekten çok daha kolaydır.
- Makine kodu oluşturmak, derleyici yazmanın daha karmaşık kısımlarından biridir. Karşılaştırıldığında, bayt kodunu oluştururken makineye bağlı hiçbir davranışın dikkate alınmaması gerektiğinden, p kodu oluşturmak çok daha kolaydır . Bu, bir derleyiciyi hızlı bir şekilde kurmak ve çalıştırmak için kullanışlı hale getirir.
- p-kodu ideal bir sanal makineyi temel aldığından, bir p-kodu programı genellikle makine koduna çevrilen aynı programdan çok daha küçüktür.
- p kodu yorumlandığında, yorumlayıcı yerel kodla uygulanması zor olan ek çalışma zamanı kontrolleri uygulayabilir.
P-kodunun önemli dezavantajlarından biri, bazen JIT derlemesi yoluyla giderilebilen yürütme hızıdır. P kodunun tersine mühendislik işlemi yerel koddan daha kolaydır .
1980'lerin başında, en az iki işletim sistemi , p-kodunun kapsamlı kullanımıyla makine bağımsızlığını elde etti . İş İşletim Sistemi (BOS) münhasıran p-code programları çalıştırmak için tasarlanmış bir çapraz platform işletim sistemi oldu. The University of California, San Diego'da geliştirilen UCSD p-System , Pascal dili tarafından nesil için optimize edilmiş p-kodunu temel alan, kendi kendini derleyen ve kendi kendini barındıran bir işletim sistemiydi .
1990'larda, p-koduna çeviri gibi dillerin uygulamaları için popüler bir strateji haline Python , Microsoft, P-Code içinde Visual Basic ve Java byte içinde Java .
Go dili , Ken Thompson tarafından Bell Labs'den Plan 9 üzerindeki çalışmanın bir uzantısı olarak uygulanan bir p-kodu biçimi olarak genel, taşınabilir bir derleme kullanır . Aksine ortak dil çalışma zamanı (CLR) bayt veya JVM bayt, hiçbir istikrarlı şartname yoktur ve bir bayt kodu biçimi yaymaz Git inşa etmek araçları daha sonra kullanılmak üzere. Go assembler, bir ara temsil olarak genel derleme dilini kullanır ve Go yürütülebilir dosyaları, makineye özgü statik olarak bağlantılı ikili dosyalardır.
UCSD p-Makine
Mimari
Diğer birçok p-kod makinesi gibi, UCSD p-Machine bir yığın makinesidir , bu da çoğu talimatın işlenenlerini bir yığından aldığı ve sonuçları yığına geri yerleştirdiği anlamına gelir . Böylece add
talimat, yığının en üstteki iki öğesini toplamlarıyla değiştirir. Birkaç talimat hemen bir argüman alır. Pascal gibi, p-kodu da güçlü bir şekilde yazılır , boolean (b), karakter (c), tamsayı (i), gerçek (r), set (s) ve işaretçi (a) veri türlerini doğal olarak destekler.
Bazı basit talimatlar:
Insn. Stack Stack Description before after adi i1 i2 i1+i2 add two integers adr r1 r2 r1+r2 add two reals inn i1 s1 is1 set membership; b1 = whether i1 is a member of s1 ldi i1 i1 i1 load integer constant mov a1 a2 a2 move not b1 b1 -b1 boolean negation
Çevre
Diğer yığın tabanlı ortamlardan ( Forth ve Java sanal makinesi gibi ) farklı olarak, ancak gerçek bir hedef CPU'ya çok benzer, p-Sistemi, prosedür yığın çerçeveleri ( dönüş adresi vb. sağlayan) tarafından paylaşılan yalnızca bir yığına ve bağımsız değişkenlere sahiptir. yerel talimatlar. Makinenin kayıtlarından üçü yığına işaret eder (yukarı doğru büyür):
- SP, yığının tepesini gösterir ( yığın işaretçisi ).
- MP, etkin yığın çerçevesinin başlangıcını işaretler ( işaret işaretçisi ).
- EP, geçerli prosedürde kullanılan en yüksek yığın konumuna işaret eder (en uç işaretçi ).
Ayrıca sabit bir alandır ve bunun altında yığın yığına doğru büyür. NP ( yeni işaretçi ) kaydı, yığının en üstüne (en düşük kullanılan adres) işaret eder. EP, NP'den büyük olduğunda, makinenin belleği tükenir.
Beşinci kayıt olan PC, kod alanındaki mevcut talimatı işaret eder.
çağrı kuralları
Yığın çerçeveleri şöyle görünür:
EP -> local stack SP -> ... locals ... parameters ... return address (previous PC) previous EP dynamic link (previous MP) static link (MP of surrounding procedure) MP -> function return value
Prosedür çağırma sırası aşağıdaki gibi çalışır: Çağrı,
mst n
burada n
yuvalama seviyelerindeki farkı belirtir (Pascal'ın yuvalanmış prosedürleri desteklediğini unutmayın). Bu talimat yığını işaretler , yani yukarıdaki yığın çerçevesinin ilk beş hücresini rezerve eder ve önceki EP, dinamik ve statik bağlantıyı başlatır. Arayan daha sonra prosedür için herhangi bir parametreyi hesaplar ve gönderir ve ardından
cup n, p
bir kullanıcı prosedürünü çağırmak için ( n
parametre sayısı p
, prosedürün adresi). Bu, bilgisayarı iade adres hücresine kaydedecek ve prosedürün adresini yeni bilgisayar olarak ayarlayacaktır.
Kullanıcı prosedürleri iki talimatla başlar
ent 1, i ent 2, j
Birincisi SP'yi MP+' i
ya, ikincisi EP'yi SP+'ya ayarlar j
. Yani i
esasen yereller için ayrılmış alanı belirtir (artı parametre sayısı artı 5) ve j
yığın için yerel olarak gereken giriş sayısını verir. Bu noktada bellek tükenmesi kontrol edilir.
Arayana geri dönüş şu şekilde gerçekleştirilir:
retC
ile C
(geri dönüş değeri için, yukarıdaki gibi, I, R, C, B, ve p) dönüş vermenin. Dönüş değeri önceden uygun hücrede saklanmalıdır. p hariç tüm türlerde, döndürme bu değeri yığında bırakacaktır.
Bir kullanıcı prosedürü (cup) çağırmak yerine, standart prosedür q
ile çağrılabilir.
csp q
Bu standart prosedürler readln()
( csp rln
), sin()
( csp sin
), vb. Pascal prosedürleridir . Tuhaf eof()
bir şekilde bunun yerine bir p-Kodu talimatıdır.
Örnek makine
Niklaus Wirth, 1976 tarihli Algorithms + Data Structures = Programs kitabında basit bir p-kod makinesi tanımladı . Makinenin 3 kaydı vardı - bir program sayacı p , bir temel kayıt b ve bir yığın üstü kayıt t . 8 talimat vardı:
- yanıyor 0, a : yük sabiti a
- Opr 0, bir : yürütme işlemi bir (13 işlemleri: GERİ, 5 matematik fonksiyonları ve 7 karşılaştırma fonksiyonları)
- lod l , a : yük değişkeni l,a
- sto l , a : l,a değişkenini depola
- cal l , a : çağrı usulü bir seviyesinde l
- int 0, a : t kaydını a ile artır
- JMP 0, bir : atlama a
- JPC 0, bir : atlama koşullu için bir
Pascal ile yazılmış makinenin kodu:
const
amax=2047; {maximum address}
levmax=3; {maximum depth of block nesting}
cxmax=200; {size of code array}
type
fct=(lit,opr,lod,sto,cal,int,jmp,jpc);
instruction=packed record
f:fct;
l:0..levmax;
a:0..amax;
end;
var
code: array [0..cxmax] of instruction;
procedure interpret;
const stacksize = 500;
var
p, b, t: integer; {program-, base-, topstack-registers}
i: instruction; {instruction register}
s: array [1..stacksize] of integer; {datastore}
function base(l: integer): integer;
var b1: integer;
begin
b1 := b; {find base l levels down}
while l > 0 do begin
b1 := s[b1];
l := l - 1
end;
base := b1
end {base};
begin
writeln(' start pl/0');
t := 0; b := 1; p := 0;
s[1] := 0; s[2] := 0; s[3] := 0;
repeat
i := code[p]; p := p + 1;
with i do
case f of
lit: begin t := t + 1; s[t] := a end;
opr:
case a of {operator}
0:
begin {return}
t := b - 1; p := s[t + 3]; b := s[t + 2];
end;
1: s[t] := -s[t];
2: begin t := t - 1; s[t] := s[t] + s[t + 1] end;
3: begin t := t - 1; s[t] := s[t] - s[t + 1] end;
4: begin t := t - 1; s[t] := s[t] * s[t + 1] end;
5: begin t := t - 1; s[t] := s[t] div s[t + 1] end;
6: s[t] := ord(odd(s[t]));
8: begin t := t - 1; s[t] := ord(s[t] = s[t + 1]) end;
9: begin t := t - 1; s[t] := ord(s[t] <> s[t + 1]) end;
10: begin t := t - 1; s[t] := ord(s[t] < s[t + 1]) end;
11: begin t := t - 1; s[t] := ord(s[t] >= s[t + 1]) end;
12: begin t := t - 1; s[t] := ord(s[t] > s[t + 1]) end;
13: begin t := t - 1; s[t] := ord(s[t] <= s[t + 1]) end;
end;
lod: begin t := t + 1; s[t] := s[base(l) + a] end;
sto: begin s[base(l)+a] := s[t]; writeln(s[t]); t := t - 1 end;
cal:
begin {generate new block mark}
s[t + 1] := base(l); s[t + 2] := b; s[t + 3] := p;
b := t + 1; p := a
end;
int: t := t + a;
jmp: p := a;
jpc: begin if s[t] = 0 then p := a; t := t - 1 end
end {with, case}
until p = 0;
writeln(' end pl/0');
end {interpret};
Bu makine, derleyici geliştirmeyi öğretmek için kullanılan bir Pascal alt küme derleyicisi olan Wirth's PL/0'ı çalıştırmak için kullanıldı.
Ayrıca bakınız
- Elma Tamsayı Tatlı 16
- bayt kodu
- Joel McCormack , p-kod makinesinin NCR Corporation versiyonunun tasarımcısı
- LLVM IR
- Microsoft P Kodu
- çalışma zamanı sistemi
- Jeton iş parçacığı
Referanslar
daha fazla okuma
- Pemberton, Steven ; Daniels, Martin. Pascal Uygulaması: P4 Derleyicisi ve Yorumlayıcısı . John Wiley . ISBN'si 0-13-653031-1.
- Pemberton, Steven , ed. (2011-04-13). "Pascal Uygulaması: Bir Kitap ve Kaynaklar" .(Not. P4 derleyicisi ve yorumlayıcısının Pascal kaynakları , kullanım talimatları vardır.)
- Pemberton, Steven , ed. (2011-04-13). "Kendisi tarafından derlenen Pascal Derleyicisinin pkodu" .(Not. Kendi ürettiği P4 derleyicisinin p koduna sahiptir .)
- "UCSD p-Sisteminde Jefferson Bilgisayar Müzesi'nin sayfası" .
- "Açık Kaynak uygulaması" .paketleme ve önceden derlenmiş ikili dosyalar dahil; Klebsch'in dostça bir çatalı . "Klebsch uygulaması" .
- Terry, Pat (2005). C# ve Java ile derleme . P. 624. ISBN 0-321-26360-X.
- Wirth, Niklaus (1975). Algoritmalar + Veri Yapıları = Programlar . ISBN'si 0-13-022418-9.
- Wirth, Niklaus (1996). Derleyici Yapısı . ISBN'si 0-201-40353-6.
- Liffick, Blaise W., ed. (1979). Pascal'ın Bayt Kitabı . ISBN'si 0-07-037823-1.
- Barron, David William , ed. (1981). Pascal: Dil ve Uygulanması . ISBN'si 0-471-27835-1.(Not. Özellikle Pascal-P Uygulama Notları ve Pascal-S: Bir Alt Küme ve Uygulaması makalelerine bakın .)