Jump to content

машина p-кода

(Перенаправлено с Microsoft P-Code )

В компьютерном программировании используется машина p-кода ( портативная кодовая машина). [1] ) — это виртуальная машина, предназначенная для выполнения p-кода ( языка ассемблера или машинного кода гипотетического центрального процессора (ЦП)). Этот термин применяется как в целом ко всем таким машинам (таким как виртуальная машина Java (JVM) и предварительно скомпилированный код MATLAB ), так и к конкретным реализациям, наиболее известной из которых является p-машина системы Pascal-P , особенно Реализация UCSD Pascal , среди разработчиков которой буква p в p-коде истолковывалась как псевдокод, чаще чем как портативный , таким образом, псевдокод означал инструкции для псевдомашины.

Хотя концепция была впервые реализована примерно в 1966 году как O-код для базового комбинированного языка программирования ( BCPL ) и P-код для языка Эйлера , [2] термин . p-код впервые появился в начале 1970-х годов Двумя ранними компиляторами, генерирующими p-код, были компилятор Pascal-P 1973 года, созданный Кесавом В. Нори, Урсом Амманном, Кэтлин Йенсен, Хансом-Генрихом Нэгели и Кристианом Якоби. [3] и компилятор Pascal-S в 1975 году, созданный Никлаусом Виртом .

Программы, переведенные в p-код, могут быть либо интерпретированы программой, которая имитирует поведение гипотетического ЦП, либо переведены в машинный код ЦП, на котором программа должна запускаться, а затем выполняться. Если существует достаточный коммерческий интерес, может быть создана аппаратная реализация спецификации ЦП (например, Pascal MicroEngine или версия процессора Java ).

Преимущества и недостатки внедрения p-кода

[ редактировать ]

По сравнению с прямой трансляцией в собственный машинный код двухэтапный подход, включающий трансляцию в p-код и выполнение путем интерпретации или JIT- компиляции , дает несколько преимуществ.

  • Гораздо проще написать небольшой интерпретатор p-кода для новой машины, чем модифицировать компилятор для генерации собственного кода для той же машины.
  • Генерация машинного кода — одна из наиболее сложных частей написания компилятора. не нужно учитывать машинно-зависимое поведение Для сравнения, генерация p-кода намного проще, поскольку при генерации байт-кода . Это делает его полезным для быстрого запуска и запуска компилятора.
  • Поскольку p-код основан на идеальной виртуальной машине, программа с p-кодом часто намного меньше той же программы, переведенной в машинный код.
  • При интерпретации p-кода интерпретатор может применять дополнительные проверки во время выполнения , которые сложно реализовать с помощью машинного кода.

Одним из существенных недостатков p-кода является скорость выполнения, которую иногда можно исправить с помощью компиляции Just-in-time . P-код часто легче перепроектировать, чем собственный код.

Реализации p-кода

[ редактировать ]

В начале 1980-х годов по крайней мере две операционные системы достигли машинной независимости благодаря широкому использованию p-кода. Бизнес -операционная система (BOS) представляла собой кросс-платформенную операционную систему, предназначенную исключительно для запуска программ p-кода. UCSD p-System , разработанная в Калифорнийском университете в Сан-Диего, представляла собой самокомпилируемую и саморазмещающуюся [ нужны разъяснения ] операционную систему, основанную на p-коде, оптимизированном для генерации языком Паскаль .

В 1990-х годах перевод в p-код стал популярной стратегией реализации таких языков, как Python , Microsoft P-Code в Visual Basic и байт-код Java в Java .

В языке Go используется универсальная переносимая сборка как форма p-кода, реализованная Кеном Томпсоном как расширение работы над Plan 9 от Bell Labs . В отличие от байт-кода Common Language Runtime (CLR) или байт-кода JVM, здесь не существует стабильной спецификации, а инструменты сборки Go не создают формат байт-кода, который будет использоваться позже. Ассемблер Go использует общий язык ассемблера в качестве промежуточного представления двоичные файлы , специфичные для конкретной машины , а исполняемые файлы Go представляют собой статически связанные . [4]

UCSD p-машина

[ редактировать ]

Архитектура

[ редактировать ]

Как и многие другие машины с p-кодом, UCSD p-Machine является стековой машиной , что означает, что большинство инструкций берут свои операнды из стека и помещают результаты обратно в стек. Таким образом, add Инструкция заменяет два верхних элемента стека их суммой. Несколько инструкций требуют немедленного аргумента. Как и в Паскале, p-код строго типизирован и изначально поддерживает логический (b), символьный (c), целочисленный (i), вещественный (r), наборный (s) и указательный (a) типы данных .

Несколько простых инструкций:

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   b1      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

Подобно реальному целевому процессору, p-система имеет только один стек, общий для кадров стека процедур (обеспечивающий адрес возврата и т. д.) и аргументы для локальных инструкций. машины Три регистра указывают на стек (который растет вверх):

Также присутствует постоянная область, а под ней — куча , растущая вниз к стопке. Регистр NP ( новый указатель ) указывает на вершину (наименьший используемый адрес) кучи. Когда EP становится больше, чем NP, память машины исчерпывается.

Пятый регистр PC указывает на текущую инструкцию в области кода.

Соглашения о вызовах

[ редактировать ]

Кадры стека выглядят следующим образом:

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

Последовательность вызова процедуры работает следующим образом: Вызов начинается с

 mst n

где n определяет разницу в уровнях вложенности (помните, что Паскаль поддерживает вложенные процедуры). Эта инструкция пометит стек, т.е. зарезервирует первые пять ячеек вышеуказанного кадра стека и инициализирует предыдущую EP, динамическую и статическую ссылку. Затем вызывающая сторона вычисляет и передает любые параметры процедуры, а затем выдает

 cup n, p

вызвать пользовательскую процедуру ( n количество параметров, p адрес процедуры). Это сохранит ПК в ячейке обратного адреса и установит адрес процедуры в качестве нового ПК.

Пользовательские процедуры начинаются с двух инструкций

 ent 1, i
 ent 2, j

Первый устанавливает SP в MP+ i, второй устанавливает EP в SP + j. Так i по существу указывает пространство, зарезервированное для локальных пользователей (плюс количество параметров плюс 5), и j дает количество записей, необходимых локально для стека. На этом этапе проверяется исчерпание памяти.

Возврат к вызывающему абоненту осуществляется через

 retC

с C задавая тип возвращаемого значения (i, r, c, b, a, как указано выше, и p для отсутствия возвращаемого значения). Возвращаемое значение должно быть предварительно сохранено в соответствующей ячейке. Для всех типов, кроме p, возврат оставит это значение в стеке.

Вместо вызова пользовательской процедуры (чашки) используется стандартная процедура q можно вызвать с помощью

 csp q

Этими стандартными процедурами являются процедуры Паскаля, такие как readln() ( csp rln), sin() ( csp sin) и т. д. Своеобразно eof() вместо этого является инструкцией p-кода.

Пример машины

[ редактировать ]

Никлаус Вирт описал простую машину с кодом p-кода в книге 1976 года «Алгоритмы + структуры данных = программы» . Машина имела 3 регистра — программный счетчик p , базовый регистр b и регистр вершины стека t . Было 8 инструкций:

  1. lit 0, a : постоянная нагрузка а
  2. opr 0, a : выполнить операцию а (13 операций: ВОЗВРАТ, 5 математических функций и 7 функций сравнения)
  3. lod l, a : загрузить переменную л , а
  4. sto l, a : сохранить переменную л , а
  5. cal l, a : процедура вызова уровне на л
  6. int 0, a : увеличить t-регистр на а
  7. jmp 0, a : перейти к а
  8. jpc 0, a : переход по условию на а [5]

Это код машины, написанный на языке Паскаль:

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};

Эта машина использовалась для запуска PL/0 Вирта , подмножества компилятора Паскаля, используемого для обучения разработке компиляторов. [6] [ не удалось пройти проверку ]

Microsoft P-код

[ редактировать ]

P-Code — это название нескольких Microsoft проприетарных промежуточных языков . Они предоставили альтернативный двоичный формат машинному коду . В разное время Microsoft заявляла, что p-code — это аббревиатура для упакованного кода. [7] или псевдокод . [8]

Microsoft p-code использовался в Visual C++ и Visual Basic . Как и другие реализации p-кода, p-code Microsoft позволил сделать исполняемый файл более компактным за счет более медленного выполнения.

Другие реализации

[ редактировать ]

См. также

[ редактировать ]
  1. ^ Аптон, Эбен; Дантеманн, Джеффри; Робертс, Ральф; Мамтора, Тим; Эверард, Бен (13 сентября 2016 г.). Изучение архитектуры компьютера с помощью Raspberry Pi . Джон Уайли и сыновья. ISBN  978-1-119-18393-8 .
  2. ^ Вирт, Никлаус ; Вебер, Гельмут (1966). «ЭЙЛЕР: обобщение АЛГОЛА и его формальное определение: Часть II» . Коммуникации АКМ . 9 (2). Нью-Йорк, США: Ассоциация вычислительной техники (ACM): 89–99. дои : 10.1145/365170.365202 . S2CID   12124100 .
  3. ^ Нори, Кесав В.; Амманн, Урс; Дженсен, Кэтлин; Нэгели, Ганс-Генрих; Якоби, Кристиан (1975). Замечания по реализации компилятора Pascal P. Цюрих, Швейцария: Швейцарский федеральный технологический институт (ETH).
  4. ^ Пайк, Роберт С. (2016). «Проектирование ассемблера Go» . YouTube (выступление на конференции). Архивировано из оригинала 11 декабря 2021 г. Проверено 25 августа 2017 г.
  5. ^ «Архивы категорий: Вирт - Эйлер - Разработано Никлаусом Виртом и Гельмутом Вебером» . Паскаль для небольших машин — вирт-языки, Pascal, UCSD, Turbo, Delphi, Freepascal, Oberon . 2018-08-02.
  6. ^ Альперт, Дональд (сентябрь 1979 г.). Интерпретатор P-кода Паскаля для Стэнфордской премии «Эмми» (PDF) (Отчет). Лаборатория компьютерных систем, факультеты элеотриальной инженерии и компьютерных наук, Стэнфордский университет. Техническая нота № 164.
  7. ^ Падавер, Энди (апрель 1992 г.). «Технология Microsoft P-Code» . Сеть разработчиков Microsoft . Архивировано из оригинала 22 февраля 2001 г.
  8. ^ «Компиляция вашего проекта в нативный код» . Документация Visual Studio 6.0 . 2007. Архивировано из оригинала 27 февраля 2007 г.

Дальнейшее чтение

[ редактировать ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 2ed16ec5f2bd8153c6080b71242226ee__1721269500
URL1:https://arc.ask3.ru/arc/aa/2e/ee/2ed16ec5f2bd8153c6080b71242226ee.html
Заголовок, (Title) документа по адресу, URL1:
p-code machine - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)