JavaRush /Blog Java /Random-PL /Kod maszynowy i kod bajtowy: w jakim języku mówi Twój pro...

Kod maszynowy i kod bajtowy: w jakim języku mówi Twój program?

Opublikowano w grupie Random-PL
Ci, którzy dopiero zaczynają zapoznawać się z Javą, często mylą się z pojęciami kodu maszynowego i kodu bajtowego . Czym oni są? Jakie są różnice? W krótkiej notatce postaramy się opisać ich cechy tak prosto i przejrzyście, jak to możliwe, aby raz na zawsze zamknąć tę kwestię.
Kod maszynowy i kod bajtowy: w jakim języku mówi Twój program?  - 1

Kod maszynowy

Procesor jest w istocie bardzo złożonym i zaawansowanym kalkulatorem. Posiada wiele lokalizacji pamięci (zwanych rejestrami), na których i pomiędzy którymi wykonywane są różne operacje matematyczne i bajtowe. Kod maszynowy to dokładny opis sekwencji operacji i zestawu danych. W rzeczywistości jest to jedyny język, jaki rozumie procesor Twojego komputera.

Wrodzona niezgodność

Jednocześnie nie wszystkie procesory „mówią” tym samym językiem. Istnieją różnice nie tylko pomiędzy architekturami CISC i RISC , ale także w obrębie tych „obozów”.

CISC (Complex Order Set Computing) to koncepcja projektowania procesora charakteryzująca się następującym zestawem właściwości:

  • wiele poleceń o różnej długości;
  • wiele trybów adresowania;
  • złożone kodowanie instrukcji.
RISC (Reduced Order Set Computing) – procesor ze zredukowanym zestawem instrukcji. Polecenia mają ten sam format, są krótkie i mają proste kodowanie.
Nowe generacje procesorów wprowadzają dodatkowe zestawy instrukcji, które są po prostu nieznane modelom starszej generacji. Z tego powodu programy skompilowane dla jednej architektury (lub jednej generacji procesorów) nie mogą działać na innym sprzęcie. Wszystko to zmusza nas do ponownej kompilacji programów, aby mieć pewność, że działają na innych komputerach. Jednak rekompilację trzeba przeprowadzić nie tylko ze względu na procesory, ale także ze względu na różnice w interakcji programów i systemu operacyjnego. To właśnie z ich powodu nie da się uruchomić programu „Windows” pod Linuksem, a programu „Linux” pod Windowsem.

Kod bajtowy

Kod bajtowy pod wieloma względami przypomina kod maszynowy, tyle że wykorzystuje zestaw instrukcji nie z prawdziwego procesora, ale z wirtualnego. Ponadto może zawierać sekcje skupiające się na wykorzystaniu kompilatora JIT , który optymalizuje wykonywanie poleceń dla rzeczywistego procesora, na którym uruchomiony jest program.
Kompilacja JIT (kompilacja just-in-time, kompilacja w locie) lub kompilacja dynamiczna (tłumaczenie dynamiczne) to technologia zwiększająca wydajność systemów oprogramowania korzystających z kodu bajtowego poprzez kompilację kodu bajtowego do kodu maszynowego lub do innego formatu bezpośrednio podczas program jest uruchomiony. „Oficjalnie” w Javie do wersji 9 istniał tylko kompilator JIT. W Javie 9 pojawił się inny kompilator, który kompiluje się z wyprzedzeniem (AoT). Ta funkcja umożliwia kompilację klas Java do kodu natywnego przed uruchomieniem na maszynie wirtualnej. Ta funkcja ma na celu skrócenie czasu uruchamiania zarówno małych, jak i dużych aplikacji, przy ograniczonym wpływie na maksymalną wydajność.
W przypadku procesorów CISC niektóre instrukcje można łączyć w bardziej złożone struktury obsługiwane przez procesor, a w przypadku RISC wręcz przeciwnie, można je rozbić na prostsze ciągi instrukcji.

Również wirtualny system operacyjny

Jednak kod bajtowy zawiera nie tylko instrukcje procesora. Zawiera także logikę interakcji z wirtualnym systemem operacyjnym, dzięki czemu zachowanie aplikacji jest niezależne od systemu operacyjnego używanego na komputerze. Widać to wyraźnie w JVM , gdzie praca z wywołaniami systemowymi i GUI często jest niezależna od systemu operacyjnego, na którym uruchomiony jest program. Ogólnie rzecz biorąc, JVM emuluje uruchomienie procesu programu, w przeciwieństwie do rozwiązań takich jak Virtual Box , które tworzą jedynie wirtualny system/sprzęt.

Czy JVM jest jedyny taki?

Absolutnie nie. Ten sam DotNet CLI jest jednocześnie maszyną wirtualną, z której najczęściej korzysta się na komputerach z systemem Windows i procesorami kompatybilnymi z x86 . Istnieje jednak implementacja dla innych systemów: aplikacje dla niego muszą działać w systemie Windows RT działającym na procesorach zgodnych z ARM (RISC) lub można je uruchamiać w systemie Linux/OSX w środowisku Mono , które jest oprogramowaniem innej firmy (a zatem nie w pełni kompatybilny) implementacja DotNet dla tych platform. Zatem ta platforma, podobnie jak JVM , działa na różnych procesorach i różnych systemach operacyjnych. Podobnych rozwiązań (starych i nowych) jest znacznie więcej: LLVM , Flash SWF i inne. Niektóre języki programowania mają własne maszyny wirtualne. Na przykład CPython kompiluje źródła PY do plików PYC - skompilowanego kodu bajtowego, który jest przygotowany do uruchomienia w PVM . Lub istnieje znacznie starszy przykład - Lisp można skompilować do plików FASL (Fast Load). W rzeczywistości zawierają drzewo AST zbudowane przez generator z kodu źródłowego. Pliki te mogą być odczytywane i wykonywane przez interpreter Lisp na różnych platformach lub wykorzystywane do generowania kodu maszynowego dla aktualnie używanej architektury sprzętowej.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION