Dalvik bytecode

การออกแบบทั่วไป

  • โมเดลเครื่องและแบบแผนการเรียกมีขึ้นเพื่อเลียนแบบสถาปัตยกรรมจริงทั่วไปและแบบแผนการโทรแบบ C:
    • เครื่องเป็นแบบลงทะเบียน และเฟรมถูกกำหนดขนาดเมื่อสร้าง แต่ละเฟรมประกอบด้วยรีจิสเตอร์จำนวนหนึ่ง (ระบุโดยเมธอด) เช่นเดียวกับข้อมูลเสริมที่จำเป็นในการดำเนินการเมธอด เช่น (แต่ไม่จำกัดเฉพาะ) ตัวนับโปรแกรมและการอ้างอิงไปยังไฟล์ .dex ที่มีเมธอด .
    • เมื่อใช้สำหรับค่าบิต (เช่น จำนวนเต็มและเลขทศนิยม) รีจิสเตอร์จะถือว่ากว้าง 32 บิต คู่รีจิสเตอร์ที่อยู่ติดกันใช้สำหรับค่า 64 บิต ไม่มีข้อกำหนดการจัดตำแหน่งสำหรับคู่ลงทะเบียน
    • เมื่อใช้สำหรับการอ้างอิงอ็อบเจ็กต์ รีจิสเตอร์จะถือว่ากว้างพอที่จะเก็บข้อมูลอ้างอิงดังกล่าวได้เพียงรายการเดียว
    • ในแง่ของการแสดงระดับบิต (Object) null == (int) 0
    • อาร์กิวเมนต์ N ของเมธอดจะเข้าสู่ N รีจิสเตอร์สุดท้ายของเฟรมการเรียกใช้เมธอดตามลำดับ อาร์กิวเมนต์กว้างใช้สองรีจิสเตอร์ เมธอดของอินสแตนซ์จะถูกส่งผ่านการอ้างอิง this เป็นอาร์กิวเมนต์แรก
  • หน่วยเก็บข้อมูลในสตรีมคำสั่งเป็นปริมาณที่ไม่ได้ลงชื่อ 16 บิต บางบิตในบางคำสั่งจะถูกละเว้น / ต้องเป็นศูนย์
  • คำแนะนำไม่ได้จำกัดไว้เฉพาะบางประเภทเท่านั้น ตัวอย่างเช่น คำสั่งที่ย้ายค่ารีจิสเตอร์ 32 บิตโดยไม่มีการตีความไม่จำเป็นต้องระบุว่ากำลังย้ายค่า int หรือ float
  • มีพูลค่าคงที่ที่แจกแจงและจัดทำดัชนีแยกต่างหากสำหรับการอ้างอิงถึงสตริง ชนิด ฟิลด์ และวิธีการ
  • ข้อมูลตามตัวอักษรระดับบิตจะแสดงในบรรทัดในสตรีมคำสั่ง
  • เนื่องจากในทางปฏิบัติ เป็นเรื่องปกติสำหรับวิธีการที่ต้องการการลงทะเบียนมากกว่า 16 รายการ และเนื่องจากความต้องการการลงทะเบียนมากกว่าแปดรายการ เป็น เรื่องปกติที่สมเหตุสมผล คำแนะนำจำนวนมากจึงจำกัดให้ระบุเฉพาะการลงทะเบียน 16 รายการแรกเท่านั้น เมื่อเป็นไปได้อย่างสมเหตุสมผล คำแนะนำอนุญาตให้มีการอ้างอิงถึงการลงทะเบียน 256 รายการแรก นอกจากนี้ คำสั่งบางคำสั่งยังมีรูปแบบต่างๆ ที่ช่วยให้สามารถนับจำนวนรีจิสเตอร์ได้มากขึ้น ซึ่งรวมถึงคำแนะนำการ move ที่รับทั้งหมด ซึ่งระบุที่อยู่ของรีจิสเตอร์ในช่วง v0v65535 ในกรณีที่ไม่มีชุดคำสั่งสำหรับจัดการกับการลงทะเบียนที่ต้องการ คาดว่าเนื้อหาการลงทะเบียนจะถูกย้ายจากการลงทะเบียนดั้งเดิมไปยังการลงทะเบียนระดับต่ำ (ก่อนการดำเนินการ) และ/หรือย้ายจากการลงทะเบียนผลลัพธ์ต่ำไปยังระดับสูง ลงทะเบียน (หลังการดำเนินการ)
  • มี "pseudo-instructions" หลายแบบที่ใช้ในการเก็บข้อมูลความยาวผันแปรได้ ซึ่งอ้างอิงตามคำสั่งปกติ (เช่น fill-array-data ) คำสั่งดังกล่าวจะต้องไม่ถูกพบในระหว่างการดำเนินการตามปกติ นอกจากนี้ คำแนะนำจะต้องอยู่บนออฟเซ็ตของ bytecode ที่เป็นเลขคู่ (นั่นคือ 4 ไบต์ในแนวเดียวกัน) เพื่อให้เป็นไปตามข้อกำหนดนี้ เครื่องมือสร้าง dex ต้องปล่อยคำสั่ง nop พิเศษเป็นตัวเว้นวรรค หากคำสั่งดังกล่าวไม่อยู่ในแนวเดียวกัน สุดท้าย แม้ว่าจะไม่จำเป็น แต่คาดว่าเครื่องมือส่วนใหญ่จะเลือกที่จะเผยแพร่คำสั่งเหล่านี้ที่ส่วนท้ายของเมธอด มิฉะนั้น อาจเป็นกรณีที่จำเป็นต้องมีคำสั่งเพิ่มเติมเพื่อแยกสาขารอบๆ
  • เมื่อติดตั้งบนระบบที่กำลังทำงานอยู่ คำแนะนำบางอย่างอาจมีการเปลี่ยนแปลง โดยเปลี่ยนรูปแบบเป็นการปรับให้เหมาะสมสำหรับการเชื่อมโยงเวลาคงที่ในการติดตั้ง เพื่อให้ดำเนินการได้เร็วขึ้นเมื่อทราบการเชื่อมโยง ดู เอกสารรูปแบบคำสั่ง ที่เกี่ยวข้องสำหรับตัวแปรที่แนะนำ แนะนำให้ใช้คำว่า "แนะนำ" ไม่จำเป็นต้องดำเนินการเหล่านี้
  • ไวยากรณ์ของมนุษย์และตัวช่วยจำ:
    • ลำดับปลายทางแล้วต้นทางสำหรับอาร์กิวเมนต์
    • opcodes บางตัวมีส่วนต่อท้ายชื่อที่ทำให้สับสนเพื่อระบุประเภทที่พวกเขาใช้งาน:
      • opcodes 32 บิตทั่วไปประเภทไม่มีเครื่องหมาย
      • opcodes แบบ 64 บิตทั่วไปต่อท้ายด้วย -wide
      • opcodes เฉพาะประเภทต่อ -void ด้วยประเภท (หรือตัวย่อตรงไปตรงมา) หนึ่งใน: -boolean -byte -string -byte -char -short -int -long -float -object -class -double
    • opcodes บางตัวมีส่วนต่อท้ายที่แก้ความกำกวมเพื่อแยกแยะการดำเนินการที่เหมือนกันซึ่งมีรูปแบบคำสั่งหรือตัวเลือกที่แตกต่างกัน คำต่อท้ายเหล่านี้แยกจากชื่อหลักด้วยเครื่องหมายทับ (" / ") และส่วนใหญ่มีอยู่เพื่อให้มีการแมปแบบหนึ่งต่อหนึ่งด้วยค่าคงที่คงที่ในโค้ดที่สร้างและตีความไฟล์เรียกทำงาน (นั่นคือ เพื่อลดความกำกวม สำหรับมนุษย์)
    • ในคำอธิบายนี้ ความกว้างของค่า (ระบุ เช่น ช่วงของค่าคงที่หรือจำนวนรีจิสเตอร์ที่อาจระบุได้) ถูกเน้นโดยการใช้อักขระต่อความกว้างสี่บิต
    • ตัวอย่างเช่น ในคำสั่ง " move-wide/from16 vAA, vBBBB ":
      • " move " คือ opcode ฐาน ซึ่งระบุการดำเนินการพื้นฐาน (ย้ายค่าของ register)
      • " wide " เป็นคำต่อท้ายชื่อ ซึ่งบ่งชี้ว่าทำงานบนข้อมูลแบบกว้าง (64 บิต)
      • " from16 " เป็นคำต่อท้าย opcode ซึ่งระบุตัวแปรที่มีการอ้างอิงการลงทะเบียน 16 บิตเป็นแหล่งที่มา
      • " vAA " คือรีจิสเตอร์ปลายทาง (โดยนัยจากการดำเนินการ กฎก็คืออาร์กิวเมนต์ปลายทางจะมาก่อนเสมอ) ซึ่งต้องอยู่ในช่วง v0v255
      • " vBBBB " คือรีจิสเตอร์ต้นทาง ซึ่งต้องอยู่ในช่วง v0v65535
  • ดู เอกสารรูปแบบคำสั่ง สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบคำสั่งต่างๆ (อยู่ภายใต้ "Op & Format") รวมทั้งรายละเอียดเกี่ยวกับไวยากรณ์ opcode
  • ดู เอกสารรูปแบบไฟล์ .dex สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับตำแหน่งที่ bytecode พอดีกับภาพที่ใหญ่ขึ้น

สรุปชุดไบต์โค้ด

Op & รูปแบบ Mnemonic / ไวยากรณ์ ข้อโต้แย้ง คำอธิบาย
00 10x นพ วัฏจักรของเสีย

หมายเหตุ: คำสั่งหลอกที่มีข้อมูลถูกแท็กด้วย opcode นี้ ซึ่งในกรณีนี้ ไบต์ลำดับสูงของหน่วย opcode จะระบุลักษณะของข้อมูล ดู " รูปแบบ packed-switch-payload ", " รูปแบบ sparse-switch-payload " และ " fill-array-data-payload Format" ด้านล่าง

01 12x ย้าย vA, vB A: ลงทะเบียนปลายทาง (4 บิต)
B: รีจิสเตอร์ต้นทาง (4 บิต)
ย้ายเนื้อหาของการลงทะเบียนที่ไม่ใช่วัตถุหนึ่งไปยังอีกรายการหนึ่ง
02 22x ย้าย/จาก 16 vAA, vBBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: รีจิสเตอร์ต้นทาง (16 บิต)
ย้ายเนื้อหาของการลงทะเบียนที่ไม่ใช่วัตถุหนึ่งไปยังอีกรายการหนึ่ง
03 32x ย้าย/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 ขยับกว้าง/16 vAAAA, vBBBB A: คู่ลงทะเบียนปลายทาง (16 บิต)
B: คู่รีจิสเตอร์ต้นทาง (16 บิต)
ย้ายเนื้อหาของคู่ลงทะเบียนหนึ่งไปยังอีกคู่หนึ่ง

หมายเหตุ: ข้อควรพิจารณาในการนำไปใช้จะเหมือนกับ move-wide ด้านบน

07 12x ย้ายวัตถุ vA, vB A: ลงทะเบียนปลายทาง (4 บิต)
B: รีจิสเตอร์ต้นทาง (4 บิต)
ย้ายเนื้อหาของรีจิสเตอร์ที่มีวัตถุหนึ่งไปยังอีกอันหนึ่ง
08 22x ย้ายวัตถุ/จาก 16 vAA, vBBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: รีจิสเตอร์ต้นทาง (16 บิต)
ย้ายเนื้อหาของรีจิสเตอร์ที่มีวัตถุหนึ่งไปยังอีกอันหนึ่ง
09 32x ย้ายวัตถุ/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: return value register (8 บิต) ส่งคืนจากวิธีการคืนค่าที่ไม่ใช่วัตถุแบบความกว้างเดียว (32 บิต)
10 11x vAA . แบบกว้างกลับ A: ส่งคืนค่าคู่ลงทะเบียน (8 บิต) ส่งคืนจากวิธีการคืนค่าแบบ double-width (64 บิต)
11 11x ส่งคืนวัตถุ vAA A: return value register (8 บิต) กลับจากวิธีการส่งคืนวัตถุ
12 11น const/4 vA, #+B A: ลงทะเบียนปลายทาง (4 บิต)
B: ลงชื่อเข้าใช้ (4 บิต)
ย้ายค่าตามตัวอักษรที่กำหนด (ขยายเครื่องหมายเป็น 32 บิต) ไปยังรีจิสเตอร์ที่ระบุ
13 21วินาที const/16 vAA, #+BBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: ลงชื่อเข้าใช้ (16 บิต)
ย้ายค่าตามตัวอักษรที่กำหนด (ขยายเครื่องหมายเป็น 32 บิต) ไปยังรีจิสเตอร์ที่ระบุ
14 31i const vAA, #+BBBBBBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: ค่าคงที่ 32 บิตโดยพลการ
ย้ายค่าตามตัวอักษรที่กำหนดไปยังรีจิสเตอร์ที่ระบุ
15 21 ชม const/high16 vAA, #+BBBB0000 A: ลงทะเบียนปลายทาง (8 บิต)
B: ลงชื่อเข้าใช้ (16 บิต)
ย้ายค่าตามตัวอักษรที่กำหนด (right-zero-extended to 32 bits) ลงในรีจิสเตอร์ที่ระบุ
16 21วิ const-wide/16 vAA, #+BBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: ลงชื่อเข้าใช้ (16 บิต)
ย้ายค่าตามตัวอักษรที่กำหนด (ขยายเครื่องหมายเป็น 64 บิต) ไปยังคู่ลงทะเบียนที่ระบุ
17 31i const-wide/32 vAA, #+BBBBBBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: ลงชื่อเข้าใช้ (32 บิต)
ย้ายค่าตามตัวอักษรที่กำหนด (ขยายเครื่องหมายเป็น 64 บิต) ไปยังคู่ลงทะเบียนที่ระบุ
18 51l vAA กว้าง const, #+BBBBBBBBBBBBBBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: ค่าคงที่ความกว้างสองเท่า (64 บิต) โดยพลการ
ย้ายค่าตามตัวอักษรที่กำหนดไปยังคู่ลงทะเบียนที่ระบุ
19 21 ชม const-wide/high16 vAA, #+BBBB000000000000 A: ลงทะเบียนปลายทาง (8 บิต)
B: ลงชื่อเข้าใช้ (16 บิต)
ย้ายค่าตามตัวอักษรที่กำหนด (right-zero-extended to 64 bits) ไปเป็น register-pair ที่ระบุ
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 มอนิเตอร์-ป้อน vAA A: รีจิสเตอร์แบริ่งอ้างอิง (8 บิต) รับจอภาพสำหรับวัตถุที่ระบุ
1e 11x ตรวจสอบ-ออก vAA A: รีจิสเตอร์แบริ่งอ้างอิง (8 บิต) ปล่อยจอภาพสำหรับวัตถุที่ระบุ

หมายเหตุ: หากคำสั่งนี้จำเป็นต้องส่งข้อยกเว้น ต้องทำเสมือนว่าพีซีได้ผ่านคำสั่งไปแล้ว อาจเป็นประโยชน์ที่จะคิดว่าสิ่งนี้เป็นคำสั่งที่ดำเนินการได้สำเร็จ (ในแง่หนึ่ง) และข้อยกเว้นที่เกิด ขึ้นหลังจาก คำสั่งนั้น แต่ ก่อนที่ คำสั่งถัดไปจะมีโอกาสเรียกใช้ คำจำกัดความนี้ทำให้สามารถใช้วิธีการล้างข้อมูลจอภาพ catch-all (เช่น finally ) บล็อกเป็นการล้างหน้าจอสำหรับบล็อกนั้นเอง เป็นวิธีจัดการกับข้อยกเว้นตามอำเภอใจที่อาจถูกทิ้งเนื่องจากการใช้ Thread.stop() ในอดีต Thread.stop() ในขณะที่ยังคงจัดการให้มีสุขอนามัยของจอภาพที่เหมาะสม

1f 21c check-cast vAA, type@BBBB A: รีจิสเตอร์แบริ่งอ้างอิง (8 บิต)
B: ประเภทดัชนี (16 บิต)
โยน ClassCastException หากการอ้างอิงในการลงทะเบียนที่กำหนดไม่สามารถส่งไปยังประเภทที่ระบุได้

หมายเหตุ: เนื่องจาก A ต้องเป็นข้อมูลอ้างอิงเสมอ (และไม่ใช่ค่าพื้นฐาน) ค่านี้จึงจำเป็นต้องล้มเหลวในขณะใช้งานจริง (กล่าวคือ จะมีข้อยกเว้น) หาก B อ้างอิงถึงประเภทพื้นฐาน

20 22c อินสแตนซ์ของ vA, vB, type@CCCC A: ลงทะเบียนปลายทาง (4 บิต)
B: รีจิสเตอร์แบริ่งอ้างอิง (4 บิต)
C: ประเภทดัชนี (16 บิต)
จัดเก็บในทะเบียนปลายทางที่กำหนด 1 หากการอ้างอิงที่ระบุเป็นอินสแตนซ์ของประเภทที่กำหนด หรือ 0 หากไม่ใช่

หมายเหตุ: เนื่องจาก B ต้องเป็นข้อมูลอ้างอิงเสมอ (และไม่ใช่ค่าดั้งเดิม) ค่านี้จะส่งผลให้มีการจัดเก็บ 0 เสมอ หาก C อ้างอิงถึงประเภทดั้งเดิม

21 12x ความยาวอาร์เรย์ vA, vB A: ลงทะเบียนปลายทาง (4 บิต)
B: รีจิสเตอร์แบริ่งอ้างอิงอาร์เรย์ (4 บิต)
จัดเก็บในปลายทางที่กำหนดให้ลงทะเบียนความยาวของอาร์เรย์ที่ระบุในรายการ
22 21c อินสแตนซ์ใหม่ vAA, type@BBBB A: ลงทะเบียนปลายทาง (8 บิต)
B: พิมพ์ดัชนี
สร้างอินสแตนซ์ใหม่ของประเภทที่ระบุ โดยจัดเก็บการอ้างอิงถึงอินสแตนซ์ดังกล่าวในปลายทาง ประเภทต้องอ้างถึงคลาสที่ไม่ใช่อาร์เรย์
23 22c อาร์เรย์ใหม่ vA, vB, type@CCCC A: ลงทะเบียนปลายทาง (4 บิต)
B: ทะเบียนขนาด
C: พิมพ์ดัชนี
สร้างอาร์เรย์ใหม่ของประเภทและขนาดที่ระบุ ประเภทต้องเป็นประเภทอาร์เรย์
24 35c เติมอาร์เรย์ใหม่ {vC, vD, vE, vF, vG}, type@BBBB A: ขนาดอาร์เรย์และการนับจำนวนคำอาร์กิวเมนต์ (4 บิต)
B: ประเภทดัชนี (16 บิต)
C..G: รีจิสเตอร์อาร์กิวเมนต์ (4 บิตต่ออัน)
สร้างอาร์เรย์ของประเภทและขนาดที่กำหนด เติมด้วยเนื้อหาที่ให้มา ประเภทต้องเป็นประเภทอาร์เรย์ เนื้อหาของอาร์เรย์ต้องเป็นคำเดียว (นั่นคือ ไม่มีอาร์เรย์ของ long หรือ double แต่ยอมรับประเภทการอ้างอิงได้) อินสแตนซ์ที่สร้างขึ้นจะถูกจัดเก็บเป็น "ผลลัพธ์" ในลักษณะเดียวกับที่คำสั่งการเรียกใช้เมธอดเก็บผลลัพธ์ ดังนั้นอินสแตนซ์ที่สร้างขึ้นจะต้องถูกย้ายไปยังรีจิสเตอร์ด้วยคำสั่งการ move-result-object ตามมาทันที (ถ้าจะใช้ ).
25 3rc เติม-ใหม่-อาร์เรย์/ช่วง {vCCCC .. vNNNN}, type@BBBB A: ขนาดอาร์เรย์และจำนวนคำอาร์กิวเมนต์ (8 บิต)
B: ประเภทดัชนี (16 บิต)
C: การลงทะเบียนอาร์กิวเมนต์แรก (16 บิต)
N = A + C - 1
สร้างอาร์เรย์ของประเภทและขนาดที่กำหนด เติมด้วยเนื้อหาที่ให้มา การชี้แจงและข้อจำกัดเหมือนกับ filled-new-array ที่อธิบายไว้ข้างต้น
26 31t fill-array-data vAA, +BBBBBBBB (พร้อมข้อมูลเสริมตามที่ระบุด้านล่างใน " fill-array-data-payload Format") A: การอ้างอิงอาร์เรย์ (8 บิต)
B: เซ็นชื่อ "สาขา" ออฟเซ็ตเป็นคำสั่งหลอกข้อมูลตาราง (32 บิต)
เติมอาร์เรย์ที่กำหนดด้วยข้อมูลที่ระบุ การอ้างอิงต้องเป็นอาร์เรย์ของพื้นฐาน และตารางข้อมูลต้องตรงกับประเภทและต้องไม่มีองค์ประกอบมากกว่าที่จะพอดีกับอาร์เรย์ นั่นคืออาร์เรย์อาจมีขนาดใหญ่กว่าตาราง และถ้าเป็นเช่นนั้น จะมีการตั้งค่าเฉพาะองค์ประกอบเริ่มต้นของอาร์เรย์ โดยปล่อยให้ส่วนที่เหลืออยู่ตามลำพัง
27 11x โยน vAA A: รีจิสเตอร์ที่มีข้อยกเว้น (8 บิต)
โยนข้อยกเว้นที่ระบุ
28 10t ไปที่ +AA A: ออฟเซ็ตสาขาที่ลงนาม (8 บิต) ข้ามไปยังคำแนะนำที่ระบุโดยไม่มีเงื่อนไข

หมายเหตุ: สาขาออฟเซ็ตต้องไม่เป็น 0 (วงปั่นอาจถูกสร้างขึ้นอย่างถูกกฎหมายด้วย goto/32 หรือโดยการรวม nop เป็นเป้าหมายก่อนกิ่ง)

29 20t ไปที่/16 +AAAA A: ออฟเซ็ตสาขาที่ลงนาม (16 บิต)
ข้ามไปยังคำแนะนำที่ระบุโดยไม่มีเงื่อนไข

หมายเหตุ: สาขาออฟเซ็ตต้องไม่เป็น 0 (วงปั่นอาจถูกสร้างขึ้นอย่างถูกกฎหมายด้วย goto/32 หรือโดยการรวม nop เป็นเป้าหมายก่อนกิ่ง)

2a 30t goto/32 +AAAAAAA A: ออฟเซ็ตสาขาที่ลงนาม (32 บิต)
ข้ามไปยังคำแนะนำที่ระบุโดยไม่มีเงื่อนไข
2b 31t pack-switch vAA, +BBBBBBBB (พร้อมข้อมูลเสริมตามที่ระบุด้านล่างใน "รูปแบบ pack packed-switch-payload ") A: ลงทะเบียนเพื่อทดสอบ
B: เซ็นชื่อ "สาขา" ออฟเซ็ตเป็นคำสั่งหลอกข้อมูลตาราง (32 บิต)
ข้ามไปยังคำสั่งใหม่ตามค่าในรีจิสเตอร์ที่กำหนด โดยใช้ตารางออฟเซ็ตที่สอดคล้องกับแต่ละค่าในช่วงอินทิกรัลเฉพาะ หรือข้ามไปยังคำสั่งถัดไปหากไม่มีการจับคู่
2c 31t sparse-switch vAA, +BBBBBBBB (พร้อมข้อมูลเสริมตามที่ระบุด้านล่างใน " sparse-switch-payload Format") 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: cmp-ยาว
A: ลงทะเบียนปลายทาง (8 บิต)
B: การลงทะเบียนแหล่งแรกหรือคู่
C: รีจิสเตอร์แหล่งที่สองหรือ pair
ดำเนินการตามจุดลอยตัวที่ระบุหรือการเปรียบเทียบแบบ long โดยตั้งค่า a 0 if b == c , 1 if b > c หรือ -1 if b < c "อคติ" ที่ระบุไว้สำหรับการดำเนินการจุดทศนิยมระบุว่าการเปรียบเทียบ NaN ได้รับการปฏิบัติ: คำแนะนำ "gt bias" ส่งคืน 1 สำหรับการเปรียบเทียบ NaN และคำแนะนำ "lt bias" ส่งคืน -1

ตัวอย่างเช่น หากต้องการตรวจสอบดูว่าจุดลอยตัว x < y แนะนำให้ใช้ cmpg-float หรือไม่ ผลลัพธ์ของ -1 บ่งชี้ว่าการทดสอบเป็นจริง และค่าอื่นๆ ระบุว่าเป็นเท็จ เนื่องจากการเปรียบเทียบที่ถูกต้อง หรือเนื่องจากค่าใดค่าหนึ่งคือ NaN

32..37 22t ถ้า- ทดสอบ vA, vB, +CCCC
32: if-eq
33: if-ne
34: if-lt
35: if-ge
36: if-gt
37: if-le
A: ลงทะเบียนครั้งแรกเพื่อทดสอบ (4 บิต)
B: รีจิสเตอร์ที่สองเพื่อทดสอบ (4 บิต)
C: ออฟเซ็ตสาขาที่ลงนาม (16 บิต)
แยกสาขาไปยังปลายทางที่กำหนด หากค่าของรีจิสเตอร์ทั้งสองให้เปรียบเทียบตามที่ระบุ

หมายเหตุ: สาขาออฟเซ็ตต้องไม่เป็น 0 (วงรอบการหมุนอาจถูกสร้างขึ้นอย่างถูกกฎหมายโดยการแตกแขนงไปรอบ ๆ goto ย้อนกลับหรือโดยการรวม nop เป็นเป้าหมายก่อนการแตกแขนง)

38.3d 21t ถ้า- ทดสอบ z vAA, +BBBB
38: if-eqz
39: if-nez
3a: if-ltz
3b: if-gez
3c: if-gtz
3d: if-lez
A: ลงทะเบียนเพื่อทดสอบ (8 บิต)
B: ออฟเซ็ตสาขาที่ลงนาม (16 บิต)
สาขาไปยังปลายทางที่กำหนดหากค่าของการลงทะเบียนที่กำหนดเปรียบเทียบกับ 0 ตามที่ระบุ

หมายเหตุ: สาขาออฟเซ็ตต้องไม่เป็น 0 (วงรอบการหมุนอาจถูกสร้างขึ้นอย่างถูกกฎหมายโดยการแตกแขนงไปรอบ ๆ goto ย้อนกลับหรือโดยการรวม nop เป็นเป้าหมายก่อนการแตกแขนง)

3e..43 10x (ไม่ได้ใช้) (ไม่ได้ใช้)
44..51 23x arrayop vAA, vBB, vCC
44: อายุ
45: กว้างอายุ
46: อายุวัตถุ
47: age-บูลีน
48: ไบต์-ไบต์
49: age-char
4a: อายุสั้น
4b: aput
4c: aput-wide
4d: aput-object
4e: aput-บูลีน
4f: aput-byte
50: aput-char
51: สั้นสั้น
A: ลงทะเบียนค่าหรือคู่; อาจเป็นต้นทางหรือปลายทาง (8 บิต)
B: การลงทะเบียนอาร์เรย์ (8 บิต)
C: การลงทะเบียนดัชนี (8 บิต)
ดำเนินการดำเนินการอาร์เรย์ที่ระบุที่ดัชนีที่ระบุของอาร์เรย์ที่กำหนด โหลดหรือจัดเก็บลงในรีจิสเตอร์ค่า
52.5.5f 22c ฉัน Instanceop vA, vB, field@CCCC
52: iget
53: iget กว้าง
54: iget-วัตถุ
55: iget-บูลีน
56: iget-ไบต์
57: iget-char
58: iget-สั้น
59: ไอพุท
5a: iput-wide
5b: iput-object
5c: iput-บูลีน
5d: iput-byte
5e: iput-char
5f: iput-สั้น
A: ลงทะเบียนค่าหรือคู่; อาจเป็นต้นทางหรือปลายทาง (4 บิต)
B: การลงทะเบียนวัตถุ (4 บิต)
C: ดัชนีอ้างอิงฟิลด์อินสแตนซ์ (16 บิต)
ดำเนินการฟิลด์อินสแตนซ์อ็อบเจ็กต์ที่ระบุด้วยฟิลด์ที่ระบุ กำลังโหลดหรือจัดเก็บในรีจิสเตอร์ค่า

หมายเหตุ: opcodes เหล่านี้เป็นตัวเลือกที่เหมาะสมสำหรับการลิงก์แบบสแตติก โดยเปลี่ยนอาร์กิวเมนต์ฟิลด์ให้เป็นออฟเซ็ตโดยตรงมากขึ้น

6..6d 21c s staticop vAA, field@BBBB
60: sget
61: sget-wide
62: sget-object
63: sget-บูลีน
64: sget-byte
65: sget-char
66: sget สั้น
67: พ่นออกมา
68: พ่นกว้าง
69: วัตถุพ่นพิษ
6a: เสมหะบูลีน
6b: สพุตไบต์
6c: พ่นถ่าน
6d: พ่นสั้น
A: ลงทะเบียนค่าหรือคู่; อาจเป็นต้นทางหรือปลายทาง (8 บิต)
B: ดัชนีอ้างอิงฟิลด์คงที่ (16 บิต)
ดำเนินการกับฟิลด์สแตติกของอ็อบเจ็กต์ที่ระบุด้วยฟิลด์สแตติกที่ระบุ กำลังโหลดหรือจัดเก็บลงในรีจิสเตอร์ค่า

หมายเหตุ: opcodes เหล่านี้เป็นตัวเลือกที่เหมาะสมสำหรับการลิงก์แบบสแตติก โดยเปลี่ยนอาร์กิวเมนต์ฟิลด์ให้เป็นออฟเซ็ตโดยตรงมากขึ้น

6e..72 35c วิงวอน- ชนิด {vC, vD, vE, vF, vG}, meth@BBBB
6e: เรียกใช้เสมือน
6f: วิงวอน super
70: วิงวอนโดยตรง
71: เรียกแบบคงที่
72: เรียกใช้อินเทอร์เฟซ
A: จำนวนคำอาร์กิวเมนต์ (4 บิต)
B: ดัชนีอ้างอิงเมธอด (16 บิต)
C..G: รีจิสเตอร์อาร์กิวเมนต์ (4 บิตต่ออัน)
เรียกวิธีการที่ระบุ ผลลัพธ์ (ถ้ามี) อาจถูกจัดเก็บด้วยตัวแปร move-result* ที่เหมาะสมตามคำสั่งที่ตามมาทันที

invoke-virtual ใช้เพื่อเรียกใช้เมธอดเสมือนปกติ (เมธอดที่ไม่ใช่ private , static หรือ final และไม่ใช่ตัวสร้างด้วย)

เมื่อ method_id อ้างถึง method ของคลาส non-interface, invoke invoke-super จะถูกใช้เพื่อเรียกใช้เมธอดเสมือนของ superclass ที่ใกล้เคียงที่สุด (ตรงข้ามกับ method_id เดียวกันในคลาสการเรียก) ข้อจำกัดเมธอดเดียวกันกับ invoke-virtual

ในไฟล์ Dex เวอร์ชัน 037 หรือใหม่กว่า หาก method_id อ้างถึงเมธอดของอินเตอร์เฟส invoke invoke-super จะถูกใช้เพื่อเรียกใช้เมธอดที่เจาะจงและไม่ถูกแทนที่เวอร์ชันที่กำหนดไว้บนอินเทอร์เฟซนั้น ข้อจำกัดเมธอดเดียวกันกับ invoke-virtual ในไฟล์ Dex ก่อนเวอร์ชัน 037 การมีอินเทอร์เฟซ method_id นั้นผิดกฎหมายและไม่ได้กำหนดไว้

invoke-direct ใช้เพื่อเรียกใช้เมธอดโดยตรงที่ไม่ static (นั่นคือ เมธอดอินสแตนซ์ที่โดยธรรมชาติแล้วไม่สามารถแทนที่ได้ กล่าวคือเมธอด private อินสแตนซ์หรือคอนสตรัคเตอร์)

invoke-static ใช้เพื่อเรียกใช้เมธอดส static (ซึ่งถือว่าเป็นเมธอดโดยตรงเสมอ)

invoke-interface ใช้เพื่อเรียกใช้เมธอดของ interface นั่นคือ บนอ็อบเจ็กต์ที่ไม่รู้จักคลาสที่เป็นรูปธรรม โดยใช้ method_id ที่อ้างถึง interface

หมายเหตุ: opcodes เหล่านี้เป็นตัวเลือกที่สมเหตุสมผลสำหรับการเชื่อมโยงแบบสแตติก โดยเปลี่ยนวิธีอาร์กิวเมนต์ให้เป็นออฟเซ็ตโดยตรงมากขึ้น (หรือคู่กัน)

73 10x (ไม่ได้ใช้) (ไม่ได้ใช้)
74..78 3rc เรียกใช้- ชนิด / ช่วง {vCCCC .. vNNNN}, meth@BBBB
74: เรียกใช้เสมือน/ช่วง
75: เรียกใช้-super/range
76: เรียกใช้โดยตรง/ช่วง
77: เรียกคงที่/ช่วง
78: เรียกใช้อินเทอร์เฟซ/ช่วง
A: จำนวนคำอาร์กิวเมนต์ (8 บิต)
B: ดัชนีอ้างอิงเมธอด (16 บิต)
C: การลงทะเบียนอาร์กิวเมนต์แรก (16 บิต)
N = A + C - 1
เรียกวิธีการที่ระบุ โปรดดู invoke- kind ละเอียด คำเตือน และคำแนะนำด้านบนด้านบน
79.7a 10x (ไม่ได้ใช้) (ไม่ได้ใช้)
7b..8f 12x unop vA, vB
7b: ลบ int
7c: ไม่ใช่ int
7d: neg-long
7e: ไม่นาน
7f: neg-float
80: เน็ก-ดับเบิ้ล
81: เต็มถึงยาว
82: int-to-float
83: int-to-double
84: ยาวถึงยาว
85: ลอยยาว
86: ยาวเป็นสองเท่า
87: ลอยไปเป็น int
88: ลอยไปยาว
89: ลอยเป็นสองเท่า
8a: สองเท่าถึง int
8b: สองเท่าถึงยาว
8c: สองเท่าเพื่อลอย
8d: int-to-byte
8e: int-to-char
8f: เต็มถึงสั้น
A: ลงทะเบียนปลายทางหรือคู่ (4 บิต)
B: รีจิสเตอร์ต้นทางหรือคู่ (4 บิต)
ดำเนินการ unary ที่ระบุบนรีจิสเตอร์ต้นทาง จัดเก็บผลลัพธ์ในรีจิสเตอร์ปลายทาง
90..af 23x binop vAA, vBB, vCC
90: ส่วนเสริม
91: sub-int
92: mul-int
93: div-int
94: rem-int
95: และ-int
96: หรือ-int
97: xor-int
98: shl-int
99: shr-int
9a: ushr-int
9b: บวกยาว
9c: ย่อยยาว
9d: mul-long
9e: div-long
9f: เรม-ลอง
a0: และ-ยาว
a1: or-long
a2: xor-long
a3: shl-long
a4: ชร-ลอง
a5: ushr-long
a6: เพิ่มลอย
a7: sub-float
a8: mul-float
a9: div-float
aa: rem-float
ab: เพิ่มคู่
ac: ซับ-ดับเบิ้ล
โฆษณา: mul-double
ae: div-double
af: rem-double
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: และ-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: และ-ยาว/2addr
c1: หรือ-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
แคลิฟอร์เนีย: rem-float/2addr
cb: add-double/2addr
ซีซี: ซับ-ดับเบิ้ล/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: และ-int/lit16
d6: or-int/lit16
d7: xor-int/lit16
A: ลงทะเบียนปลายทาง (4 บิต)
B: รีจิสเตอร์ต้นทาง (4 บิต)
C: ค่าคงที่แบบลงนาม (16 บิต)
ดำเนินการไบนารี่ที่ระบุบนรีจิสเตอร์ที่ระบุ (อาร์กิวเมนต์แรก) และค่าตามตัวอักษร (อาร์กิวเมนต์ที่สอง) จัดเก็บผลลัพธ์ในรีจิสเตอร์ปลายทาง

หมายเหตุ: rsub-int ไม่มีส่วนต่อท้ายเนื่องจากเวอร์ชันนี้เป็น opcode หลักของตระกูล ดูด้านล่างสำหรับรายละเอียดเกี่ยวกับความหมายของมัน

d8..e2 22b binop /lit8 vAA, vBB, #+CC
d8: add-int/lit8
d9: rsub-int/lit8
ดา: mul-int/lit8
db: div-int/lit8
กระแสตรง: rem-int/lit8
dd: และ-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: ค่าคงที่แบบลงนาม (8 บิต)
ดำเนินการไบนารี่ที่ระบุบนรีจิสเตอร์ที่ระบุ (อาร์กิวเมนต์แรก) และค่าตามตัวอักษร (อาร์กิวเมนต์ที่สอง) จัดเก็บผลลัพธ์ในรีจิสเตอร์ปลายทาง

หมายเหตุ: ดูรายละเอียดเกี่ยวกับความหมายของ rsub-int ด้านล่าง

e3..f9 10x (ไม่ได้ใช้) (ไม่ได้ใช้)
เอฟเอ45cc เรียกใช้-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH A: จำนวนคำอาร์กิวเมนต์ (4 บิต)
B: ดัชนีอ้างอิงเมธอด (16 บิต)
C: ตัวรับ (4 บิต)
D..G: รีจิสเตอร์อาร์กิวเมนต์ (4 บิตต่ออัน)
H: ดัชนีอ้างอิงต้นแบบ (16 บิต)
เรียกใช้เมธอด polymorphic ลายเซ็นที่ระบุ ผลลัพธ์ (ถ้ามี) อาจถูกจัดเก็บด้วยตัวแปร move-result* ที่เหมาะสมตามคำสั่งที่ตามมาทันที

การอ้างอิงเมธอดต้องเป็นเมธอด polymorphic ที่เป็นลายเซ็น เช่น java.lang.invoke.MethodHandle.invoke หรือ java.lang.invoke.MethodHandle.invokeExact

ผู้รับต้องเป็นอ็อบเจ็กต์ที่สนับสนุนเมธอดโพลิมอร์ฟิกลายเซ็นที่ถูกเรียกใช้

การอ้างอิงต้นแบบอธิบายประเภทอาร์กิวเมนต์ที่มีให้และประเภทการส่งคืนที่คาดไว้

bytecode ที่ invoke-polymorphic -polymorphic อาจเพิ่มข้อยกเว้นเมื่อดำเนินการ ข้อยกเว้นได้อธิบายไว้ในเอกสารประกอบ API สำหรับวิธี Signature Polymorphic ที่ถูกเรียกใช้

นำเสนอในไฟล์ Dex ตั้งแต่เวอร์ชัน 038 เป็นต้นไป
fb 4rcc เรียกใช้-polymorphic/ช่วง {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH A: จำนวนคำอาร์กิวเมนต์ (8 บิต)
B: ดัชนีอ้างอิงเมธอด (16 บิต)
C: ตัวรับ (16 บิต)
H: ดัชนีอ้างอิงต้นแบบ (16 บิต)
N = A + C - 1
เรียกใช้แฮนเดิลเมธอดที่ระบุ ดูคำอธิบายที่ invoke-polymorphic ด้านบนสำหรับรายละเอียด

นำเสนอในไฟล์ Dex ตั้งแต่เวอร์ชัน 038 เป็นต้นไป
fc 35c เรียกกำหนดเอง {vC, vD, vE, vF, vG}, call_site@BBBB A: จำนวนคำอาร์กิวเมนต์ (4 บิต)
B: ดัชนีอ้างอิงไซต์การโทร (16 บิต)
C..G: รีจิสเตอร์อาร์กิวเมนต์ (4 บิตต่ออัน)
แก้ไขและเรียกใช้ไซต์การโทรที่ระบุ ผลลัพธ์จากการเรียก (ถ้ามี) อาจถูกจัดเก็บด้วยตัวแปร move-result* ที่เหมาะสมตามคำสั่งที่ตามมาทันที

คำสั่งนี้ดำเนินการในสองขั้นตอน: การแก้ปัญหาไซต์การโทรและการเรียกใช้ไซต์การโทร

การแก้ปัญหาไซต์การโทรตรวจสอบว่าไซต์การโทรที่ระบุมีอินสแตนซ์ java.lang.invoke.CallSite ที่เกี่ยวข้องหรือไม่ หากไม่เป็นเช่นนั้น เมธอด bootstrap linker สำหรับไซต์การโทรที่ระบุจะถูกเรียกใช้โดยใช้อาร์กิวเมนต์ที่มีอยู่ในไฟล์ DEX (ดู call_site_item ) เมธอดตัวเชื่อมโยงบูตสแตรปส่งคืนอินสแตนซ์ java.lang.invoke.CallSite ที่จะเชื่อมโยงกับไซต์การโทรที่ระบุหากไม่มีการเชื่อมโยง เธรดอื่นอาจสร้างการเชื่อมโยงไว้ก่อนแล้ว และหากการดำเนินการของคำสั่งดำเนินต่อไปด้วยอินสแตนซ์ java.lang.invoke.CallSite ที่เชื่อมโยงครั้งแรก

การเรียกไซต์เรียกทำบนเป้าหมาย java.lang.invoke.MethodHandle ของอินสแตนซ์ java.lang.invoke.CallSite ที่แก้ไขแล้ว เป้าหมายถูกเรียกใช้ราวกับว่ากำลังดำเนินการ invoke-polymorphic (อธิบายไว้ด้านบน) โดยใช้วิธีการจัดการและอาร์กิวเมนต์ของคำสั่ง invoke-custom เป็นอาร์กิวเมนต์ของวิธีการจัดการการเรียกใช้ที่แน่นอน

ข้อยกเว้นที่เกิดจากวิธีตัวเชื่อมโยงบูตสแตรปถูกรวมไว้ใน java.lang.BootstrapMethodError BootstrapMethodError ยังถูกยกขึ้นหาก:
  • เมธอดตัวเชื่อมโยง bootstrap ไม่สามารถส่งคืนอินสแตนซ์ java.lang.invoke.CallSite
  • java.lang.invoke.CallSite ที่ส่งคืนมีเป้าหมายการจัดการเมธอด null
  • เป้าหมายของการจัดการเมธอดไม่ใช่ประเภทที่ร้องขอ
นำเสนอในไฟล์ Dex ตั้งแต่เวอร์ชัน 038 เป็นต้นไป
fd 3rc เรียกใช้-กำหนดเอง/ช่วง {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 เป็นต้นไป

รูปแบบ pack-switch-payload

ชื่อ รูปแบบ คำอธิบาย
ตัวตน ushort = 0x0100 การระบุ pseudo-opcode
ขนาด ushort จำนวนรายการในตาราง
first_key int ค่าเคสสวิตช์แรก (และต่ำสุด)
เป้าหมาย ภายใน[] รายการเป้าหมายสาขาสัมพันธ์ size เป้าหมายสัมพันธ์กับที่อยู่ของสวิตช์ opcode ไม่ใช่ของตารางนี้

หมายเหตุ: จำนวนหน่วยโค้ดทั้งหมดสำหรับอินสแตนซ์ของตารางนี้คือ (size * 2) + 4

กระจัดกระจาย-สลับ-รูปแบบเพย์โหลด

ชื่อ รูปแบบ คำอธิบาย
ตัวตน ushort = 0x0200 การระบุ pseudo-opcode
ขนาด ushort จำนวนรายการในตาราง
กุญแจ ภายใน[] รายการค่าคีย์ size เรียงจากต่ำไปสูง
เป้าหมาย ภายใน[] รายการเป้าหมายสาขาสัมพันธ์ size โดยแต่ละรายการสอดคล้องกับค่าคีย์ที่ดัชนีเดียวกัน เป้าหมายสัมพันธ์กับที่อยู่ของสวิตช์ opcode ไม่ใช่ของตารางนี้

หมายเหตุ: จำนวนหน่วยโค้ดทั้งหมดสำหรับอินสแตนซ์ของตารางนี้คือ (size * 4) + 2

รูปแบบการเติมข้อมูล-ข้อมูล-เพย์โหลด

ชื่อ รูปแบบ คำอธิบาย
ตัวตน ushort = 0x0300 การระบุ pseudo-opcode
element_width ushort จำนวนไบต์ในแต่ละองค์ประกอบ
ขนาด uint จำนวนองค์ประกอบในตาราง
ข้อมูล ยูไบต์[] ค่าข้อมูล

หมายเหตุ: จำนวนหน่วยรหัสทั้งหมดสำหรับอินสแตนซ์ของตารางนี้คือ (size * element_width + 1) / 2 + 4

รายละเอียดการดำเนินการทางคณิตศาสตร์

หมายเหตุ: การดำเนินการจุดลอยตัวต้องเป็นไปตามกฎ IEEE 754 โดยใช้อันเดอร์โฟลว์แบบปัดเศษไปใกล้ที่สุดและค่อยเป็นค่อยไป ยกเว้นที่ระบุไว้เป็นอย่างอื่น

Opcode ซี ความหมาย หมายเหตุ
neg-int int32 ก;
ผลลัพธ์ int32 = -a;
ยูนารี ทู-คอมพลีเมนต์
ไม่ใช่ int int32 ก;
ผลลัพธ์ int32 = ~a;
Unary one-complement.
เน็ก-ลอง int64 ก;
ผลลัพธ์ int64 = -a;
ยูนารี ทู-คอมพลีเมนต์
ไม่นาน int64 ก;
ผลลัพธ์ int64 = ~a;
Unary one-complement.
neg-float ลอย a;
float result = -a;
Floating point negation.
neg-double double a;
double result = -a;
Floating point negation.
int-to-long int32 a;
int64 result = (int64) a;
Sign extension of int32 into int64 .
int-to-float int32 a;
float result = (float) a;
Conversion of int32 to float , using round-to-nearest. This loses precision for some values.
int-to-double int32 a;
double result = (double) a;
Conversion of int32 to double .
long-to-int int64 a;
int32 result = (int32) a;
Truncation of int64 into int32 .
long-to-float int64 a;
float result = (float) a;
Conversion of int64 to float , using round-to-nearest. This loses precision for some values.
long-to-double int64 a;
double result = (double) a;
Conversion of int64 to double , using round-to-nearest. This loses precision for some values.
float-to-int float a;
int32 result = (int32) a;
Conversion of float to int32 , using round-toward-zero. NaN and -0.0 (negative zero) convert to the integer 0 . Infinities and values with too large a magnitude to be represented get converted to either 0x7fffffff or -0x80000000 depending on sign.
float-to-long float a;
int64 result = (int64) a;
Conversion of float to int64 , using round-toward-zero. The same special case rules as for float-to-int apply here, except that out-of-range values get converted to either 0x7fffffffffffffff or -0x8000000000000000 depending on sign.
float-to-double float a;
double result = (double) a;
Conversion of float to double , preserving the value exactly.
double-to-int double a;
int32 result = (int32) a;
Conversion of double to int32 , using round-toward-zero. The same special case rules as for float-to-int apply here.
double-to-long double a;
int64 result = (int64) a;
Conversion of double to int64 , using round-toward-zero. The same special case rules as for float-to-long apply here.
double-to-float double a;
float result = (float) a;
Conversion of double to float , using round-to-nearest. This loses precision for some values.
int-to-byte int32 a;
int32 result = (a << 24) >> 24;
Truncation of int32 to int8 , sign extending the result.
int-to-char int32 a;
int32 result = a & 0xffff;
Truncation of int32 to uint16 , without sign extension.
int-to-short int32 a;
int32 result = (a << 16) >> 16;
Truncation of int32 to int16 , sign extending the result.
add-int int32 a, b;
int32 result = a + b;
Twos-complement addition.
sub-int int32 a, b;
int32 result = a - b;
Twos-complement subtraction.
rsub-int int32 a, b;
int32 result = b - a;
Twos-complement reverse subtraction.
mul-int int32 a, b;
int32 result = a * b;
Twos-complement multiplication.
div-int int32 a, b;
int32 result = a / b;
Twos-complement division, rounded towards zero (that is, truncated to integer). This throws ArithmeticException if b == 0 .
rem-int int32 a, b;
int32 result = a % b;
Twos-complement remainder after division. The sign of the result is the same as that of a , and it is more precisely defined as result == a - (a / b) * b . This throws ArithmeticException if b == 0 .
and-int int32 a, b;
int32 result = a & b;
Bitwise AND.
or-int int32 a, b;
int32 result = a | b;
Bitwise OR.
xor-int int32 a, b;
int32 result = a ^ b;
Bitwise XOR.
shl-int int32 a, b;
int32 result = a << (b & 0x1f);
Bitwise shift left (with masked argument).
shr-int int32 a, b;
int32 result = a >> (b & 0x1f);
Bitwise signed shift right (with masked argument).
ushr-int uint32 a, b;
int32 result = a >> (b & 0x1f);
Bitwise unsigned shift right (with masked argument).
add-long int64 a, b;
int64 result = a + b;
Twos-complement addition.
sub-long int64 a, b;
int64 result = a - b;
Twos-complement subtraction.
mul-long int64 a, b;
int64 result = a * b;
Twos-complement multiplication.
div-long int64 a, b;
int64 result = a / b;
Twos-complement division, rounded towards zero (that is, truncated to integer). This throws ArithmeticException if b == 0 .
rem-long int64 a, b;
int64 result = a % b;
Twos-complement remainder after division. The sign of the result is the same as that of a , and it is more precisely defined as result == a - (a / b) * b . This throws ArithmeticException if b == 0 .
and-long int64 a, b;
int64 result = a & b;
Bitwise AND.
or-long int64 a, b;
int64 result = a | b;
Bitwise OR.
xor-long int64 a, b;
int64 result = a ^ b;
Bitwise XOR.
shl-long int64 a;
int32 b;
int64 result = a << (b & 0x3f);
Bitwise shift left (with masked argument).
shr-long int64 a;
int32 b;
int64 result = a >> (b & 0x3f);
Bitwise signed shift right (with masked argument).
ushr-long uint64 a;
int32 b;
int64 result = a >> (b & 0x3f);
Bitwise unsigned shift right (with masked argument).
add-float float a, b;
float result = a + b;
Floating point addition.
sub-float float a, b;
float result = a - b;
Floating point subtraction.
mul-float float a, b;
float result = a * b;
Floating point multiplication.
div-float float a, b;
float result = a / b;
Floating point division.
rem-float float a, b;
float result = a % b;
Floating point remainder after division. This function is different than IEEE 754 remainder and is defined as result == a - roundTowardZero(a / b) * b .
add-double double a, b;
double result = a + b;
Floating point addition.
sub-double double a, b;
double result = a - b;
Floating point subtraction.
mul-double double a, b;
double result = a * b;
Floating point multiplication.
div-double double a, b;
double result = a / b;
Floating point division.
rem-double double a, b;
double result = a % b;
Floating point remainder after division. This function is different than IEEE 754 remainder and is defined as result == a - roundTowardZero(a / b) * b .