{"id":12175,"date":"2021-11-29T09:46:46","date_gmt":"2021-11-29T08:46:46","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=12175"},"modified":"2023-05-30T14:49:52","modified_gmt":"2023-05-30T12:49:52","slug":"maszyny-wirtualne-interpretery-czesc-i-architektura","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/maszyny-wirtualne-interpretery-czesc-i-architektura\/","title":{"rendered":"Maszyny wirtualne \u2013 interpretery. Cz\u0119\u015b\u0107 I \u2013 Architektura"},"content":{"rendered":"\n<p>Postanowi\u0142em pochyli\u0107 si\u0119 nad tematem maszyn wirtualnych, a konkretnie interpreter\u00f3w. Jest to ciekawe zagadnienie ze wzgl\u0119du na mo\u017cliwe zastosowania. Interpreter mo\u017ce zosta\u0107 uruchomiony niemal\u017ce na ka\u017cdej maszynie, rozpoczynaj\u0105c od mikrokontroler\u00f3w, a\u017c po maszyny serwerowe.<\/p>\n\n\n\n<p>Je\u015bli spojrzymy na zastosowania, jest ich naprawd\u0119 sporo. Zaczynaj\u0105c od bardziej klasycznych, czyli wykonywania program\u00f3w og\u00f3lnego przeznaczenia (np. Python, Perl itd.), tworzenie grafiki i dokument\u00f3w (np. DVI) lub nawet bezstratna kompresje danych (np. kompresory z rodziny lz). Tak naprawd\u0119, wirtualne maszyny da si\u0119 wykorzysta\u0107 wsz\u0119dzie tam, gdzie jest zdefiniowana sta\u0142a lista dyrektyw lub rozkaz\u00f3w.<\/p>\n\n\n\n<p>Dodatkow\u0105 zalet\u0105 wirtualnej maszyny jest ujednolicenie \u015brodowiska uruchomieniowego. Interpreter wykonuje wy\u0142\u0105cznie w\u0142asne instrukcje, niezale\u017cnie na jakiej maszynie fizycznie jest uruchomiony (np. ARM, x86, RISC V ). Mo\u017cna powiedzie\u0107, \u017ce niekt\u00f3re maszyny wirtualne pr\u00f3buj\u0105 podrabia\u0107 w swym dzia\u0142aniu procesory.<\/p>\n\n\n\n<p>Ta <a href=\"https:\/\/sii.pl\/blog\/maszyny-wirtualne-interpretery-czesc-ii-implementacja\/\"><strong>seria artyku\u0142\u00f3w<\/strong><\/a> skupi si\u0119 g\u0142\u00f3wnie na <strong>stworzeniu w\u0142asnego interpretera oraz kompilatora assemblera do bytecode\u2019u.<\/strong><\/p>\n\n\n\n<p>W kolejnych cz\u0119\u015bciach <strong>stworzymy translator<\/strong>, kt\u00f3ry b\u0119dzie t\u0142umaczy\u0142 j\u0119zyk wysokiego poziomu na assembler maszyny.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troch\u0119 teorii dotycz\u0105cej maszyn wirtualnych<\/h2>\n\n\n\n<p>Poj\u0119cie maszyn wirtualnych jest zagadnieniem og\u00f3lnym. Zawiera si\u0119 w nim wiele r\u00f3\u017cnych technologii oraz rozwi\u0105za\u0144. Najcz\u0119\u015bciej kojarz\u0105 si\u0119 one z oprogramowaniem, kt\u00f3re jest w stanie uruchomi\u0107 ca\u0142y system operacyjny \u201eobok\u201d ju\u017c uruchomionego. Temat jest jednak znacznie szerszy.<\/p>\n\n\n\n<p>Rozr\u00f3\u017cniamy poni\u017csze rodzaje maszyn wirtualnych:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>emulatory,<\/li>\n\n\n\n<li>kompilatory JIT,<\/li>\n\n\n\n<li>interpretery.<\/li>\n<\/ul>\n\n\n\n<p><strong>Emulatory<\/strong> to oprogramowanie, kt\u00f3re stawia za cel zasymulowanie w jak najbardziej wierny spos\u00f3b konkretnego rozwi\u0105zania sprz\u0119towego. W tym przypadku emulator odtwarza procesor (uk\u0142ad i funkcje rejestr\u00f3w, peryferia itd.) oraz inne uk\u0142ady mu towarzysz\u0105ce np. akceleratory grafiki itp. Ca\u0142a trudno\u015b\u0107 polega na pokryciu specyficznych zachowa\u0144 sprz\u0119tu (nawet b\u0142\u0119d\u00f3w projektowych). Kolejnym wyzwaniem jest zapewnienie odpowiedniej wydajno\u015bci.<\/p>\n\n\n\n<p><strong>Kompilatory JIT<\/strong> z kolei, stawiaj\u0105 sobie za cel t\u0142umaczenie kodu po\u015bredniego do kodu maszynowego. Celem w tym przypadku jest umo\u017cliwienie uruchomienia kodu uniwersalnego (po\u015bredniego) na r\u00f3\u017cnych platformach sprz\u0119towych z jak najwi\u0119ksz\u0105 wydajno\u015bci\u0105. Tak wiec kompilator JIT jest interpreterem i kompilatorem w jednym.<\/p>\n\n\n\n<p><strong>Interpretery<\/strong>, og\u00f3lnie m\u00f3wi\u0105c, stawiaj\u0105 sobie za cel interpretacj\u0119 dyrektyw. Dyrektywy mog\u0105 by\u0107 zapisane w postaci czytelnej dla cz\u0142owieka, np. przyjmuj\u0105c form\u0119 j\u0119zyka programowania lub w postaci kodu po\u015bredniego np. w formie binarnej. Oczywi\u015bcie stopie\u0144 skomplikowania obu podej\u015b\u0107 jest r\u00f3\u017cny. Wszystko zale\u017cy od architektury oraz zastosowania.<\/p>\n\n\n\n<p>Interpretery dzieli si\u0119 na dwie kategorie:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>rejestrowe,<\/li>\n\n\n\n<li>stosowe.<\/li>\n<\/ul>\n\n\n\n<p>Interpretery rejestrowe z za\u0142o\u017cenia wykorzystuj\u0105 odpowiedniki rejestr\u00f3w znane z procesor\u00f3w do wykonywania operacji logicznych, arytmetycznych itd. Jako przyk\u0142ad mo\u017ce pos\u0142u\u017cy\u0107 maszyna wirtualna Parrot. W przypadku maszyn stosowych wszelkie operacje logiczne, arytmetyczne itd. s\u0105 wykonywane na stosie. Przedstawicielem tego rozwi\u0105zania jest np. Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Za\u0142o\u017cenia<\/h2>\n\n\n\n<p>Aby mo\u017cliwa sta\u0142a si\u0119 realizacja projektu, zdefiniowa\u0142em poni\u017csze za\u0142o\u017cenia:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Interpreter powinien by\u0107 zaprojektowany w taki spos\u00f3b, aby mo\u017cliwe by\u0142o \u0142atwe przeno\u015bnie go na r\u00f3\u017cne konfiguracje sprz\u0119towe.<\/li>\n\n\n\n<li>Rozmiar interpretera powinien by\u0107 jak najmniejszy, tzn. przyj\u0105\u0142em sobie za cel maksymalnie 4 KiB pami\u0119ci ROM. Dzi\u0119ki temu b\u0119dzie mo\u017cliwe uruchomienie maszyny na mikrokontrolerach o ma\u0142ych zasobach.<\/li>\n\n\n\n<li>Potrzebna ilo\u015b\u0107 pami\u0119ci RAM do uruchomienie maszyny mniej ni\u017c 1 KiB. Chodzi tutaj o pami\u0119\u0107 operacyjn\u0105 samej maszyny, nie pami\u0119\u0107 kodu po\u015bredniego.<\/li>\n\n\n\n<li>Instrukcje interpretera powinny by\u0107 proste w implementacji, a ich ilo\u015b\u0107 mo\u017cliwie ograniczona (do sensownego minimum).<\/li>\n\n\n\n<li>Interpreter musi mie\u0107 dost\u0119p do pami\u0119ci w spos\u00f3b liniowy (adresowanie bajtowe).<\/li>\n\n\n\n<li>Wirtualna maszyn\u0105 b\u0119dzie maszyna rejestrowa.<\/li>\n\n\n\n<li>Interpreter b\u0119dzie operowa\u0142 na kodzie po\u015brednim w formie binarnej.<\/li>\n\n\n\n<li>Operacje na liczbach 32-bitowych ca\u0142kowitych.<\/li>\n\n\n\n<li>Instrukcje b\u0119d\u0105 zmiennej szeroko\u015bci.<\/li>\n\n\n\n<li>Interpreter nie musi by\u0107 optymalny, tzn. b\u0119dzie to zabawka do poszerzenia wiedzy.<\/li>\n<\/ul>\n\n\n\n<p>Powy\u017csze za\u0142o\u017cenia wymuszaj\u0105 prostot\u0119 rozwi\u0105zania. Celem tego artyku\u0142u jest <strong>przekazanie idei<\/strong>.<br>Kolejnym, nie mniej wa\u017cnym, aspektem jest czas realizacji projektu. Przy z\u0142o\u017conym projekcie czas potrzebny na analiz\u0119, a p\u00f3\u017aniej na implementacj\u0119, by\u0142by zbyt d\u0142ugi oraz wymaga\u0142by wi\u0119cej r\u0105k do pracy. Tak\u017ce prostota rozwi\u0105zania jest na nasz\u0105 korzy\u015b\u0107 w ka\u017cdym aspekcie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Architektura<\/h2>\n\n\n\n<p>Jak ju\u017c wiemy, interpreter b\u0119dzie maszyn\u0105 wirtualn\u0105 rejestrow\u0105. Wyb\u00f3r ten jest podyktowany blisko\u015bci\u0105 do tego, co wi\u0119kszo\u015b\u0107 programist\u00f3w obserwuje programuj\u0105c mikrokontrolery. Za\u0142o\u017cy\u0142em, ze b\u0119dzie to prostsze do zrozumienia i bardziej intuicyjne.<\/p>\n\n\n\n<p>Jak ka\u017cdy wie, wi\u0119kszo\u015b\u0107 procesor\u00f3w posiada pewna okre\u015blon\u0105 pul\u0119 rejestr\u00f3w. Rejestry te pe\u0142ni\u0105 okre\u015blone funkcje. Tak wiec mamy rejestry:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>og\u00f3lnego przeznaczenia,<\/li>\n\n\n\n<li>kontrolne,<\/li>\n\n\n\n<li>statusu.<\/li>\n<\/ul>\n\n\n\n<p>Oczywi\u015bcie mo\u017ce ich by\u0107 wi\u0119cej, ale jest to minimum potrzebne nam do zrealizowania celu.<\/p>\n\n\n\n<p>Podobnie jak w mikrokontrolerach, nasza maszyna b\u0119dzie posiada\u0107 r\u00f3wnie\u017c stos. Jest on przydatny do przechowywania danych oraz wykonywania skok\u00f3w.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rejestry<\/h2>\n\n\n\n<p>Na pocz\u0105tku zajmiemy si\u0119 rejestrami og\u00f3lnego przeznaczenia. Postanowi\u0142em, \u017ce b\u0119dzie ich 16. Rejestry te pos\u0142u\u017c\u0105 do wykonywania r\u00f3\u017cnych operacji: arytmetycznych, logicznych itp. Dla lepszego zobrazowania b\u0119dziemy je nazywa\u0107<em> r0 . . . r15<\/em>. Oczywi\u015bcie, nic nie stoi na przeszkodzie, \u017ceby by\u0142o ich 8, 32 lub wi\u0119cej.<\/p>\n\n\n\n<p>Kolejn\u0105 grup\u0105 rejestr\u00f3w jest grupa kontroluj\u0105ca maszyn\u0119. Tutaj znajdziemy rejestr <strong>PC (Program Counter)<\/strong>, kt\u00f3ry to wskazuje na aktualny adres pami\u0119ci wykonywanego kodu. Nast\u0119pny to <strong>SP (Stack Pointer)<\/strong>. Jego celem jest wskazanie wierzcho\u0142ka stosu. Dodatkowym rejestrem jest rejestr statusu <strong>SR (Status Register)<\/strong>, kt\u00f3ry s\u0142u\u017cy do przechowywania flag informuj\u0105cych o stanie maszyny lub wykonanej operacji. Tak wi\u0119c do dyspozycji posiadamy flagi:<\/p>\n\n\n\n<p><strong>Z<\/strong> \u2014 warto\u015b\u0107 rejestru docelowego wynosi 0,<br><strong>NZ<\/strong> \u2014 warto\u015b\u0107 rejestru docelowego jest r\u00f3\u017cna od 0,<br><strong>EQ<\/strong> \u2014 warto\u015bci s\u0105 r\u00f3wne,<br><strong>NE<\/strong> \u2014 warto\u015bci s\u0105 r\u00f3\u017cne,<br><strong>GT<\/strong> \u2014 argument 1 jest wi\u0119kszy od argumentu 2,<br><strong>LT<\/strong> \u2014 argument 1 jest mniejszy od argumentu 2,<br><strong>ME<\/strong> \u2014 b\u0142\u0105d pami\u0119ci (np. adres poza zakresem),<br><strong>DZ<\/strong> \u2014 b\u0142\u0105d dzielenia (dzielenie przez 0).<\/p>\n\n\n\n<p>Tak naprawd\u0119 wystarczy\u0142by 3 flagi <strong>EQ<\/strong>, <strong>GT<\/strong> oraz<strong> Z,<\/strong> aby pokry\u0107 wszystkie przypadki. Ze wzgl\u0119du na prostot\u0119 rozwi\u0105zania, postanowi\u0142em rozszerzy\u0107 list\u0119 flag. Pozwoli to w p\u00f3\u017aniejszym etapie upro\u015bci\u0107 instrukcje skoku warunkowego. Postanowi\u0142em, \u017ceby dost\u0119p do rejestr\u00f3w og\u00f3lnego przeznaczenia i rejestr\u00f3w kontrolnych maszyny, by\u0142 jednolity, tzn. znajdowa\u0142 si\u0119 w tej samej \u201eprzestrzeni adresowej\u201d.<br>Pozwoli to na zmniejszenie ilo\u015bci instrukcji oraz je upro\u015bci.<\/p>\n\n\n\n<p>Zatem, rejestry kontrolne b\u0119d\u0105 przedstawiane jako kolejne rejestry og\u00f3lnego przeznaczenia:<br><em>r16 (PC), r17 (SP), r18 (SR)<\/em>. Mamy w sumie do dyspozycji 19 rejestr\u00f3w.<\/p>\n\n\n\n<p>Zosta\u0142o to zobrazowane w tabeli 1.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter wp-image-12178 size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tabela-1.-2.png\"><img decoding=\"async\" width=\"526\" height=\"467\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tabela-1.-2.png\" alt=\"Tabela prezentuj\u0105ca uk\u0142ad rejestr\u00f3w\" class=\"wp-image-12178\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tabela-1.-2.png 526w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tabela-1.-2-300x266.png 300w\" sizes=\"(max-width: 526px) 100vw, 526px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 1 Uk\u0142ad rejestr\u00f3w<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Stos<\/h2>\n\n\n\n<p>Rejestr <strong>SP<\/strong> zwiera adres wierzcho\u0142ka stosu. Dla uproszczenia interpreter nie b\u0119dzie posiada\u0142 kontroli stosu. Nic jednak nie stoi na przeszkodzie, aby tak\u0105 funkcjonalno\u015b\u0107 doda\u0107.<\/p>\n\n\n\n<p>Dane na stos b\u0119d\u0105 wrzucane poprzez odpowiednie instrukcje, po czym nast\u0119powa\u0107 b\u0119dzie inkrementacja adresu. Odwrotn\u0105 operacj\u0105 jest zdejmowanie warto\u015bci ze stosu. W tym przypadku adres stosu zostanie najpierw zmniejszony, a nast\u0119pnie warto\u015b\u0107 zostanie przekazana.<\/p>\n\n\n\n<p>Adresowanie stosu b\u0119dzie bajtowe. Tak wi\u0119c, wrzucenie na stos s\u0142owa maszyny spowoduje zwi\u0119kszenie adresu o 4 (32-bit), pobranie niezmniejszenie o 4. Wynika to z za\u0142o\u017cenia, ze pami\u0119\u0107 jest liniowa i adresowana bajtowo. Pami\u0119\u0107 operacyjna interpretera jest wsp\u00f3lna ze stosem. Rozmiar stosu oraz jego po\u0142o\u017cenie b\u0119dzie zale\u017cne od programisty.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Instrukcje<\/h2>\n\n\n\n<p>Generalnie instrukcja b\u0119dzie kodowana w jednym bajcie danych. B\u0119dziemy go nazywa\u0107 jako <em>opcode<\/em>. Dodatkowe bajty danych b\u0119d\u0105 ju\u017c zale\u017cne od u\u017cytej instrukcji. Ze wzgl\u0119du na to, \u017ce maszyna wirtualna b\u0119dzie operowa\u0107 maksymalnie na dw\u00f3ch operandach, <em>opcode<\/em> instrukcji b\u0119dzie zawiera\u0107 dodatkowe informacje, czy instrukcja odnosi si\u0119 do rejestru, czy do sta\u0142ej. Rysunek 1 przedstawia bajt <em>opcode<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12180\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-1-4.png\"><img decoding=\"async\" width=\"551\" height=\"59\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-1-4.png\" alt=\"Tabela prezentuj\u0105ca budow\u0119 bajtu opcode\" class=\"wp-image-12180\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-1-4.png 551w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-1-4-300x32.png 300w\" sizes=\"(max-width: 551px) 100vw, 551px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 Budowa bajtu opcode<\/figcaption><\/figure>\n\n\n\n<p>Jak przedstawiono, mamy do dyspozycji 6 bit\u00f3w na kodowanie instrukcji, co daje nam do dyspozycji maksymalnie 64 instrukcje. Oznaczenia <em>arg 0<\/em> oraz <em>arg 1<\/em> odnosz\u0105 si\u0119 do rodzaju argumentu \u2014 rejestr (1) lub sta\u0142a (0) odpowiednio dla danego operandu. Przyk\u0142ady przedstawiono w tabeli 2. W przypadku instrukcji, kt\u00f3re posiadaj\u0105 tylko jeden argument, wy\u0142\u0105cznie jedno pole b\u0119dzie brane pod uwag\u0119 (<em>arg 0<\/em>).<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12181\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-2.png\"><img decoding=\"async\" width=\"795\" height=\"177\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-2.png\" alt=\"Tabela prezentuj\u0105ca przyk\u0142ady kodowania instrukcji\" class=\"wp-image-12181\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-2.png 795w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-2-300x67.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-2-768x171.png 768w\" sizes=\"(max-width: 795px) 100vw, 795px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 2 Przyk\u0142ady kodowania instrukcji<\/figcaption><\/figure>\n\n\n\n<p>Jak przedstawiono na przyk\u0142adzie, instrukcje posiadaj\u0105 r\u00f3\u017cn\u0105 szeroko\u015b\u0107, nawet je\u015bli wykonuj\u0105 t\u0119 sam\u0105 operacj\u0119. Wynika to z tego, ze interpreter b\u0119dzie m\u00f3g\u0142 operowa\u0107 bezpo\u015brednio na rejestrach oraz sta\u0142ych. Sta\u0142e warto\u015bci s\u0105 zawsze 4-bajtowe, zapisane w kolejno\u015bci little endian.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Operacje wykonywane przez maszyn\u0119 wirtualn\u0105<\/h3>\n\n\n\n<p>Maszyna wirtualna b\u0119dzie wykonywa\u0142a nast\u0119puj\u0105ce operacje:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>arytmetyczne,<\/li>\n\n\n\n<li>logiczne,<\/li>\n\n\n\n<li>transferu danych,<\/li>\n\n\n\n<li>skoku.<\/li>\n<\/ul>\n\n\n\n<p>Szczeg\u00f3\u0142y zosta\u0142y przedstawione w tabelach 3, 4, 5, 6 oraz 7 poni\u017cej.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12184\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-3.png\"><img decoding=\"async\" width=\"797\" height=\"226\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-3.png\" alt=\"Tabela prezentuj\u0105ca instrukcje arytmetyczne\" class=\"wp-image-12184\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-3.png 797w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-3-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-3-768x218.png 768w\" sizes=\"(max-width: 797px) 100vw, 797px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 3 Instrukcje arytmetyczne<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12185\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-4.png\"><img decoding=\"async\" width=\"796\" height=\"225\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-4.png\" alt=\"Tabela prezentuj\u0105ca instrukcje logiczne\" class=\"wp-image-12185\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-4.png 796w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-4-300x85.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-4-768x217.png 768w\" sizes=\"(max-width: 796px) 100vw, 796px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 4 Instrukcje logiczne<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12186\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-5.png\"><img decoding=\"async\" width=\"796\" height=\"259\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-5.png\" alt=\"Tabela prezentuj\u0105ca instrukcj\u0119 skoku\" class=\"wp-image-12186\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-5.png 796w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-5-300x98.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-5-768x250.png 768w\" sizes=\"(max-width: 796px) 100vw, 796px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 5 Instrukcja skoku<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12187\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-6.png\"><img decoding=\"async\" width=\"795\" height=\"82\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-6.png\" alt=\"Tabela prezentuj\u0105ca instrukcj\u0119 transferu danych\" class=\"wp-image-12187\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-6.png 795w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-6-300x31.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-6-768x79.png 768w\" sizes=\"(max-width: 795px) 100vw, 795px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 6 Instrukcja wywo\u0142a\u0144 systemowych<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full wp-image-12188\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-7.png\"><img decoding=\"async\" width=\"796\" height=\"579\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-7.png\" alt=\"Tabela prezentuj\u0105ca instrukcje transferu danych\" class=\"wp-image-12188\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-7.png 796w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-7-300x218.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Tab.-7-768x559.png 768w\" sizes=\"(max-width: 796px) 100vw, 796px\" \/><\/a><figcaption class=\"wp-element-caption\">Tab. 7 Instrukcje transferu danych<\/figcaption><\/figure>\n\n\n\n<p>Instrukcje <strong>push<\/strong> oraz <strong>pop<\/strong> odpowiedzialne s\u0105 za umieszczanie oraz pobieranie danych ze stosu. Obie instrukcje posiadaj\u0105 dwa operandy. Ka\u017cdy z operand\u00f3w mo\u017ce by\u0107 rejestrem lub sta\u0142\u0105. W zale\u017cno\u015bci od wyboru, instrukcje b\u0119d\u0105 dzia\u0142a\u0107 nieco inaczej.<\/p>\n\n\n\n<p>Pierwszy argument <em>a0<\/em> mo\u017ce przyj\u0105\u0107 rejestr lub sta\u0142\u0105. W przypadku podania rejestru, instrukcja push lub pop b\u0119dzie pobiera\u0107 lub zapisywa\u0107 warto\u015b\u0107 rozpoczynaj\u0105c od podanego rejestru, przechodz\u0105c przez kolejne rejestry w zale\u017cno\u015bci od zdefiniowanej ilo\u015bci. Drugi argument <em>a1<\/em> zawsze okre\u015bla ilo\u015b\u0107 element\u00f3w, kt\u00f3re nale\u017cy umie\u015bci\u0107 lub zdj\u0105\u0107 ze stosu. Ilo\u015b\u0107 mo\u017ce by\u0107 zdefiniowana jako warto\u015b\u0107 dodatnia lub ujemna.<\/p>\n\n\n\n<p>Warto\u015bci dodatnie oraz ujemne zawsze okre\u015blaj\u0105 ilo\u015b\u0107 element\u00f3w (co do warto\u015bci absolutnej), kt\u00f3re nale\u017cy umie\u015bci\u0107 lub pobra\u0107 ze stosu.<\/p>\n\n\n\n<p>Na przyk\u0142ad <strong>push r2 5<\/strong> spowoduje umieszczenie na stosie kolejno warto\u015bci z rejestr\u00f3w: <em>r2, r3, r4, r5 i r6.<\/em><\/p>\n\n\n\n<p>Natomiast ilo\u015b\u0107 ze znakiem \u201e\u2013\u201d spowoduje dekrementacje licznika rejestru, tak jak na przyk\u0142adzie: <strong>push r8 -5<\/strong>, umie\u015bci na stosie rejestry: <em>r8, r7, r6, r5 i r4.<\/em><\/p>\n\n\n\n<p>W przypadku rejestr\u00f3w spoza zakresu, warto\u015b\u0107 poprzednia zostanie wstawiona. Podobna sytuacja dotyczy instrukcji pop z t\u0105 r\u00f3\u017cnica\u0105, \u017ce warto\u015bci s\u0105 pobierane ze stosu.<br>Instrukcje operacji na stosie jako argument a0 mog\u0105 przyj\u0105\u0107 r\u00f3wnie\u017c sta\u0142\u0105. <strong>Push<\/strong> umie\u015bci na stosie podan\u0105 warto\u015b\u0107 zdefiniowan\u0105 ilo\u015b\u0107 razy na stosie. Pop natomiast zdejmie ze stosu bez innych efekt\u00f3w.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-2-1.png\"><img decoding=\"async\" width=\"694\" height=\"341\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-2-1.png\" alt=\"Instrukcje push i pop\" class=\"wp-image-12191\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-2-1.png 694w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Ryc.-2-1-300x147.png 300w\" sizes=\"(max-width: 694px) 100vw, 694px\" \/><\/a><\/figure>\n\n\n\n<p>Instrukcje te wydaj\u0105 si\u0119 do\u015b\u0107 skomplikowane, ale z punktu widzenia implementacji maszyny sprawa wygl\u0105da znacznie pro\u015bciej. Poni\u017cszy przyk\u0142ad przedstawia przyk\u0142adowe u\u017cycie instrukcji <strong>push<\/strong> i <strong>pop<\/strong>:<\/p>\n\n\n\n<p>To wszystko w tej cz\u0119\u015bci artyku\u0142u. <a href=\"https:\/\/sii.pl\/blog\/maszyny-wirtualne-interpretery-czesc-ii-implementacja\/?category=development-na-twardo&amp;tag=embedded%2Cinterpreter%2Cmaszyna-wirtualna&amp;preview_id=12802&amp;preview_nonce=985480ce1f&amp;preview=true&amp;_thumbnail_id=12196\" target=\"_blank\" rel=\"noopener\">W kolejnej cz\u0119\u015bci zajmiemy si\u0119 implementacj\u0105 naszej maszyny wirtualnej<\/a> zgodnej z wymaganiami oraz zdefiniowanymi instrukcjami.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;12175&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;6&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 6)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Maszyny wirtualne \u2013 interpretery. Cz\u0119\u015b\u0107 I \u2013 Architektura&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 6)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Postanowi\u0142em pochyli\u0107 si\u0119 nad tematem maszyn wirtualnych, a konkretnie interpreter\u00f3w. Jest to ciekawe zagadnienie ze wzgl\u0119du na mo\u017cliwe zastosowania. Interpreter &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/maszyny-wirtualne-interpretery-czesc-i-architektura\/\">Continued<\/a><\/p>\n","protected":false},"author":248,"featured_media":12196,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":6,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[563,1169,1168],"class_list":["post-12175","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-embedded","tag-interpreter","tag-maszyna-wirtualna"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/11\/Maszyny-wirtualne-interpretery.-Czesc-I-Architektura.png","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/12175"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/248"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=12175"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/12175\/revisions"}],"predecessor-version":[{"id":22056,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/12175\/revisions\/22056"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/12196"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=12175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=12175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=12175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}