p코드 머신

p-code machine

컴퓨터 프로그래밍에서 p코드 머신(휴대용 코드[1] 머신)은 p코드(가상의 중앙처리장치(CPU)의 어셈블리 언어 또는 머신 코드)를 실행하도록 설계된 가상 머신입니다.이 용어는 이러한 모든 머신(Java Virtual Machine(JVM; Java 가상 머신) 및 MATLAB 사전 컴파일 코드 등)과 특정 구현에 모두 일반적으로 적용되며, 특히 Pascal-P 시스템의 p-Machine은 개발자들 사이에서 p-codep-machine으로 해석되는 경우가 많습니다.따라서 의사 기계에 대한 명령을 의미하는 휴대용 의사 코드입니다.

이 개념은 1966년경에 처음 구현되었지만 (기본 복합 프로그래밍 언어(BCPL)의 O-코드 및 오일러 언어[2] P-코드로서) p-코드라는 용어는 1970년대 초에 처음 등장했다.p-code를 생성하는 두 개의 초기 컴파일러는 1973년 Kesav V에 의해 Pascal-P 컴파일러였다.Nori, Urs Ammann, Kathleen Jensen, Hans-Heinrich Négeli, Christian Jacobi [3]및 1975년 Niklaus Worth파스칼-S 컴파일러.

p-code로 변환된 프로그램은 가상 CPU의 동작을 에뮬레이트하는 소프트웨어 프로그램으로 해석하거나 프로그램을 실행하는 CPU의 머신코드로 변환하여 실행할 수 있습니다.충분한 상업적 관심이 있는 경우 CPU 사양의 하드웨어 구현이 구축될 수 있습니다(예를 들어 Pascal MicroEngine 또는 Java 프로세서의 버전).

p-code 구현의 장점과 단점

네이티브 머신 코드로의 직접 변환에 비해 p-code로의 변환과 해석 또는 JIT(Just-in-time Compilation)에 의한 실행을 수반하는 2단계 어프로치에는 몇 가지 이점이 있습니다.

  • 컴파일러를 수정하여 같은 머신의 네이티브 코드를 생성하는 것보다 새로운 머신을 위한 작은 p 코드 인터프리터를 작성하는 것이 훨씬 쉽습니다.
  • 머신 코드를 생성하는 것은 컴파일러 작성의 보다 복잡한 부분 중 하나입니다.이에 비해 바이트 코드를 생성할 때 기계에 의존하는 동작을 고려할 필요가 없기 때문에 p-code 생성은 훨씬 쉽습니다.이를 통해 컴파일러를 빠르게 가동할 수 있습니다.
  • p-code는 이상적인 가상 머신을 기반으로 하기 때문에 p-code 프로그램은 종종 머신 코드로 변환된 동일한 프로그램보다 훨씬 작습니다.
  • p-code가 해석되면 인터프리터는 네이티브코드로는 구현하기 어려운 추가 런타임체크를 적용할 수 있습니다.

p-code의 중요한 단점 중 하나는 실행 속도입니다.이 속도는 때때로 J를 통해 수정될 수 있습니다.IT 컴파일P-code는 종종 네이티브코드보다 리버스 엔지니어링이 용이합니다.

1980년대 초반에는 적어도 두 개의 운영 체제가 광범위한 p-code 사용을 통해 기계 독립성을 달성했습니다.BOS(Business Operating System)는 p-code 프로그램을 독점적으로 실행하도록 설계된 크로스 플랫폼 운영 체제입니다.샌디에이고 캘리포니아 대학에서 개발된 UCSD p-System은 Pascal 언어에 의해 생성되도록 최적화된 p-code를 기반으로 한 자가 컴파일 및 자가[clarification needed] 호스팅 운영 체제였습니다.

1990년대에 p-code로의 변환은 Python, Visual Basic의 Microsoft P-Code, [4][failed verification]JavaJava 바이트 코드와 같은 언어 구현에 있어 인기 있는 전략이 되었습니다.

Go라는 언어는 일반적인 휴대용 어셈블리를 P-코드의 형태로 사용하며, Bell Labs의 Plan 9 작업의 연장선상에서 Ken Thompson에 의해 구현되었습니다.CLR(Common Language Runtime) 바이트 코드나 JVM 바이트 코드와는 달리 안정적인 사양은 없으며 Go 빌드 도구는 나중에 사용할 바이트 코드 형식을 내보내지 않습니다.Go 어셈블러는 일반 어셈블리 언어를 중간 표현으로 사용하며 Go 실행 파일은 시스템별로 정적으로 연결된 [5]이진 파일입니다.

UCSD p-머신

아키텍처

다른 많은 p-code 머신과 마찬가지로 UCSD p-Machine은 스택머신입니다즉, 대부분의 명령어는 스택에서 오퍼랜드를 가져와 결과를 스택으로 되돌립니다.즉,add명령어는 스택의 최상위 2개의 요소를 합계로 바꿉니다.몇 가지 지시에는 즉각적인 논의가 필요합니다.Pascal과 마찬가지로 p-code는 부울(b), 문자(c), 정수(i), 실수(r), 집합(s) 및 포인터(a) 데이터 유형을 네이티브하게 지원하는 강력한 유형입니다.

간단한 절차:

Insn. 스택 설명 adi i1 i2 i1+i2 뒤에 r1 r2 r1+r2 두 개의 정수를 추가하고 i1 s1 is1 set 멤버십을 추가합니다.b1 = i1이 s1 ldi i1 load 정수 mov a1 a2 not b1 b - 1 b 부울링의 멤버인지 여부

환경

다른 스택 기반 환경(: Fourth 및 Java 가상 머신)과 달리 실제 타깃 CPU와 매우 유사하지만 p-System에는 프로시저 스택프레임(반환 주소 제공 등) 및 로컬 명령에 대한 인수로 공유되는 스택이 하나만 있습니다.기계의 레지스터 중 세 개가 스택을 가리키고 있습니다(위쪽으로 증가).

  • SP는 스택의 맨 위(스택 포인터)를 가리킵니다.
  • MP는 액티브스택 프레임(마크포인터)의 시작을 표시합니다.
  • EP는 현재 절차에서 사용되는 가장 높은 스택 위치(익스트림 포인터)를 가리킵니다.

또한 일정한 영역이 존재하며, 그 아래에는 스택을 향해 확장되는 힙이 있습니다.NP(새로운 포인터) 레지스터는 힙의 최상위(최저 사용 주소)를 가리킵니다.EP가 NP보다 커지면 머신의 메모리가 모두 소모됩니다.

다섯 번째 레지스터인 PC는 코드 영역의 현재 명령을 가리킵니다.

호출 규칙

스택 프레임은 다음과 같습니다.

EP -> 로컬스택 SP -> ...locals... 파라미터...반환 주소(이전 PC) 이전 EP 다이내믹 링크(이전 MP) 스태틱 링크(주변 프로시저의 MP) MP -> 함수 반환값

프로시저 호출 시퀀스는 다음과 같이 동작합니다.콜이 도입되는 것은

첫 번째

어디에n는 중첩 수준의 차이를 지정합니다(Pascal은 중첩된 프로시저를 지원합니다).이 명령에서는 스택에 마크를 붙입니다.즉, 위의 스택프레임의 첫 번째 5개의 셀을 예약하고 이전 EP, 다이내믹 및 스태틱링크를 초기화합니다.다음으로 발신자는 프로시저의 파라미터를 계산하고 푸시하여 발행합니다.

컵 n, p

사용자 프로시저를 호출하다(n파라미터의 개수가 됩니다.p(주소)를 참조해 주세요.그러면 반환 주소 셀에 PC가 저장되고 프로시저의 주소가 새 PC로 설정됩니다.

사용자 절차는 두 가지 지침으로 시작합니다.

ent 1, i ent 2, j

첫 번째는 SP를 MP+로 설정합니다.i두 번째는 EP를 SP+로 설정합니다.j.그렇게i기본적으로 로컬용으로 예약된 공간(및 파라미터 수에 5를 더한 값)을 지정합니다.j에 스택에 로컬로 필요한 엔트리 수를 나타냅니다.이 시점에서 메모리 소모가 체크됩니다.

발신자에게의 반송은, 다음의 방법으로 행해집니다.

리트시

와 함께C반환 유형(i, r, c, b, 위와 같은 a, 반환 값 없음)을 지정합니다.반환 값은 미리 적절한 셀에 저장해야 합니다.p를 제외한 모든 유형에서 반환하면 이 값은 스택에 남습니다.

사용자 프로시저(컵)를 호출하는 대신 표준 프로시저q와 함께 부를 수 있다

csp q

이러한 표준 절차는 다음과 같은 Pascal 절차입니다.readln()(csp rln),sin()(csp sin특이하게eof()대신 p-Code 명령입니다.

기계 예시

Niklaus Worth는 1976년 책 Algorithms + Data Structures = Programs에서 단순한 p-code 기계를 지정했습니다.기계에는 프로그램 카운터 p, 베이스 레지스터 b, Top-of-Stack 레지스터 t 등 3개의 레지스터가 있습니다.다음 8가지 지침이 있습니다.

  1. 점등 0, a : 부하 상수 a
  2. opr 0, a : 연산 a 실행 (13 연산: RETURN, 5 연산, 7 비교 함수)
  3. lod l, a : 부하 변수 l,a
  4. sto l, a : 변수 l,a 저장
  5. cal l, a : 레벨1에서의 콜프로시저 a
  6. int 0, a : t-register를 1씩 증가시킵니다.
  7. jmp 0, a : 로의 점프
  8. jpc 0, a : a에 조건부[6] 점프

다음은 Pascal로 작성된 기계 코드입니다.

컨스턴트  암맥스=2047;      {최대 주소}  리맥스=3;       {블록 중첩의 최대 깊이}  최대=200;      {코드 배열 크기}  유형   기능하다=(불을 켰다.,동작,로드,스토우,호출하다,인트,jmp,jpc);  설명=포장된 기록.    f:기능하다;   l:0..리맥스;   a:0..암맥스;  끝.;  변화하다  코드: 배열 [0..최대]  설명;  절차. 해석하다;    컨스턴트 스택 사이즈 = 500;    변화하다     p, b, t: 정수; {program-, base-, topstack-module}     i: 설명; {명령 레지스터}     s: 배열 [1..스택 사이즈]  정수; {filename}    기능. 기초(l: 정수): 정수;     변화하다 b1: 정수;   시작한다.     b1 := b; {기본 레벨 L을 찾습니다}     하는 동안에 l > 0 하다 시작한다.       b1 := s[b1];       l := l - 1     끝.;     기초 := b1   끝. {base};  시작한다.   기입하다('시작 pl/0');   t := 0; b := 1; p := 0;   s[1] := 0; s[2] := 0; s[3] := 0;   따라하다     i := 코드[p]; p := p + 1;     와 함께 i 하다       사례. f          불을 켰다.: 시작한다. t := t + 1; s[t] := a 끝.;         동작:            사례. a  {filename}             0:                시작한다. {return}                 t := b - 1; p := s[t + 3]; b := s[t + 2];               끝.;             1: s[t] := -s[t];             2: 시작한다. t := t - 1; s[t] := s[t] + s[t + 1] 끝.;             3: 시작한다. t := t - 1; s[t] := s[t] - s[t + 1] 끝.;             4: 시작한다. t := t - 1; s[t] := s[t] * s[t + 1] 끝.;             5: 시작한다. t := t - 1; s[t] := s[t] 나누다 s[t + 1] 끝.;             6: s[t] := 주문하다(이상한(s[t]));             8: 시작한다. t := t - 1; s[t] := 주문하다(s[t] = s[t + 1]) 끝.;             9: 시작한다. t := t - 1; s[t] := 주문하다(s[t] << 고객명 >>님 s[t + 1]) 끝.;             10: 시작한다. t := t - 1; s[t] := 주문하다(s[t] < > s[t + 1]) 끝.;             11: 시작한다. t := t - 1; s[t] := 주문하다(s[t] >= s[t + 1]) 끝.;             12: 시작한다. t := t - 1; s[t] := 주문하다(s[t] > s[t + 1]) 끝.;             13: 시작한다. t := t - 1; s[t] := 주문하다(s[t] <=> s[t + 1]) 끝.;           끝.;         로드: 시작한다. t := t + 1; s[t] := s[기초(l) + a] 끝.;         스토우: 시작한다. s[기초(l)+a] := s[t]; 기입하다(s[t]); t := t - 1 끝.;         호출하다:            시작한다. {새 블록 표시 생성}             s[t + 1] := 기초(l); s[t + 2] := b; s[t + 3] := p;             b := t + 1; p := a           끝.;         인트: t := t + a;         jmp: p := a;         jpc: 시작한다. 한다면 s[t] = 0 그리고나서 p := a; t := t - 1 끝.       끝. {with, case}   까지 p = 0;   기입하다('end pl/0'); 끝. {filename}; 

이 기계는 Worth의 PL/0을 실행하는 데 사용되었습니다.이것은 컴파일러 [7][failed verification]개발을 가르치는 데 사용되는 파스칼 서브셋 컴파일러입니다.

Microsoft P-Code

P-Code는 마이크로소프트의 여러 가지 중간 언어의 이름입니다.그들은 기계 코드에 대체 바이너리 형식을 제공했다.마이크로소프트는 p-code가 packed[8] code 또는 pseudo [9]code의 줄임말이라고 여러 차례 말해왔다.

Microsoft p-code는 Visual C++Visual Basic에서 사용되었습니다.다른 p-code 구현과 마찬가지로 Microsoft p-code를 사용하면 실행 속도가 느려지는 대신 보다 콤팩트한 실행 파일을 사용할 수 있습니다.

기타 구현

「 」를 참조해 주세요.

레퍼런스

  1. ^ Upton, Eben; Duntemann, Jeffrey; Roberts, Ralph; Mamtora, Tim; Everard, Ben (2016-09-13). Learning Computer Architecture with Raspberry Pi. John Wiley & Sons. ISBN 978-1-119-18393-8.
  2. ^ Wirth, Niklaus; Weber, Helmut (1966). "EULER: a generalization of ALGOL, and its formal definition: Part II". Communications of the ACM. New York, USA: Association for Computing Machinery (ACM). 9 (2): 89–99. doi:10.1145/365170.365202. S2CID 12124100.
  3. ^ Nori, Kesav V.; Ammann, Urs; Jensen, Kathleen; Nägeli, Hans-Heinrich; Jacobi, Christian (1975). The Pascal P Compiler Implementation Notes. Zürich, Switzerland: Eidgenössische Technische Hochschule (ETH).
  4. ^ "The p-code system".
  5. ^ Pike, Robert C. (2016). "The Design of the Go Assembler". YouTube (Conference talk). Archived from the original on 2021-12-11. Retrieved 2017-08-25.
  6. ^ "Category Archives: Wirth - Euler - Designed by Niklaus Wirth and Helmut Weber". Pascal for small machines - Wirth languages, Pascal, UCSD, Turbo, Delphi, Freepascal, Oberon. 2018-08-02.
  7. ^ Alpert, Donald (September 1979). A Pascal P-Code Interpreter for the Stanford Emmy (PDF) (Report). Computer Systems Laboratory, Departments of Eleotrioal Engineering and Computer Scienoes, Stanford University. Technioal Note No. 164.
  8. ^ Padawer, Andy (April 1992). "Microsoft P-Code Technology". Microsoft Developer Network. Archived from the original on 2001-02-22.
  9. ^ "Compiling Your Project to Native Code". Visual Studio 6.0 Documentation. 2007. Archived from the original on 2007-02-27.

추가 정보

외부 링크