**جاوا بایت کد (**به انگلیسی: **Java bytecode)** مجموعه دستورالعمل‌های ماشین مجازی جاوا یا به اختصار JVM است.

ارتباط با جاوا
--------------

یک برنامه‌نویس جاوا نیازی به دانستن یا درک جاوا بایت کد ندارد. با این حال، همان‌طور که در مجله IBM developerWorks پیشنهاد شده‌است، «درک بایت کد و آنچه که توسط کامپایلر جاوا تولید می‌شود، به برنامه نویس جاوا کمک می‌کند همانطور که دانش اسمبلی(Assembly) به برنامه نویس C یا C ++ کمک می‌کند.»

مجموعه دستورالعمل معماری
------------------------

جی وی ام(JVM) هم یک ماشین پشته ای (به انگلیسی: stack machine) و هم یک ماشین ثبات (به انگلیسی: register machine) است. هر فریم برای یک فراخوانی تابع دارای یک "پشته عملوند" و یک آرایه از "متغیرهای محلی" است. : 2.6 پشته عملوند برای عملوندهای محاسبات و برای دریافت مقدار بازگشتی یک تابع فراخوانی شده استفاده می‌شود، در حالی که متغیرهای محلی برای اهداف مشابهی همانند ثبات‌ها استفاده می‌شوند و همچنین برای انتقال دادن آرگومان‌های تابع استفاده می‌شوند. حداکثر اندازه پشته عملوند و آرایه متغیر محلی، محاسبه شده توسط کامپایلر، بخشی از ویژگی های(attributes) هر تابع است. : 4.7.3 هر کدام از آنها می‌تواند به‌طور مستقل از ۰ تا ۶۵۵۳۵ مقدار داشته باشد، که هر مقدار ۳۲ بیت است. `long` و `double`که ۶۴ بیت هستند، دو متغیر محلی متوالی : 2.6.1 (که نیازی به اینکه به صورت ۶۴ بیت در یک ردیف در آرایه متغیرهای محلی قرار گرفته باشد نیست) یا یک مقدار در پشته عملوند را می‌گیرند (اما به عنوان دو واحد در عمق پشته به‌شمار می‌رود) : 2.6.2

### مجموعه دستورالعمل

هر بایت کد از یک بایت که نشانگر آپ کد (به انگلیسی: opcode) است، همراه با صفر یا تعداد بایت بیشتر برای عملوندها تشکیل شده‌است. : 2.11

از ۲۵۶ بایت-long آپ کد ممکن، تا تاریخ ۲۰۱۵[بروزرسانی]، ۲۰۲ در حال استفاده هستند (~ ۷۹٪)، ۵۱ برای استفاده در آینده رزرو شده‌اند(~ ۲۰٪)، و ۳ دستورالعمل (~ ۱٪) به‌طور دائمی برای استفاده پیاده‌سازی‌های **جی وی ام** رزرو شده‌است. : 6.2 دو تا از اینها (`impdep2` و `impdep1`) به ترتیب مسئول ایجاد تله(trap) برای پیاده‌سازی خاص نرم‌افزار و سخت‌افزار هستند. سومی توسط دیباگرها برای پیاده‌سازی نقطه توقف(break point) استفاده می‌شود.

دستورالعمل‌ها به تعدادی گروه گسترده تقسیم می‌شوند:

* بارگذاری و ذخیره (مانند `aload_0` ، `istore`)
* ریاضیات و منطق (مانند `ladd` ، `fcmpl`)
* تبدیل نوع (به انگلیسی: Type conversion) (مانند `i2b` ، `d2i`)
* ایجاد و دستکاری شی (به انگلیسی: Operand stack management)(`new` ، `putfield`)
* مدیریت پشته عملوند (مانند `swap` ، `dup2`)
* انتقال کنترل (مانند `ifeq` ، `goto`)
* فراخوانی تابع و بازگشت (مانند `invokespecial,` `areturn`)

همچنین چندین دستورالعمل برای تعدادی از کارهای تخصصی تر مانند پرتاپ استثنا (به انگلیسی: exception throwing)، هماهنگ سازی (به انگلیسی: synchronization) و غیره وجود دارد.

بسیاری از دستورالعمل‌ها دارای پیشوند و / یا پسوندهای مربوط به انواع عملوندهایی که روی آن عمل می‌کنند هستند. : 2.11.1 که به شرح زیر است:

| پسوند/پیشوند | نوع عملوند |
| --- | --- |
| `i` | integer |
| `l` | long |
| `s` | short |
| `b` | byte |
| `c` | character |
| `f` | float |
| `d` | double |
| `a` | reference |

برای مثال، `iadd` دو عدد صحیح(integer) را جمع می‌کند، در حالی که `dadd` دو عدد double را جمع می‌کند. دستورالعمل‌های `const` ، `load` و `store` می‌توانند یک پسوند از فرم `_ *n*` داشته باشند، که *n* یک عدد از ۰–۳ برای `load` و `store` می‌باشد. حداکثر مقدار *n* برای `const` بسته به نوع متفاوت است.

دستورالعمل `const` یک مقدار از نوع مشخص شده را بر روی پشته قرار می‌دهد. به عنوان مثال، `iconst_5` یک عدد صحیح (مقدار ۳۲ بیتی) با مقدار ۵ را روی پشته قرار می‌دهد، در حالی که `dconst_1` یک double با مقدار 1 (64bit floating point value) را بر روی پشته قرار می‌دهد. همچنین دستورالعمل `aconst_null`وجود دارد، که یک مرجع(reference) `null` را روی پشته قرار می‌دهد. *n* برای دستورالعمل `load` و `store` ، شاخص(index) را در آرایه متغیر محلی برای بارگیری یا ذخیره کردن مشخص می‌کند. دستورالعمل `aload_0` شی (به انگلیسی: object) را در متغیر محلی ۰ را بر روی پشته قرار می‌دهد (این معمولاً شی`this` است). `istore_1` عدد صحیح بالای پشته را در متغیر محلی ۱ ذخیره می‌کند. برای متغیرهای محلی فراتر از ۳، پسوند وجود ندارد و باید از عملوند استفاده شود.

مثال
----

کد جاوا زیر را در نظر بگیرید: 

```
outer:
for (int i = 2 ; i < 1000; i++) {
 for (int j = 2 ; j < i; j++) {
 if (i % j == 0)
 continue outer;
 }
 System.out.println (i);
}

```
 یک کامپایلر جاوا ممکن است کد جاوای بالا را به بایت کد به صورت زیر ترجمه کند، فرض بر این است که کد بالا در یک تابع قرار داده شده‌است: 

```
0: iconst\_2
1: istore\_1
2: iload\_1
3: sipush 1000
6: if\_icmpge 44
9: iconst\_2
10: istore\_2
11: iload\_2
12: iload\_1
13: if\_icmpge 31
16 : iload\_1
17: iload\_2
18: irem
19: ifne 25
22: goto 38
25: iinc 2, 1
28: goto 11
31: getstatic #84; // Field java/lang/System.out:Ljava/io/PrintStream;
34: iload\_1
35: invokevirtual #85; // Method java/io/PrintStream.println:(I)V
38: iinc 1, 1
41: goto 2
44: return

```

نسل
---

رایج‌ترین زبان که با تولید جاوا بایت کد ماشین مجازی جاوا JVM را هدف قرار داده‌است، جاوا است. در ابتدا تنها یک کامپایلر وجود داشت، کامپایلر javac از Sun Microsystems، که کد منبع جاوا را به جاوا بایت کد کامپایل می‌کند؛ اما به دلیل اینکه تمام خصوصیات بایت کدی جاوا در حال حاضر در دسترس است، دسته‌های دیگر کامپایلرهایی را تولید کرده‌اند که جاوا بایت کد تولید می‌کنند. نمونه‌هایی از کامپایلرهای دیگر عبارتند از:

* Jikes، از جاوا به جاوا بایت کد کامپایل می‌کند (توسعه یافته توسط IBM، اجرا شده در C ++)
* Espresso، از جاوا به جاوا بایت کد کامپایل می‌کند (فقط جاوا ۱٫۰)
* کامپایلر GNU برای جاوا (GCJ)، از جاوا به جاوا بایت کد کامپایل می‌کند؛ همچنین می‌تواند به کد ماشین بومی (به انگلیسی: native) کامپایل کند و تا نسخه ۶ بخشی از مجموعه کامپایلر گنو (GCC) بود.

بعضی از پروژه‌ها، اسمبلرهای جاوا را قادر می‌سازند که به ضورت دستی جاوا بایت کد بنویسند. کد اسمبلی ممکن است توسط ماشین تولید شود، مثلاً توسط یک کامپایلر که یک ماشین مجازی جاوا را هدف قرار می‌دهد. اسمبلرهای مشهور جاوا عبارتند از:

* Jasmin، توصیف‌های متنی برای کلاسهای جاوا می‌گیرد، که در قالب یک ترکیب اسمبلی-مانند ساده است و از مجموعه دستورالعمل‌های **جی وی ام** استفاده کرده و فایل کلاس جاوا(Java class file) تولید می‌کند
* Jamaica، یک زبان اسمبلی ماکرو برای ماشین مجازی جاوا است. نحو جاوا (Java syntax) برای تعریف کلاس یا رابط(interface) استفاده می‌شود. بدنه تابع با دستورالعمل‌های بایت کد مشخص می‌شوند.
* Krakatau Bytecode Tools، در حال حاضر شامل سه ابزار است: decompiler و disassembler برای فایل‌های کلاس جاوا و یک اسمبلر برای ایجاد فایل‌های کلاس.
* Lilac، یک اسمبلر و disassembler برای ماشین مجازی جاوا.

دیگران برای زبان‌های برنامه‌نویسی مختلف کامپایلرهایی را که ماشین مجازی جاوا را هدف قرار می‌دهند، توسعه داده‌اند مانند:

* ColdFusion
* JRuby و Jython، دو زبان اسکریپتی بر اساس روبی و پایتون
* Apache Groovy، یک زبان اسکریپتیزبان اسکریپتی مبتنی بر جاوا است
* Scala، یک زبان برنامه‌نویسی عمومی و نوعی-امن است که از برنامه‌نویسی شی گرا و کاربردی پشتیبانی می‌کند
* JGNAT و AppletMagic، از زبان Ada به Java bytecode کامپایل می‌کند
* C به کامپایلر بایت کد جاوا
* Clojure، یک زبان برنامه‌نویسی کاربردی، غیرقابل تغییر، عمومی در خانواده Lisp با تأکید قوی بر همزمان سازی
* MIDletPascal
* کد اسکریپت JavaFX به جاوا بایت کد کامپایل می‌شود
* کوتلین
* کد منبع آبجکت پاسکال با استفاده از کامپایلر Free Pascal 3.0+ به جاوا بایت کدکامپایل می‌شود.

اجرا
----

امروزه ماشین‌های متعددی وجود دارند که هم رایگان و هم تجاری هستند.

اگر اجرای جاوا بایت کد در یک ماشین مجازی جاوا نامطلوب باشد، یک توسعه دهنده می‌تواند کد منبع جاوا یا بایت کد را به‌طور مستقیم به کد ماشین بومی با ابزارهایی مانند کامپایلر GNU برای جاوا (GCJ) کامپایل کند. بعضی از پردازنده‌ها می‌توانند بایت کد جاوا را به‌طور بومی اجرا کنند. چنین پردازنده هایی*پردازنده‌های جاوا* نامیده می‌شوند.

پشتیبانی از زبان‌های پویا
-------------------------

ماشین مجازی جاوا از زبان‌های پویا تایپ شونده (به انگلیسی: dynamically typed languages) پشتیبانی می‌کند. بیشتر دستورالعمل‌های موجود در جی وی ام ثابت تایپ شونده (به انگلیسی: statically typed) هستند - به این معنی که فراخوانی توابع امضا(signature) خود را در زمان کامپایل تایپ-چک می‌کنند، بدون مکانیزمی برای تعویق این تصمیم به زمان اجرا، یا برای انتخاب ارسال تابع با یک روش جایگزین.

JSR 292 *(از زبان‌های پویا تایپ شونده در بسترهای جاوا پشتیبانی می‌کند)* دستورالعمل جدید`invokedynamic` را در سطح جی وی ام اضافه کرد، تا فراخوانی تابع به داینامیک تایپ-چک (به انگلیسی: type checking) تکیه کند (به جای استاتیک تایپ-چک موجود با دستورالعمل`invokevirtual`). داوینچی ماشین (به انگلیسی: Da Vinci Machine) یک نمونه اولیه ماشین مجازی است که میزبان توسعه دهنده‌های جی وی ام با هدف پشتیبانی از زبانهای پویا است. همهٔ جی وی ام‌هایی که از ۷ JSE پشتیبانی می‌کنند شامل آپ کد `invokedynamic` هستند.

جستارهای وابسته
---------------

* Java bytecode instruction listings
* Java class file
* List of JVM languages
* Java backporting tools
* C to Java Virtual Machine compilers
* JStik
* Common Intermediate Language (CIL), Microsoft's rival to Java bytecode
* ObjectWeb ASM
* Byte Code Engineering Library

منابع
-----

1.فهم بایت کد شما را به برنامه‌نویس بهتری تبدیل می‌کند

2.*The Java Virtual Machine Specification*

3.Jamica: The Java virtual JVM macro assembler

4.Krakatau home page

5.Free Pascal 3.0 release notes

6.Free Pascal JVM Target

7.see JSR ۲۹۲

پیوند به بیرون
--------------

* خصوصیات مجازی ماشین جاوا اوراکل
* زبان‌های برنامه‌نویسی برای ماشین مجازی جاوا
	+