פורמט קוד בתים של Dalvik

עיצוב כללי

  • מודל המכונה ומוסכמות השיחות נועדו לחקות בערך ארכיטקטורות אמיתיות נפוצות ומוסכמות שיחות בסגנון C:
    • המכונה מבוססת אוגר, ומסגרות קבועות בגודל עם היצירה. כל מסגרת מורכבת ממספר מסוים של אוגרים (שמצוין על ידי השיטה) וכן כל נתוני נלווים הדרושים לביצוע השיטה, כגון (אך לא מוגבל) מונה התוכנית והפניה לקובץ .dex המכיל את השיטה. .
    • בשימוש לערכי סיביות (כגון מספרים שלמים ומספרי נקודה צפה), אוגרים נחשבים ברוחב של 32 סיביות. צמדי אוגר סמוכים משמשים לערכי 64 סיביות. אין דרישת יישור עבור זוגות רישום.
    • כאשר משתמשים בהם להפניות אובייקטים, אוגרים נחשבים לרחבים מספיק כדי להחזיק בדיוק התייחסות אחת כזו.
    • במונחים של ייצוג סיביות, (Object) null == (int) 0 .
    • ה- N הטיעונים לשיטה נוחתים ב- N הרגיסטרים האחרונים של מסגרת הפנייה של השיטה, לפי הסדר. טיעונים רחבים צורכים שני אוגרים. שיטות מופע מועברות להפניה this כארגומנט הראשון שלהן.
  • יחידת האחסון בזרם ההוראות היא כמות של 16 סיביות ללא חתימה. חלק מהסיביות בהוראות מסוימות מתעלמות / חייבים להיות אפס.
  • הוראות אינן מוגבלות ללא תשלום לסוג מסוים. לדוגמה, הוראות שמזיזות ערכי אוגר של 32 סיביות ללא פרשנות אינן חייבות לציין אם הן נעות אינטס או צפים.
  • ישנן מאגרי קבועים שנמנו ונפרדים בנפרד עבור הפניות למחרוזות, סוגים, שדות ושיטות.
  • נתונים מילוליים באופן חלקי מיוצגים בשורה בזרם ההוראות.
  • מכיוון שבפועל, זה נדיר ששיטה צריכה יותר מ-16 אוגרים, ומכיוון שצורך ביותר משמונה אוגרים הוא נפוץ למדי, הוראות רבות מוגבלות להתייחסות רק ל-16 הרשמים הראשונים. כשאפשר באופן סביר, הוראות מאפשרות הפניות לעד 256 הרשמים הראשונים. בנוסף, לחלק מההוראות יש גרסאות המאפשרות ספירת רישום גדולה בהרבה, כולל צמד הוראות move תפוס שיכולות להתייחס לרשמים בטווח v0v65535 . במקרים בהם וריאנט הוראות אינו זמין כדי לתת מענה למאגר מבוקש, צפוי שתכולת האוגר יועבר מהאוגר המקורי לרישום נמוך (לפני הפעולה) ו/או יועבר ממאגר תוצאות נמוך לגבוה להירשם (לאחר הפעולה).
  • ישנן מספר "פקודות פסאודו" המשמשות לאחסן מטענים של נתונים באורך משתנה, שאליהם מתייחסים בהוראות רגילות (לדוגמה, fill-array-data ). אסור להיתקל בהוראות כאלה במהלך זרימת הביצוע הרגילה. בנוסף, ההוראות חייבות להיות ממוקמות בקיזוז בתים זוגיים (כלומר, מיושרים ל-4 בתים). על מנת לעמוד בדרישה זו, כלים ליצירת dex חייבים לפלוט הוראת nop נוספת בתור מרווח אם הוראה כזו לא תהיה מיושרת. לבסוף, אם כי לא נדרש, צפוי שרוב הכלים יבחרו לפלוט הוראות אלו בקצות השיטות, שכן אחרת סביר להניח שיהיה צורך בהוראות נוספות כדי להסתעף סביבם.
  • כאשר מותקן על מערכת פועלת, הוראות מסוימות עשויות להשתנות, תוך שינוי הפורמט שלהן, כאופטימיזציה סטטית של קישורים בזמן ההתקנה. זאת על מנת לאפשר ביצוע מהיר יותר ברגע שהקישור ידוע. ראה את מסמך פורמטי ההוראות המשויך עבור הווריאציות המוצעות. המילה "מוצע" משמשת בייעוץ; אין חובה ליישם את אלה.
  • תחביר אנושי ומנמונית:
    • סידור יעד-לאחר-מקור עבור טיעונים.
    • לחלק מהאופקודים יש סיומת שם מפורשת כדי לציין את הסוג/ים שבהם הם פועלים:
      • קודים כלליים של 32 סיביות אינם מסומנים.
      • קודים כלליים של 64 סיביות מסויימים -wide .
      • קודים ספציפיים לסוג מסויימים בסוג שלהם (או קיצור פשוט), אחד מ: -boolean -byte -char -short -int -long -float -double -object -string -class -void .
    • לקודים מסוימים יש סיומת מבדלת כדי להבחין בין פעולות זהות אחרת שיש להן פריסות או אפשרויות שונות של הוראות. הסיומות הללו מופרדות מהשמות הראשיים עם קו נטוי (" / ") ובעיקר קיימות בכלל כדי שיהיה מיפוי אחד לאחד עם קבועים סטטיים בקוד שיוצר ומפרש קובצי הפעלה (כלומר להפחית אי בהירות לבני אדם).
    • בתיאורים כאן, הרוחב של ערך (המציין, למשל, טווח של קבוע או מספר רגיסטרים שאולי מתייחסים אליו) מודגש על ידי שימוש בתו לכל ארבע סיביות רוחב.
    • לדוגמה, בהוראה " move-wide/from16 vAA, vBBBB ":
      • " move " הוא ה-opcode הבסיסי, המציין את פעולת הבסיס (הזזת ערך של אוגר).
      • " wide " היא סיומת השם, המציינת שהוא פועל על נתונים רחבים (64 סיביות).
      • " from16 " היא סיומת ה-opcode, המציינת וריאנט שיש לו הפניה לרשום של 16 סיביות כמקור.
      • " vAA " הוא אוגר היעד (משתמע מהפעולה; שוב, הכלל הוא שארגומנטים של יעד תמיד מגיעים קודם), אשר חייב להיות בטווח v0v255 .
      • " vBBBB " הוא אוגר המקור, שעליו להיות בטווח v0v65535 .
  • עיין במסמך פורמטי ההוראות לפרטים נוספים על פורמטי ההוראות השונים (המפורטים תחת "Op & Format") וכן פרטים על תחביר opcode.
  • עיין במסמך בפורמט קובץ .dex לקבלת פרטים נוספים על היכן קוד הבתים משתלב בתמונה הגדולה יותר.

סיכום של ערכת קוד בתים

הפעלה ופורמט מנמוני / תחביר טיעונים תיאור
00 10x לא מחזורי פסולת.

הערה: הוראות פסאודו הנושאות נתונים מתויגות עם קוד זה, ובמקרה זה הבתים בסדר גבוה של יחידת הקוד מציינים את אופי הנתונים. ראה "פורמט packed-switch-payload ", " sparse-switch-payload " ו-" fill-array-data-payload Format" להלן.

01 12x להעביר vA, vB A: אוגר יעד (4 סיביות)
B: אוגר מקור (4 סיביות)
העבר את התוכן של אוגר אחד שאינו אובייקט למשנהו.
02 22x move/from16 vAA, vBBBB A: אוגר יעד (8 סיביות)
B: אוגר מקור (16 סיביות)
העבר את התוכן של אוגר אחד שאינו אובייקט למשנהו.
03 32x move/16 vAAAA, vBBBB A: אוגר יעד (16 סיביות)
B: אוגר מקור (16 סיביות)
העבר את התוכן של אוגר אחד שאינו אובייקט למשנהו.
04 12x תנועה רחבת vA, vB A: זוג אוגר יעד (4 סיביות)
B: זוג אוגר מקור (4 סיביות)
העבר את התוכן של זוג אוגר אחד למשנהו.

הערה: זה חוקי לעבור מ- v N ל- v N-1 או v N+1 , כך שהמימושים חייבים לסדר את קריאת שני החצאים של זוג אוגר לפני שכתוב משהו.

05 22x לזוז-רוחב/מ-16 vAA, vBBBB A: זוג אוגר יעד (8 סיביות)
B: זוג אוגר מקור (16 סיביות)
העבר את התוכן של זוג אוגר אחד למשנהו.

הערה: שיקולי היישום זהים move-wide , לעיל.

06 32x move-wide/16 vAAAA, vBBBB A: זוג אוגר יעד (16 סיביות)
B: זוג אוגר מקור (16 סיביות)
העבר את התוכן של זוג אוגר אחד למשנהו.

הערה: שיקולי היישום זהים move-wide , לעיל.

07 12x move-object vA, vB A: אוגר יעד (4 סיביות)
B: אוגר מקור (4 סיביות)
העבר את התוכן של אוגר נושא אובייקט אחד למשנהו.
08 22x move-object/from16 vAA, vBBBB A: אוגר יעד (8 סיביות)
B: אוגר מקור (16 סיביות)
העבר את התוכן של אוגר נושא אובייקט אחד למשנהו.
09 32x move-object/16 vAAAA, vBBBB A: אוגר יעד (16 סיביות)
B: אוגר מקור (16 סיביות)
העבר את התוכן של אוגר נושא אובייקט אחד למשנהו.
0a 11x תוצאה של מהלך vAA A: אוגר יעד (8 סיביות) העבר את תוצאת המילה הבודדת שאינה אובייקט invoke- kind האחרון לתוך האוגר המצוין. זה חייב להיעשות כהוראה מיד לאחר invoke- kind שאין להתעלם מהתוצאה שלה (במילה אחת, ללא אובייקט); כל מקום אחר אינו חוקי.
0b 11x vAA לרוחב התוצאה A: זוג אוגר יעד (8 סיביות) העבר את תוצאת המילה הכפולה של invoke- kind האחרון לתוך צמד האוגרים המצוין. זה חייב להיעשות כהוראה מיד לאחר invoke- kind , שאין להתעלם מהתוצאה (המילה הכפולה) שלו; כל מקום אחר אינו חוקי.
0c 11x העבר-תוצאה-אובייקט vAA A: אוגר יעד (8 סיביות) העבר את תוצאת האובייקט של invoke- kind האחרון לתוך האוגר המצוין. זה חייב להיעשות כהוראה מיד לאחר מערך- invoke- kind או filled-new-array שאין להתעלם מהתוצאה (האובייקט) שלו; כל מקום אחר אינו חוקי.
0d 11x תנועה חריגה vAA A: אוגר יעד (8 סיביות) שמור חריג שזה עתה נתפס במאגר הנתון. זו חייבת להיות ההוראה הראשונה של כל מטפל חריג שאין להתעלם מהחריג שנתפס שלו, והוראה זו חייבת להתרחש רק כהוראה ראשונה של מטפל חריג; כל מקום אחר אינו חוקי.
0e 10x חזרה-בטלה חזרה משיטת void .
0f 11x החזר vAA A: אוגר ערך החזר (8 סיביות) החזר משיטת החזרת ערך ברוחב יחיד (32 סיביות) ללא אובייקט.
10 11x vAA ברוחב תשואה A: החזרת ערך אוגר-זוג (8 סיביות) החזר משיטת החזרת ערך ברוחב כפול (64 סיביות).
11 11x return-object vAA A: אוגר ערך החזר (8 סיביות) חזרה משיטת החזרת אובייקטים.
12 11n const/4 vA, #+B A: אוגר יעד (4 סיביות)
B: int signed (4 סיביות)
העבר את הערך המילולי הנתון (סימן מורחב ל-32 סיביות) לתוך האוגר שצוין.
13 21 שניות const/16 vAA, #+BBBB A: אוגר יעד (8 סיביות)
B: int signed (16 סיביות)
העבר את הערך המילולי הנתון (סימן מורחב ל-32 סיביות) לתוך האוגר שצוין.
14 31i const vAA, #+BBBBBBBB A: אוגר יעד (8 סיביות)
B: קבוע שרירותי של 32 סיביות
העבר את הערך המילולי הנתון לתוך האוגר שצוין.
15 21 שעות const/high16 vAA, #+BBBB0000 A: אוגר יעד (8 סיביות)
B: int signed (16 סיביות)
העבר את הערך המילולי הנתון (ימינה-אפס-מורחב ל-32 סיביות) לתוך האוגר שצוין.
16 21 שניות const-wide/16 vAA, #+BBBB A: אוגר יעד (8 סיביות)
B: int signed (16 סיביות)
העבר את הערך המילולי הנתון (סימן-מורחב ל-64 סיביות) לזוג האוגר שצוין.
17 31i const-wide/32 vAA, #+BBBBBBBB A: אוגר יעד (8 סיביות)
B: int signed (32 סיביות)
העבר את הערך המילולי הנתון (סימן-מורחב ל-64 סיביות) לזוג האוגר שצוין.
18 51 ל const-wide vAA, #+BBBBBBBBBBBBBBBB A: אוגר יעד (8 סיביות)
B: קבוע ברוחב כפול שרירותי (64 סיביות).
העבר את הערך המילולי הנתון לתוך זוג האוגר שצוין.
19 21 שעות const-wide/high16 vAA, #+BBBB0000000000000 A: אוגר יעד (8 סיביות)
B: int signed (16 סיביות)
העבר את הערך המילולי הנתון (ימינה-אפס-מורחב ל-64 סיביות) לזוג האוגר שצוין.
1a 21c const-string vAA, string@BBBB A: אוגר יעד (8 סיביות)
B: אינדקס מחרוזת
העבר הפניה למחרוזת שצוינה על ידי האינדקס הנתון לתוך האוגר שצוין.
1b 31c const-string/jumbo vAA, string@BBBBBBBB A: אוגר יעד (8 סיביות)
B: אינדקס מחרוזת
העבר הפניה למחרוזת שצוינה על ידי האינדקס הנתון לתוך האוגר שצוין.
1c 21c const-class vAA, type@BBBB A: אוגר יעד (8 סיביות)
B: אינדקס סוג
העבר הפניה למחלקה שצוינה על ידי האינדקס הנתון לתוך האוגר שצוין. במקרה שבו הטיפוס המצוין הוא פרימיטיבי, זה יאחסן הפניה למחלקה המנוונת של הטיפוס הפרימיטיבי.
1d 11x monitor-enter vAA A: אוגר נושא התייחסות (8 סיביות) רכוש את הצג עבור האובייקט המצוין.
1e 11x monitor-exit vAA A: אוגר נושא התייחסות (8 סיביות) שחרר את הצג עבור האובייקט המצוין.

הערה: אם הוראה זו צריכה לזרוק חריג, עליה לעשות זאת כאילו המחשב כבר התקדם מעבר להוראה. זה עשוי להיות שימושי לחשוב על זה כעל ההוראה שמתבצעת בהצלחה (במובן מסוים), והחריג שנזרק אחרי ההוראה אבל לפני שההוראה הבאה מקבלת הזדמנות לפעול. הגדרה זו מאפשרת לשיטה להשתמש ב-catch-all לניקוי צג (למשל, finally ) בתור ניקוי הצג עבור הבלוק עצמו, כדרך לטפל בחריגים שרירותיים שעלולים להיזרק עקב היישום ההיסטורי של Thread.stop() , תוך שהוא מצליח לשמור על היגיינת מוניטור נאותה.

1f 21c check-cast vAA, type@BBBB A: אוגר נושא התייחסות (8 סיביות)
B: אינדקס סוג (16 סיביות)
זרוק ClassCastException אם לא ניתן להטיל את ההפניה באוגר הנתון לסוג המצוין.

הערה: מכיוון ש- A חייב להיות תמיד הפניה (ולא ערך פרימיטיבי), זה בהכרח ייכשל בזמן ריצה (כלומר, זה יזרוק חריג) אם B מתייחס לסוג פרימיטיבי.

20 22ג מופע של vA, vB, type@CCCC A: אוגר יעד (4 סיביות)
B: אוגר נושא התייחסות (4 סיביות)
C: אינדקס סוג (16 סיביות)
אחסן במאגר היעד הנתון 1 אם ההפניה המצוינת היא מופע מהסוג הנתון, או 0 אם לא.

הערה: מכיוון ש- B חייב להיות תמיד הפניה (ולא ערך פרימיטיבי), זה תמיד יביא לכך ש 0 יישמר אם C מתייחס לסוג פרימיטיבי.

21 12x אורך מערך vA, vB A: אוגר יעד (4 סיביות)
B: אוגר נושא התייחסות למערך (4 סיביות)
אחסן ברישום היעד הנתון את אורך המערך המצוין, בערכים
22 21ג מופע חדש vAA, type@BBBB A: אוגר יעד (8 סיביות)
B: אינדקס סוג
בנה מופע חדש מהסוג המצוין, שמור הפניה אליו ביעד. הסוג חייב להתייחס למחלקה שאינה מערך.
23 22ג מערך חדש vA, vB, type@CCCC A: אוגר יעד (4 סיביות)
B: רשם מידות
C: אינדקס סוג
בנו מערך חדש מהסוג והגודל המצוינים. הסוג חייב להיות סוג של מערך.
24 35c filled-new-array {vC, vD, vE, vF, vG}, type@BBBB A: גודל מערך וספירת מילות ארגומנט (4 סיביות)
B: אינדקס סוג (16 סיביות)
C..G: אוגרי ארגומנטים (4 סיביות כל אחד)
בנה מערך מהסוג והגודל הנתונים, ממלא אותו בתכולה שסופקה. הסוג חייב להיות סוג של מערך. תוכן המערך חייב להיות בן מילה אחת (כלומר, אין מערכים של long או double , אבל סוגי הפניות מקובלים). המופע שנבנה מאוחסן כ"תוצאה" באותו האופן שבו הוראות הפעלת השיטה מאחסנות את התוצאות שלהן, ולכן יש להעביר את המופע שנבנה לרישום עם הוראה מיד לאחר מכן move-result-object (אם יש להשתמש בו ).
25 3rc filled-new-array/range {vCCCC .. vNNNN}, type@BBBB A: גודל מערך וספירת מילות ארגומנט (8 סיביות)
B: אינדקס סוג (16 סיביות)
C: אוגר ארגומנט ראשון (16 סיביות)
N = A + C - 1
בנה מערך מהסוג והגודל הנתונים, ממלא אותו בתכולה שסופקה. הבהרות והגבלות זהות ל- filled-new-array , המתואר לעיל.
26 31ט fill-array-data vAA, +BBBBBBBB (עם נתונים משלימים כמפורט להלן בפורמט " fill-array-data-payload ") A: הפניה למערך (8 סיביות)
B: היסט "ענף" חתום לנתוני טבלה פסאודו-פקודה (32 סיביות)
מלא את המערך הנתון בנתונים המצוינים. ההתייחסות חייבת להיות למערך של פרימיטיביים, וטבלת הנתונים חייבת להתאים לה בסוג שלה ולא להכיל יותר אלמנטים ממה שיתאים למערך. כלומר, המערך עשוי להיות גדול יותר מהטבלה, ואם כן, רק האלמנטים הראשוניים של המערך מוגדרים, ומשאירים את השאר לבד.
27 11x לזרוק vAA A: אוגר נושא חריג (8 סיביות)
זרוק את החריג המצוין.
28 10ט goto +AA A: קיזוז ענף חתום (8 סיביות) קפוץ ללא תנאי להוראה המצוינת.

הערה: הסטת הענף לא חייבת להיות 0 . (ניתן לבנות לולאת ספין באופן חוקי או עם goto/32 או על ידי הכללת nop כמטרה לפני הענף.)

29 20ט goto/16 +AAAA A: קיזוז ענף חתום (16 סיביות)
קפוץ ללא תנאי להוראה המצוינת.

הערה: הסטת הענף לא חייבת להיות 0 . (ניתן לבנות לולאת ספין באופן חוקי או עם goto/32 או על ידי הכללת nop כמטרה לפני הענף.)

2a 30t goto/32 +AAAAAAAA A: קיזוז ענף חתום (32 סיביות)
קפוץ ללא תנאי להוראה המצוינת.
2ב 31ט packed-switch vAA, +BBBBBBBB (עם נתונים משלימים כמפורט להלן בפורמט " packed-switch-payload ") A: הירשם לבדיקה
B: היסט "ענף" חתום לנתוני טבלה פסאודו-פקודה (32 סיביות)
קפוץ להוראה חדשה המבוססת על הערך באוגר הנתון, באמצעות טבלת קיזוזים התואמת לכל ערך בטווח אינטגרלי מסוים, או תיפול להוראה הבאה אם ​​אין התאמה.
2c 31t sparse-switch vAA, +BBBBBBBB (עם נתונים משלימים כמפורט להלן בפורמט " sparse-switch-payload ") A: הירשם לבדיקה
B: היסט "ענף" חתום לנתוני טבלה פסאודו-פקודה (32 סיביות)
קפוץ להוראה חדשה המבוססת על הערך באוגר הנתון, באמצעות טבלה מסודרת של זוגות היסט ערך, או תיפול להוראה הבאה אם ​​אין התאמה.
2d..31 23x סוג cmp vAA, vBB, vCC
2d: cmpl-float (הטיית LT)
2e: cmpg-float (הטיית gt)
2f: cmpl-double (הטיית lt)
30: cmpg-double (הטיית gt)
31: אורך ס"מ
A: אוגר יעד (8 סיביות)
B: אוגר מקור ראשון או זוג
C: אוגר או זוג מקור שני
בצע את הנקודה הצפה המצוינת או השוואה long , הגדר את a ל 0 אם b == c , 1 אם b > c , או -1 אם b < c . ה"הטיה" הרשומה עבור פעולות הנקודה הצפה מציינת כיצד מתייחסים להשוואות NaN : הוראות "gt bias" מחזירות 1 עבור השוואות NaN , והוראות "lt bias" מחזירות -1 .

לדוגמה, כדי לבדוק אם נקודה צפה x < y רצוי להשתמש cmpg-float ; תוצאה של -1 מציינת שהבדיקה הייתה נכונה, והערכים האחרים מציינים שהיא הייתה שקר או בגלל השוואה חוקית או בגלל שאחד הערכים היה NaN .

32..37 22ט if- test vA, vB, +CCCC
32: if-eq
33: אם-לא
34: if-lt
35: אם-גה
36: אם-gt
37: אם-לה
A: הירשם ראשון לבדיקה (4 סיביות)
B: אוגר שני לבדיקה (4 סיביות)
C: קיזוז ענף חתום (16 סיביות)
הסתעף ליעד הנתון אם ערכי שני האוגרים הנתונים משתווים כמפורט.

הערה: הסטת הענף לא חייבת להיות 0 . (לולאת ספין עשויה להיבנות באופן חוקי או על ידי הסתעפות מסביב ל- goto לאחור או על ידי הכללת nop כמטרה לפני הענף.)

38..3ד 21ט if- test z vAA, +BBBB
38: if-eqz
39: אם-נז
3a: if-ltz
3ב: אם-ז
3c: if-gtz
3d: if-lez
A: הירשם לבדיקה (8 סיביות)
B: קיזוז ענף חתום (16 סיביות)
הסתעף ליעד הנתון אם הערך של האוגר הנתון משתווה ל-0 כפי שצוין.

הערה: הסטת הענף לא חייבת להיות 0 . (לולאת ספין עשויה להיבנות באופן חוקי או על ידי הסתעפות מסביב ל- goto לאחור או על ידי הכללת nop כמטרה לפני הענף.)

3e..43 10x (לא בשימוש) (לא בשימוש)
44..51 23x מערך vAA, vBB, vCC
44: גיל
45: לכל הגילאים
46: אובייקט-גיל
47: גיל-בולאני
48: age-byte
49: גיל-צ'אר
4א: קצר-גיל
4ב: אפוט
4c: רוחב
4ד: aput-object
4e: aput-boolean
4f: aput-byte
50: אפוט-צ'אר
51: אפוט-קצר
A: אוגר ערך או זוג; יכול להיות מקור או יעד (8 סיביות)
B: אוגר מערך (8 סיביות)
C: אוגר אינדקס (8 סיביות)
בצע את פעולת המערך המזוהה באינדקס המזוהה של המערך הנתון, טעינה או אחסון במאגר הערכים.
52..5f 22c i instanceop vA, vB, field@CCCC
52: איגט
53: רחב
54: iget-object
55: iget-boolean
56: iget-byte
57: iget-char
58: iget-קצר
59: איפוט
5a: רוחב ה-iput
5b: iput-object
5c: iput-boolean
5d: iput-byte
5e: iput-char
5f: iput-קצר
A: אוגר ערך או זוג; יכול להיות מקור או יעד (4 סיביות)
B: אוגר אובייקטים (4 סיביות)
C: אינדקס הפניה לשדה מופע (16 סיביות)
בצע את פעולת השדה של מופע אובייקט מזוהה עם השדה המזוהה, טעינה או אחסון במאגר הערכים.

הערה: קודים אלה הם מועמדים סבירים לקישור סטטי, ומשנים את ארגומנט השדה לקיזוז ישיר יותר.

60..6d 21c s staticop vAA, field@BBBB
60: סגט
61: רחב
62: sget-object
63: סגט-בולאני
64: sget-byte
65: sget-char
66: קצר
67: ירק
68: רוחב יריקה
69: אובייקט-זרוק
6a: ספוט-בולאני
6b: sput-byte
6c: ספוט-char
6ד: ספוט-קצר
A: אוגר ערך או זוג; יכול להיות מקור או יעד (8 סיביות)
B: אינדקס התייחסות לשדה סטטי (16 סיביות)
בצע את פעולת השדה הסטטי של האובייקט המזוהה עם השדה הסטטי המזוהה, טעינה או אחסון במאגר הערכים.

הערה: קודים אלה הם מועמדים סבירים לקישור סטטי, ומשנים את ארגומנט השדה לקיזוז ישיר יותר.

6e..72 35c invoke- kind {vC, vD, vE, vF, vG}, meth@BBBB
6e: invoke-virtual
6f: invoke-super
70: invoke-direct
71: invoke-static
72: ממשק הפעלת
A: ספירת מילות ארגומנט (4 סיביות)
B: אינדקס התייחסות לשיטה (16 סיביות)
C..G: אוגרי ארגומנטים (4 סיביות כל אחד)
התקשר לשיטה המצוינת. התוצאה (אם קיימת) עשויה להיות מאוחסנת עם גרסה מתאימה move-result* כהוראה מיד לאחר מכן.

invoke-virtual משמש להפעלת שיטה וירטואלית רגילה (שיטה שאינה private , static או final , וגם אינה בנאי).

כאשר ה- method_id מתייחס למתודה של מחלקה שאינה ממשק, invoke-super משמש כדי להפעיל את השיטה הוירטואלית של מחלקת העל הקרובה ביותר (בניגוד לזו עם אותה method_id במחלקה הקוראת). אותן הגבלות שיטה מתקיימות כמו עבור invoke-virtual .

בקבצי Dex גרסה 037 ואילך, אם ה- method_id מתייחס לשיטת ממשק, invoke-super משמש כדי להפעיל את הגרסה הספציפית ביותר, שאינה מבוטלת, של אותה שיטה שהוגדרה בממשק זה. אותן הגבלות שיטה מתקיימות כמו עבור invoke-virtual . בקבצי Dex שלפני גרסה 037 , קיום של interface method_id אינו חוקי ולא מוגדר.

invoke-direct משמש להפעלת שיטה ישירה לא static (כלומר, שיטת מופע שמטבעה אינה ניתנת לביטול, כלומר שיטת מופע private או בנאי).

invoke-static משמש להפעלת שיטה static (שתמיד נחשבת לשיטה ישירה).

invoke-interface משמש להפעלת שיטת interface , כלומר על אובייקט שהמחלקה הקונקרטית שלו אינה ידועה, באמצעות method_id המתייחס interface .

הערה: קודים אלו הם מועמדים סבירים לקישור סטטי, ומשנים את ארגומנט השיטה להיות היסט ישיר יותר (או צמד שלו).

73 10x (לא בשימוש) (לא בשימוש)
74..78 3rc invoke- kind /range {vCCCC .. vNNNN}, meth@BBBB
74: הפעלת-וירטואלית/טווח
75: invoke-super/range
76: invoke-direct/טווח
77: הפעלת-סטטי/טווח
78: invoke-interface/range
A: ספירת מילות ארגומנט (8 סיביות)
B: אינדקס התייחסות לשיטה (16 סיביות)
C: אוגר ארגומנט ראשון (16 סיביות)
N = A + C - 1
התקשר לשיטה המצוינת. ראה את התיאור הראשון invoke- kind למעלה לפרטים, אזהרות והצעות.
79..7a 10x (לא בשימוש) (לא בשימוש)
7b..8f 12x unop vA, vB
7ב: neg-int
7c: לא-int
7ד: לא ארוך
7e: לא ארוך
7f: neg-float
80: נג-דאבל
81: אינט-לאורך
82: פנימה לצוף
83: int-to-double
84: ארוך עד אינט
85: ארוך לצוף
86: ארוך עד דאבל
87: מרחף ל-int
88: מרחף עד ארוך
89: לצוף-לכפול
8a: כפול ל-int
8ב: כפול עד ארוך
8c: כפול לצוף
8d: int-to-byte
8e: int-to-char
8f: אינט-לקצר
A: אוגר או זוג יעד (4 סיביות)
B: אוגר מקור או זוג (4 סיביות)
בצע את הפעולה האנרית המזוהה על אוגר המקור, אחסון התוצאה באוגר היעד.
90..af 23x binop vAA, vBB, vCC
90: תוספת
91: sub-int
92: mul-int
93: div-int
94: rem-int
95: ו-int
96: או-ינט
97: xor-int
98: shl-int
99: sh-int
9a: ushr-int
9b: הוספה ארוכה
9c: תת ארוך
9ד: ארוך
9e: div-ארוך
9f: rem-ארוך
a0: ו-ארוך
a1: או-ארוך
a2: xor-long
a3: shl-long
a4: sh-ארוך
a5: אושר ארוך
a6: add-float
a7: תת-צף
a8: mul-float
a9: div-float
aa: rem-float
ab: הוספה-כפולה
ac: תת-כפול
מודעה: mul-double
ae: div-double
af: rem-כפול
A: רישום יעד או זוג (8 סיביות)
B: אוגר או זוג מקור ראשון (8 סיביות)
C: אוגר או זוג מקור שני (8 סיביות)
בצע את הפעולה הבינארית המזוהה על שני אוגרי המקור, ושמור את התוצאה באוגר היעד.

הערה: בניגוד לפעולות מתמטיות -long אחרות (שלוקחות צמדי אוגר עבור המקור הראשון והשני שלהן), shl-long , shr-long ו- ushr-long לוקחים זוג אוגר עבור המקור הראשון שלהם (הערך שיש להזיז ), אלא אוגר יחיד עבור המקור השני שלהם (מרחק ההסטה).

b0..cf 12x binop /2addr vA, vB
b0: add-int/2addr
b1: sub-int/2addr
b2: mul-int/2addr
b3: div-int/2addr
b4: rem-int/2addr
b5: and-int/2addr
b6: or-int/2addr
b7: xor-int/2addr
b8: shl-int/2addr
b9: shr-int/2addr
ba: ushr-int/2addr
bb: add-long/2addr
bc: sub-long/2addr
bd: mul-long/2addr
להיות: div-long/2addr
bf: rem-long/2addr
c0: and-long/2addr
c1: or-long/2addr
c2: xor-long/2addr
c3: shl-long/2addr
c4: shr-long/2addr
c5: ushr-long/2addr
c6: add-float/2addr
c7: sub-float/2addr
c8: mul-float/2addr
c9: div-float/2addr
ca: rem-float/2addr
cb: add-double/2addr
cc: sub-double/2addr
CD: mul-double/2addr
ce: div-double/2addr
cf: rem-double/2addr
A: אוגר או זוג של יעד ומקור ראשון (4 סיביות)
B: אוגר או זוג מקור שני (4 סיביות)
בצע את הפעולה הבינארית המזוהה על שני אוגרי המקור, שמור את התוצאה באוגר המקור הראשון.

הערה: בניגוד לפעולות מתמטיות אחרות -long/2addr (שלוקחות צמדי רישום הן עבור היעד/המקור הראשון והן עבור המקור השני שלהן), shl-long/2addr , shr-long/2addr ו- ushr-long/2addr לוקחים רישום זוג עבור היעד/המקור הראשון שלהם (הערך שיש להזיז), אבל אוגר יחיד עבור המקור השני שלהם (מרחק ההסטה).

d0..d7 22s binop /lit16 vA, vB, #+CCCC
d0: add-int/lit16
d1: rsub-int (חיסור הפוך)
d2: mul-int/lit16
d3: div-int/lit16
d4: rem-int/lit16
d5: and-int/lit16
d6: or-int/lit16
d7: xor-int/lit16
A: אוגר יעד (4 סיביות)
B: אוגר מקור (4 סיביות)
C: קבוע int חתום (16 סיביות)
בצע את הפעולה הבינארית המצוינת על האוגר המצוין (ארגומנט ראשון) ועל הערך המילולי (ארגומנט שני), ושמור את התוצאה באוגר היעד.

הערה: rsub-int אין סיומת מכיוון שגרסה זו היא ה-opcode הראשי של המשפחה שלה. כמו כן, ראה להלן לפרטים על הסמנטיקה שלו.

d8..e2 22b binop /lit8 vAA, vBB, #+CC
d8: add-int/lit8
d9: rsub-int/lit8
da: mul-int/lit8
db: div-int/lit8
dc: rem-int/lit8
dd: and-int/lit8
de: or-int/lit8
df: xor-int/lit8
e0: shl-int/lit8
e1: shr-int/lit8
e2: ushr-int/lit8
A: אוגר יעד (8 סיביות)
B: אוגר מקור (8 סיביות)
C: קבוע int חתום (8 סיביות)
בצע את הפעולה הבינארית המצוינת על האוגר המצוין (ארגומנט ראשון) ועל הערך המילולי (ארגומנט שני), ושמור את התוצאה באוגר היעד.

הערה: ראה למטה לפרטים על הסמנטיקה של rsub-int .

e3..f9 10x (לא בשימוש) (לא בשימוש)
fa 45cc invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH A: ספירת מילות ארגומנט (4 סיביות)
B: אינדקס התייחסות לשיטה (16 סיביות)
C: מקלט (4 סיביות)
D..G: אוגרי ארגומנטים (4 סיביות כל אחד)
H: אינדקס התייחסות של אב טיפוס (16 סיביות)
הפעל את השיטה הפולימורפית החתימה המצוינת. התוצאה (אם קיימת) עשויה להיות מאוחסנת עם גרסה מתאימה move-result* כהוראה מיד לאחר מכן.

ההתייחסות לשיטה חייבת להיות למתודה פולימורפית חתימה, כגון java.lang.invoke.MethodHandle.invoke או java.lang.invoke.MethodHandle.invokeExact .

המקלט חייב להיות אובייקט התומך בשיטה הפולימורפית החתימה המופעלת.

הפניה לאב-טיפוס מתארת ​​את סוגי הארגומנטים שסופקו ואת סוג ההחזר הצפוי.

ה- invoke-polymorphic bytecode עשוי להעלות חריגים כאשר הוא מופעל. החריגים מתוארים בתיעוד ה-API עבור השיטה הפולימורפית החתימה המופעלת.

הצג בקבצי Dex מגרסה 038 ואילך.
fb 4rcc invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH A: ספירת מילות ארגומנט (8 סיביות)
B: אינדקס התייחסות לשיטה (16 סיביות)
C: מקלט (16 סיביות)
H: אינדקס התייחסות של אב טיפוס (16 סיביות)
N = A + C - 1
הפעל את ידית השיטה המצוינת. לפרטים, עיין בתיאור invoke-polymorphic למעלה.

הצג בקבצי Dex מגרסה 038 ואילך.
fc 35c invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB A: ספירת מילות ארגומנט (4 סיביות)
B: אינדקס הפניה לאתר שיחה (16 סיביות)
C..G: אוגרי ארגומנטים (4 סיביות כל אחד)
פותר ומפעיל את אתר השיחה המצוין. התוצאה מההפניה (אם בכלל) עשויה להיות מאוחסנת עם move-result* כהוראה מיד לאחר מכן.

הוראה זו מבוצעת בשני שלבים: פתרון אתרי שיחות והפעלת אתר שיחות.

רזולוציית אתר שיחה בודקת אם לאתר השיחה המצוין יש מופע java.lang.invoke.CallSite משויך. אם לא, שיטת הקישור של bootstrap עבור אתר השיחה המצוין מופעלת באמצעות ארגומנטים הקיימים בקובץ DEX (ראה call_site_item ). שיטת bootstrap linker מחזירה מופע java.lang.invoke.CallSite אשר ישויך לאחר מכן לאתר הקריאה המצוין אם לא קיים שיוך. ייתכן שרשור אחר כבר עשה את השיוך הראשון, ואם כן ביצוע ההוראה ממשיך עם המופע הראשון המשויך java.lang.invoke.CallSite .

הפנייה לאתר שיחה מתבצעת ביעד java.lang.invoke.MethodHandle של מופע java.lang.invoke.CallSite שנפתר. המטרה מופעלת כאילו היא מבצעת invoke-polymorphic (מתואר לעיל) תוך שימוש באספקת המתודה וארגומנטים להוראה invoke-custom כמו הארגומנטים להפעלת שיטה מדויקת.

חריגים שהועלו על ידי שיטת bootstrap Link עטופים ב- java.lang.BootstrapMethodError . מועלית גם BootstrapMethodError אם:
  • שיטת bootstrap Link לא מצליחה להחזיר מופע java.lang.invoke.CallSite .
  • ל- java.lang.invoke.CallSite המוחזר יש יעד טיפול בשיטת null .
  • יעד הטיפול של השיטה אינו מהסוג המבוקש.
הצג בקבצי Dex מגרסה 038 ואילך.
fd 3rc invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB A: ספירת מילות ארגומנט (8 סיביות)
B: אינדקס הפניה לאתר שיחה (16 סיביות)
C: אוגר ארגומנט ראשון (16 סיביות)
N = A + C - 1
פתרון והפעל אתר שיחות. לפרטים, עיין בתיאור invoke-custom למעלה.

הצג בקבצי Dex מגרסה 038 ואילך.
fe 21c const-method-handle vAA, method_handle@BBBB A: אוגר יעד (8 סיביות)
B: אינדקס נקודת אחיזה (16 סיביות)
העבר הפניה לאחיזה של השיטה שצוינה על ידי האינדקס הנתון לתוך האוגר שצוין.

הצג בקבצי Dex מגרסה 039 ואילך.
ff 21c const-method-type vAA, proto@BBBB A: אוגר יעד (8 סיביות)
B: התייחסות לאב טיפוס של שיטה (16 סיביות)
העבר הפניה לאב הטיפוס של השיטה שצוין על ידי האינדקס הנתון לתוך האוגר שצוין.

הצג בקבצי Dex מגרסה 039 ואילך.

פורמט packed-switch-payload

שֵׁם פוּרמָט תיאור
זיהוי ushort = 0x0100 זיהוי פסאודו-אופקוד
גודל קצר מספר הערכים בטבלה
מפתח_ראשון int ערך המיתוג הראשון (והנמוך ביותר).
מטרות int[] רשימה של יעדי סניפים יחסיים size . המטרות הן ביחס לכתובת של קוד הבורר, לא של הטבלה הזו.

הערה: המספר הכולל של יחידות קוד עבור מופע של טבלה זו הוא (size * 2) + 4 .

פורמט דל-בורר-מטען

שֵׁם פוּרמָט תיאור
זיהוי ushort = 0x0200 זיהוי פסאודו-אופקוד
גודל קצר מספר הערכים בטבלה
מפתחות int[] רשימה של ערכי מפתח size , ממוינים מנמוך לגבוה
מטרות int[] רשימה של יעדי סניפים יחסיים size , שכל אחד מהם מתאים לערך המפתח באותו אינדקס. המטרות הן ביחס לכתובת של קוד הבורר, לא של הטבלה הזו.

הערה: המספר הכולל של יחידות קוד עבור מופע של טבלה זו הוא (size * 4) + 2 .

פורמט fill-array-data-payload

שֵׁם פוּרמָט תיאור
זיהוי ushort = 0x0300 זיהוי פסאודו-אופקוד
element_width קצר מספר בתים בכל אלמנט
גודל uint מספר האלמנטים בטבלה
נתונים ubyte[] ערכי נתונים

הערה: המספר הכולל של יחידות קוד עבור מופע של טבלה זו הוא (size * element_width + 1) / 2 + 4 .

פרטי פעולה מתמטיים

הערה: פעולות נקודה צפה חייבות לפעול בהתאם לכללי IEEE 754, תוך שימוש בזרימה עגולה לקרוב והדרגתית, אלא אם צוין אחרת.

Opcode ג סמנטיקה הערות
neg-int int32 a;
int32 result = -a;
Unary two-complete.
לא-int int32 a;
int32 result = ~a;
משלים אחדים לא נראים.
neg-long int64 a;
int64 result = -a;
Unary two-complete.
לא ארוך int64 a;
int64 result = ~a;
משלים אחדים לא נראים.
neg-float לצוף א;
תוצאה לצוף = -a;
שלילת נקודה צפה.
neg-כפול כפול א;
תוצאה כפולה = -a;
שלילת נקודה צפה.
בין-לאורך int32 a;
int64 result = (int64) a;
חתום על הארכת int32 ל- int64 .
int-to-float int32 a;
תוצאה צף = (צף) א;
המרה של int32 float , בעזרת סבב-אל-נרתי ביותר. זה מאבד דיוק עבור ערכים מסוימים.
int to-double int32 a;
תוצאה כפולה = (כפול) א;
המרה של int32 double .
זמן רב-אינטי INT64 A;
int32 תוצאה = (int32) a;
גיזום של int64 ל- int32 .
זמן רב לצד INT64 A;
תוצאה צף = (צף) א;
המרה של int64 float , בעזרת סבב-אל-נרתי ביותר. זה מאבד דיוק עבור ערכים מסוימים.
זמן רב לכפול INT64 A;
תוצאה כפולה = (כפול) א;
המרה של int64 double , באמצעות סיבוב-אל-נרתי ביותר. זה מאבד דיוק עבור ערכים מסוימים.
צף לאינט צף א;
int32 תוצאה = (int32) a;
המרת float ל- int32 , באמצעות אפס עגול. NaN ו- -0.0 (אפס שלילי) מומרים למספר שלם 0 . אינסוף וערכים עם גודל גדול מדי המיוצג ייצוגו מומרים ל- 0x7fffffff או -0x80000000 תלוי בשלט.
צף לאורך צף א;
int64 תוצאה = (int64) a;
המרת float ל- int64 , באמצעות אפס עגול. אותם כללי מקרה מיוחד כמו עבור float-to-int חלים כאן, פרט לכך שערכים מחוץ לטווח יוסרו ל- 0x7fffffffffffffff או -0x8000000000000000 תלוי בשלט.
צף-טו-כפול צף א;
תוצאה כפולה = (כפול) א;
המרת float double , שמירה על הערך בדיוק.
כפול לאינט כפול א;
int32 תוצאה = (int32) a;
המרה של double ל- int32 , באמצעות אפס עגול. אותם כללי מקרה מיוחד כמו float-to-int כאן.
כפול-ארוך כפול א;
int64 תוצאה = (int64) a;
המרה של double ל- int64 , באמצעות אפס עגול. אותם כללי מקרה מיוחד כמו חלים כאן float-to-long .
כפול לצד כפול א;
תוצאה צף = (צף) א;
המרה של double float , בעזרת סבב-אל-נכרי ביותר. זה מאבד דיוק עבור ערכים מסוימים.
int to-byte int32 a;
int32 תוצאה = (a << 24) >> 24;
גיזום של int32 ל- int8 , סימן המרחיב את התוצאה.
int to-char int32 a;
int32 תוצאה = a & 0xffff;
גיזום של int32 ל- uint16 , ללא הארכת סימן.
אינט-לקור int32 a;
int32 תוצאה = (a << 16) >> 16;
גיזום של int32 ל- int16 , סימן המרחיב את התוצאה.
הוסף int32 a, b;
int32 תוצאה = a + b;
תוספת לשלימה של TWOS.
תת-יינט int32 a, b;
int32 תוצאה = a - b;
חיסור על השלימה של TWOS.
rsub-int int32 a, b;
int32 תוצאה = b - a;
חיסור הפוך של TWOS-Complession.
mul-int int32 a, b;
int32 תוצאה = a * b;
כפל ההשלמה של TWOS.
div-int int32 a, b;
int32 תוצאה = a / b;
חלוקת ההשלמה של TWOS, מעוגלת לעבר אפס (כלומר קטום למספר שלם). זה זורק ArithmeticException אם b == 0 .
rem-int int32 a, b;
תוצאה int32 = % b;
שארית ההשלמה של TWOS לאחר החטיבה. הסימן של התוצאה זהה לזה של a , והוא מוגדר בצורה מדויקת יותר result == a - (a / b) * b . זה זורק ArithmeticException אם b == 0 .
ואינט int32 a, b;
int32 תוצאה = a & b;
קצת ו.
אור-אינט int32 a, b;
int32 תוצאה = a | ב;
מעט או.
xor-int int32 a, b;
int32 תוצאה = a ^ b;
Xor bitwise.
shl-int int32 a, b;
int32 תוצאה = a << (B & 0x1f);
משמרת סיביות שמאלה (עם ויכוח רעולי פנים).
shr-int int32 a, b;
int32 תוצאה = a >> (B & 0x1f);
משמרת חתימה על סיביות ימינה (עם טיעון רעולי פנים).
ushr-int uint32 a, b;
int32 תוצאה = a >> (B & 0x1f);
משמרת לא חתומה מעט (עם טיעון רעולי פנים).
הוסף ארוך int64 a, b;
int64 תוצאה = a + b;
תוספת לשלימה של TWOS.
תת-אורך int64 a, b;
int64 תוצאה = a - b;
חיסור על השלימה של TWOS.
אורך-לונג int64 a, b;
int64 תוצאה = a * b;
כפל ההשלמה של TWOS.
DIV ארוך int64 a, b;
int64 תוצאה = a / b;
חלוקת ההשלמה של TWOS, מעוגלת לעבר אפס (כלומר קטום למספר שלם). זה זורק ArithmeticException אם b == 0 .
rem ארוך int64 a, b;
int64 תוצאה = % b;
שארית ההשלמה של TWOS לאחר החטיבה. הסימן של התוצאה זהה לזה של a , והוא מוגדר בצורה מדויקת יותר result == a - (a / b) * b . זה זורק ArithmeticException אם b == 0 .
וארוך int64 a, b;
int64 תוצאה = a & b;
קצת ו.
אורח int64 a, b;
int64 תוצאה = a | ב;
מעט או.
אורך אורך int64 a, b;
int64 תוצאה = a ^ b;
Xor bitwise.
SHL-Long INT64 A;
INT32 B;
int64 תוצאה = a << (B & 0x3f);
משמרת סיביות שמאלה (עם ויכוח רעולי פנים).
שרוף INT64 A;
INT32 B;
int64 תוצאה = a >> (B & 0x3f);
משמרת חתימה על סיביות ימינה (עם טיעון רעולי פנים).
USHR-Long uint64 a;
INT32 B;
int64 תוצאה = a >> (B & 0x3f);
משמרת לא חתומה מעט (עם טיעון רעולי פנים).
הוסף צמצום צף a, b;
תוצאה צפה = a + b;
תוספת נקודה צפה.
תת-צמצום צף a, b;
תוצאה צפה = a - b;
חיסור נקודה צפה.
צפיפה צף a, b;
תוצאה צפה = a * b;
כפל נקודת צף.
צמצום צף a, b;
תוצאה צפה = a / b;
חטיבת נקודה צפה.
רם צפה צף a, b;
תוצאה צפה = % b;
שארית הנקודה הצפה לאחר החטיבה. פונקציה זו שונה מ- IEEE 754 שארית ומוגדרת result == a - roundTowardZero(a / b) * b .
הוסף-דאבל כפול a, b;
תוצאה כפולה = A + B;
תוספת נקודה צפה.
תת-דובל כפול a, b;
תוצאה כפולה = a - b;
חיסור נקודה צפה.
מול-דובל כפול a, b;
תוצאה כפולה = a * b;
כפל נקודת צף.
Div-Double כפול a, b;
תוצאה כפולה = A / B;
חטיבת נקודה צפה.
rem-double כפול a, b;
תוצאה כפולה = % b;
שארית הנקודה הצפה לאחר החטיבה. פונקציה זו שונה מ- IEEE 754 שארית ומוגדרת result == a - roundTowardZero(a / b) * b .