การออกแบบทั่วไป
- รูปแบบเครื่องและรูปแบบการเรียกมีไว้เพื่อเลียนแบบสถาปัตยกรรมจริงและรูปแบบการเรียกสไตล์ C ทั่วไปโดยประมาณ ดังนี้
- เครื่องจะอิงตามรีจิสทรีและเฟรมจะมีขนาดคงที่เมื่อสร้าง
แต่ละเฟรมประกอบด้วยรีจิสเตอร์จํานวนหนึ่งๆ (ที่ระบุโดยเมธอด) รวมถึงข้อมูลเพิ่มเติมที่จําเป็นสําหรับการเรียกใช้เมธอด เช่น (แต่ไม่จํากัดเพียง) ตัวนับโปรแกรมและการอ้างอิงไฟล์
.dex
ที่มีเมธอด - เมื่อใช้กับค่าบิต (เช่น จำนวนเต็มและเลขทศนิยม) รีจิสเตอร์จะถือว่ากว้าง 32 บิต ระบบจะใช้คู่รีจิสทร์ที่อยู่ติดกันสำหรับค่า 64 บิต ไม่มีข้อกำหนดในการจัดแนวสำหรับคู่รีจิสทอร์
- เมื่อใช้สำหรับข้อมูลอ้างอิงออบเจ็กต์ ระบบจะถือว่ารีจิสเตอร์มีขนาดใหญ่พอที่จะเก็บข้อมูลอ้างอิงดังกล่าวได้เพียงรายการเดียว
- ในแง่ของการแสดงผลแบบบิตต่อบิต
(Object) null == (int) 0
- โดยอาร์กิวเมนต์ N ของเมธอดจะอยู่ในรีจิสเตอร์ N สุดท้ายของเฟรมการเรียกใช้เมธอดตามลําดับ อาร์กิวเมนต์แบบกว้างจะใช้รีจิสเตอร์ 2 รายการ ระบบจะส่งผ่าน
this
อ้างอิงเป็นอาร์กิวเมนต์แรกให้กับเมธอดอินสแตนซ์
- เครื่องจะอิงตามรีจิสทรีและเฟรมจะมีขนาดคงที่เมื่อสร้าง
แต่ละเฟรมประกอบด้วยรีจิสเตอร์จํานวนหนึ่งๆ (ที่ระบุโดยเมธอด) รวมถึงข้อมูลเพิ่มเติมที่จําเป็นสําหรับการเรียกใช้เมธอด เช่น (แต่ไม่จํากัดเพียง) ตัวนับโปรแกรมและการอ้างอิงไฟล์
- หน่วยความจําในสตรีมคำสั่งคือจํานวน 16 บิตที่ไม่มีการนําหน้า ระบบจะไม่สนใจ / ต้องเท่ากับ 0 สำหรับบิตบางบิตในคำสั่งบางรายการ
- วิธีการไม่ได้จำกัดอยู่แค่ประเภทใดประเภทหนึ่ง เช่น คำสั่งที่ย้ายค่ารีจิสเตอร์ 32 บิตโดยไม่ตีความไม่จำเป็นต้องระบุว่าเป็นการย้าย int หรือ float
- มีพูลค่าคงที่ที่ระบุและจัดทําดัชนีแยกต่างหากสําหรับการอ้างอิงสตริง ประเภท ฟิลด์ และเมธอด
- ข้อมูลลิเทอรัลแบบบิตแสดงในบรรทัดในสตรีมคำสั่ง
- เนื่องจากในทางปฏิบัติ วิธีที่ต้องใช้รีจิสเตอร์มากกว่า 16 รายการนั้นเกิดขึ้นไม่บ่อยนัก และเนื่องจากความต้องการรีจิสเตอร์มากกว่า 8 รายการเกิดขึ้นค่อนข้างบ่อย คำสั่งจำนวนมากจึงจํากัดอยู่ที่การระบุเฉพาะรีจิสเตอร์ 16 รายการแรกเท่านั้น คำสั่งจะอนุญาตให้อ้างอิงรีจิสเตอร์ได้สูงสุด 256 รายการแรก หากเป็นไปได้ นอกจากนี้ คำสั่งบางรายการยังมีตัวแปรที่อนุญาตให้มีจำนวนรีจิสเตอร์มากขึ้นได้ รวมถึงคำสั่ง
move
ทั่วไป 2 รายการที่จัดการรีจิสเตอร์ในช่วงv0
–v65535
ได้ ในกรณีที่ไม่มีตัวแปรคำสั่งสำหรับจัดการรีจิสเตอร์ที่ต้องการ ระบบจะย้ายเนื้อหารีจิสเตอร์จากรีจิสเตอร์เดิมไปยังรีจิสเตอร์ต่ำ (ก่อนการดำเนินการ) และ/หรือย้ายจากรีจิสเตอร์ผลลัพธ์ต่ำไปยังรีจิสเตอร์สูง (หลังการดำเนินการ) - มี "คำสั่งจำลอง" หลายรายการที่ใช้เก็บข้อมูลเพย์โหลดที่มีความยาวแปรผัน ซึ่งคำสั่งปกติจะอ้างอิงถึง (เช่น
fill-array-data
) คำสั่งดังกล่าวต้องไม่ปรากฏขึ้นในระหว่างขั้นตอนการดำเนินการตามปกติ นอกจากนี้ คำสั่งต้องอยู่ในออฟเซตของไบต์โค้ดที่มีเลขคู่ (กล่าวคือ มีการจัดแนว 4 ไบต์) เครื่องมือสร้าง Dex ต้องแสดงคำสั่งnop
เพิ่มเติมเป็นตัวเว้นวรรคหากคำสั่งดังกล่าวไม่สอดคล้องกัน เพื่อให้เป็นไปตามข้อกำหนดนี้ สุดท้ายนี้ แม้ว่าจะไม่บังคับ แต่คาดว่าเครื่องมือส่วนใหญ่จะเลือกแสดงคำสั่งเหล่านี้ที่ท้ายเมธอด เนื่องจากไม่เช่นนั้น ก็อาจต้องใช้คำสั่งเพิ่มเติมเพื่อแยกย่อยคำสั่ง - เมื่อติดตั้งในระบบที่ทำงานอยู่ คำสั่งบางอย่างอาจมีการแก้ไขเพื่อเปลี่ยนรูปแบบเป็นการเพิ่มประสิทธิภาพการลิงก์แบบคงที่ ณ เวลาติดตั้ง การดำเนินการนี้ช่วยให้การดําเนินการเร็วขึ้นเมื่อทราบการลิงก์ ดูตัวแปรที่แนะนำได้ในเอกสารรูปแบบคำสั่งที่เกี่ยวข้อง เราใช้คำว่า "แนะนำ" ด้วยความระมัดระวังเนื่องจากคุณไม่จำเป็นต้องใช้ฟีเจอร์เหล่านี้
- ไวยากรณ์และคําช่วยจําสําหรับผู้ใช้
- การจัดลําดับปลายทางก่อนแหล่งที่มาสําหรับอาร์กิวเมนต์
- ออปโค้ดบางรายการมีนามสกุลที่ระบุประเภทเพื่อบ่งชี้ประเภทที่ดำเนินการ ดังนี้
- ออปโค้ด 32 บิตประเภททั่วไปจะไม่มีเครื่องหมาย
- ออปโค้ด 64 บิตประเภททั่วไปจะมี
-wide
ต่อท้าย - ออปโค้ดเฉพาะประเภทจะมีประเภท (หรือคำย่อที่เข้าใจง่าย) ต่อท้าย ซึ่งได้แก่
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
- ออปโค้ดบางรายการมีนามสกุลที่ทำให้เกิดความเข้าใจที่ชัดเจนเพื่อแยกแยะการดำเนินการที่เหมือนกันแต่มีเลย์เอาต์คำสั่งหรือตัวเลือกที่แตกต่างกัน ส่วนต่อท้ายเหล่านี้จะแยกจากชื่อหลักด้วยเครื่องหมายทับ ("
/
") และมีอยู่เพื่อทำให้มีการแมปแบบ 1:1 กับค่าคงที่แบบคงที่ในโค้ดที่สร้างและตีความไฟล์ปฏิบัติการ (กล่าวคือ เพื่อลดความคลุมเครือสำหรับผู้ใช้) - ในคำอธิบายนี้ ความกว้างของค่า (ซึ่งระบุถึงช่วงของค่าคงที่หรือจำนวนรีจิสเตอร์ที่อาจระบุ) จะเน้นด้วยการใช้อักขระต่อความกว้าง 4 บิต
- เช่น ในคำสั่ง
"
move-wide/from16 vAA, vBBBB
"- "
move
" คืออ็อปโค้ดพื้นฐาน ซึ่งระบุการดำเนินการพื้นฐาน (ย้ายค่าของรีจิสเตอร์) - "
wide
" คือส่วนต่อท้ายชื่อ ซึ่งบ่งบอกว่าทํางานกับข้อมูลแบบกว้าง (64 บิต) - "
from16
" คือส่วนต่อท้ายของ opcode ซึ่งระบุตัวแปรที่มีข้อมูลอ้างอิงรีจิสเตอร์ 16 บิตเป็นแหล่งที่มา - "
vAA
" คือรีจิสเตอร์ปลายทาง (ซึ่งบอกเป็นนัยโดยการดำเนินการ โปรดทราบว่ากฎคืออาร์กิวเมนต์ปลายทางต้องมาก่อนเสมอ) ซึ่งต้องอยู่ในช่วงv0
–v255
- "
vBBBB
" คือรีจิสทอร์แหล่งที่มา ซึ่งต้องอยู่ในช่วงv0
–v65535
- "
- ดูรายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบคำสั่งต่างๆ (แสดงอยู่ในส่วน "การดำเนินการและรูปแบบ") รวมถึงรายละเอียดเกี่ยวกับไวยากรณ์ของรหัสการดำเนินการได้ในเอกสารเกี่ยวกับรูปแบบคำสั่ง
- ดูรายละเอียดเพิ่มเติมเกี่ยวกับตำแหน่งของไบต์โค้ดในภาพรวมได้ในเอกสารรูปแบบไฟล์
.dex
สรุปชุดไบต์โค้ด
การดำเนินการและรูปแบบ | Mnemonic / Syntax | อาร์กิวเมนต์ | คำอธิบาย |
---|---|---|---|
00 10x | nop | วงจรของเสีย
หมายเหตุ:
คำสั่งจำลองที่มีข้อมูลจะติดแท็กด้วยอ็อปโค้ดนี้ ซึ่งในกรณีนี้ ไบต์ลำดับสูงของหน่วยอ็อปโค้ดจะระบุลักษณะของข้อมูล ดู " |
|
01 12x | move 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 บิต) |
ย้ายเนื้อหาของคู่รีจิสทรีหนึ่งไปยังอีกคู่หนึ่ง
หมายเหตุ:
การย้ายจาก |
05 22x | move-wide/from16 vAA, vBBBB | A: คู่รีจิสเตอร์ปลายทาง (8 บิต)B: คู่รีจิสเตอร์ต้นทาง (16 บิต) |
ย้ายเนื้อหาของคู่รีจิสทรีหนึ่งไปยังอีกคู่หนึ่ง
หมายเหตุ:
ข้อควรพิจารณาในการติดตั้งใช้งานเหมือนกับ |
06 32x | move-wide/16 vAAAA, vBBBB | A: คู่รีจิสเตอร์ปลายทาง (16 บิต)B: คู่รีจิสเตอร์ต้นทาง (16 บิต) |
ย้ายเนื้อหาของคู่รีจิสทรีหนึ่งไปยังอีกคู่หนึ่ง
หมายเหตุ:
ข้อควรพิจารณาในการติดตั้งใช้งานเหมือนกับ |
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 | move-result vAA | A: รีจิสเตอร์ปลายทาง (8 บิต) |
ย้ายผลการค้นหาที่ไม่ใช่ออบเจ็กต์แบบคำเดียวของ invoke-kind ล่าสุดไปยังรีจิสทร์ที่ระบุ
การดำเนินการนี้ต้องอยู่ในคำสั่งต่อจาก invoke-kind ทันที ซึ่งผลลัพธ์ (คำเดียวที่ไม่ใช่ออบเจ็กต์) จะต้องไม่ถูกละเว้น ไม่เช่นนั้นจะเป็นโมฆะ |
0b 11x | vAA แบบผลลัพธ์แบบกว้าง | A: คู่รีจิสเตอร์ปลายทาง (8 บิต) |
ย้ายผลลัพธ์แบบ 2 คำของ invoke-kind ล่าสุดไปยังคู่รีจิสเตอร์ที่ระบุ
การดำเนินการนี้ต้องอยู่ในคำสั่งต่อจาก invoke-kind โดยตรง ซึ่งผลลัพธ์ (แบบ 2 คำ) จะต้องไม่ถูกละเว้น ไม่เช่นนั้นผลลัพธ์จะใช้งานไม่ได้ |
0c 11x | move-result-object vAA | A: รีจิสเตอร์ปลายทาง (8 บิต) |
ย้ายผลลัพธ์ออบเจ็กต์ของ invoke-kind ล่าสุดไปไว้ในรีจิสทร์ที่ระบุ การดำเนินการนี้ต้องเป็นไปตามคำสั่งโดยอยู่ถัดจาก invoke-kind หรือ filled-new-array ทันที ซึ่งผลลัพธ์ (ออบเจ็กต์) จะไม่ถูกละเว้น การวางไว้ที่อื่นจะไม่ถูกต้อง |
0 วัน 11 เท่า | move-exception vAA | A: รีจิสเตอร์ปลายทาง (8 บิต) |
บันทึกข้อยกเว้นที่เพิ่งจับได้ในรีจิสเตอร์ที่ระบุ คำสั่งนี้ต้องเท่านั้นที่จะเป็นคำสั่งแรกของตัวแฮนเดิลข้อยกเว้นที่ระบบจะไม่ละเว้นข้อยกเว้นที่จับได้ และคำสั่งนี้ต้องเท่านั้นที่จะเป็นคำสั่งแรกของตัวแฮนเดิลข้อยกเว้น ตำแหน่งอื่นใดก็ตามไม่ถูกต้อง |
0e 10x | return-void | กลับมาจากเมธอด void |
|
0f 11x | return vAA | A: รีจิสเตอร์ผลลัพธ์ (8 บิต) |
กลับจากเมธอดที่แสดงผลค่าที่ไม่ใช่ออบเจ็กต์แบบความกว้างเดียว (32 บิต) |
10 11x | vAA ระดับการคืนสินค้า | A: คู่รีจิสเตอร์ผลลัพธ์ (8 บิต) |
กลับจากเมธอดที่แสดงผลค่าแบบ 2 เท่า (64 บิต) |
11 11x | return-object vAA | A: รีจิสเตอร์ผลลัพธ์ (8 บิต) |
กลับจากเมธอดที่แสดงผลออบเจ็กต์ |
12 11n | const/4 vA, #+B | A: รีจิสเตอร์ปลายทาง (4 บิต)B: signed int (4 บิต) |
ย้ายค่าลิเทอรัลที่ระบุ (ขยายเครื่องหมายเป็น 32 บิต) ไปยังรีจิสทร์ที่ระบุ |
13 21 วิ | const/16 vAA, #+BBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: signed int (16 บิต) |
ย้ายค่าลิเทอรัลที่ระบุ (ขยายเครื่องหมายเป็น 32 บิต) ไปยังรีจิสทร์ที่ระบุ |
14 31i | const vAA, #+BBBBBBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: ค่าคงที่ 32 บิตที่กำหนดเอง |
ย้ายค่าตัวอักษรที่ระบุไปยังรีจิสเตอร์ที่ระบุ |
15 21h | const/high16 vAA, #+BBBB0000 | A: รีจิสเตอร์ปลายทาง (8 บิต)B: signed int (16 บิต) |
ย้ายค่าลิเทอรัลที่ระบุ (ขยายค่า 0 ทางด้านขวาเป็น 32 บิต) ไปยังรีจิสเตอร์ที่ระบุ |
16 21 วิ | const-wide/16 vAA, #+BBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: signed int (16 บิต) |
ย้ายค่าลิเทอรัลที่ระบุ (ขยายเครื่องหมายเป็น 64 บิต) ไปยังคู่รีจิสเตอร์ที่ระบุ |
17 31i | const-wide/32 vAA, #+BBBBBBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: signed int (32 บิต) |
ย้ายค่าลิเทอรัลที่ระบุ (ขยายเครื่องหมายเป็น 64 บิต) ไปยังคู่รีจิสเตอร์ที่ระบุ |
18 51l | const-wide vAA, #+BBBBBBBBBBBBBBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: ค่าคงที่แบบกว้าง 2 เท่า (64 บิต) ที่กำหนดเอง |
ย้ายค่าลิเทอรัลที่ระบุไปยังคู่รีจิสเตอร์ที่ระบุ |
19 21h | const-wide/high16 vAA, #+BBBB000000000000 | A: รีจิสเตอร์ปลายทาง (8 บิต)B: signed int (16 บิต) |
ย้ายค่าลิเทอรัลที่ระบุ (ขยายค่า 0 ทางด้านขวาเป็น 64 บิต) ไปยังคู่รีจิสเตอร์ที่ระบุ |
1ก 21ค | const-string vAA, string@BBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: ดัชนีสตริง |
ย้ายการอ้างอิงไปยังสตริงที่ระบุโดยดัชนีที่ระบุไปยังรีจิสเตอร์ที่ระบุ |
1ข 31ค | const-string/jumbo vAA, string@BBBBBBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: ดัชนีสตริง |
ย้ายการอ้างอิงไปยังสตริงที่ระบุโดยดัชนีที่ระบุไปยังรีจิสเตอร์ที่ระบุ |
1c 21c | const-class vAA, type@BBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: ดัชนีประเภท |
ย้ายการอ้างอิงไปยังคลาสที่ระบุโดยดัชนีที่ระบุไปยังรีจิสเตอร์ที่ระบุ ในกรณีที่ประเภทที่ระบุเป็นแบบพื้นฐาน ระบบจะจัดเก็บการอ้างอิงไปยังคลาสที่เปลี่ยนรูปแบบของประเภทพื้นฐาน |
1 วัน 11 เท่า | monitor-enter vAA | A: รีจิสเตอร์การอ้างอิง (8 บิต) |
หาจอภาพสำหรับวัตถุที่ระบุ |
1e 11x | monitor-exit vAA | A: รีจิสเตอร์การอ้างอิง (8 บิต) |
ปล่อยเครื่องมือตรวจสอบสำหรับวัตถุที่ระบุ
หมายเหตุ:
หากคำสั่งนี้จำเป็นต้องแสดงข้อยกเว้น จะต้องดำเนินการดังกล่าวราวกับว่า PC ข้ามคำสั่งไปแล้ว
คุณอาจลองคิดว่าคำสั่งนี้ทำงานสำเร็จ (ในแง่หนึ่ง) และข้อยกเว้นเกิดขึ้นหลังจากคำสั่งดังกล่าว แต่ก่อนที่คำสั่งถัดไปจะได้มีโอกาสทำงาน คําจํากัดความนี้ทําให้เมธอดใช้การล้างข้อมูลการตรวจสอบแบบครอบคลุมได้ (เช่น |
1f 21c | check-cast vAA, type@BBBB | A: รีจิสเตอร์ที่ใช้อ้างอิง (8 บิต)B: ดัชนีประเภท (16 บิต) |
แสดงข้อยกเว้น ClassCastException หากไม่สามารถแคสต์ข้อมูลอ้างอิงในรีจิสทร์ที่ระบุเป็นประเภทที่ระบุ
หมายเหตุ: เนื่องจาก |
20 22c | instance-of vA, vB, type@CCCC | A: รีจิสเตอร์ปลายทาง (4 บิต)B: รีจิสเตอร์ที่มีข้อมูลอ้างอิง (4 บิต)C: ดัชนีประเภท (16 บิต) |
จัดเก็บในรีจิสทรีปลายทางที่ระบุ 1
หากการอ้างอิงที่ระบุคืออินสแตนซ์ของประเภทที่ระบุ หรือ 0 หากไม่ใช่
หมายเหตุ: เนื่องจาก |
21 12x | array-length vA, vB | A: รีจิสเตอร์ปลายทาง (4 บิต)B: รีจิสเตอร์ที่มีข้อมูลอ้างอิงอาร์เรย์ (4 บิต) |
จัดเก็บความยาวของอาร์เรย์ที่ระบุไว้ในรายการลงในรีจิสทรีปลายทางที่ระบุ |
22 21c | new-instance vAA, type@BBBB | A: รีจิสเตอร์ปลายทาง (8 บิต)B: ดัชนีประเภท |
สร้างอินสแตนซ์ใหม่ของประเภทที่ระบุ โดยจัดเก็บการอ้างอิงไปยังอินสแตนซ์นั้นในปลายทาง ประเภทต้องอ้างอิงถึงคลาสที่ไม่ใช่อาร์เรย์ |
23 22c | new-array 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 31t | fill-array-data vAA, +BBBBBBBB (พร้อมข้อมูลเสริมตามที่ระบุไว้ด้านล่างในส่วน "fill-array-data-payload รูปแบบ") |
A: การอ้างอิงอาร์เรย์ (8 บิต)B: ออฟเซ็ต "branch" ที่มีค่าลงนามไปยังคำสั่งจำลองข้อมูลตาราง
(32 บิต)
|
กรอกข้อมูลในอาร์เรย์ที่ระบุ การอ้างอิงต้องอ้างอิงถึงอาร์เรย์ของพรอมิเตี และตารางข้อมูลต้องตรงกับประเภทนั้น รวมถึงต้องมีองค์ประกอบไม่เกินจำนวนที่พอดีในอาร์เรย์ กล่าวคือ อาร์เรย์อาจมีขนาดใหญ่กว่าตาราง และหากเป็นเช่นนั้น ระบบจะตั้งค่าเฉพาะองค์ประกอบเริ่มต้นของอาร์เรย์เท่านั้น โดยไม่สนใจองค์ประกอบที่เหลือ |
27 11x | throw vAA | A: รีจิสเตอร์ที่มีข้อยกเว้น (8 บิต) |
ส่งข้อยกเว้นที่ระบุ |
28 10t | goto +AA | A: ออฟเซตสาขาที่มีค่าลงนาม (8 บิต) |
ข้ามไปยังคำสั่งที่ระบุโดยไม่มีเงื่อนไข
หมายเหตุ:
ออฟเซตสาขาต้องไม่ใช่ |
29 20t | goto/16 +AAAA | A: ออฟเซตการแยกทางที่มีค่าลงท้าย (16 บิต) |
ข้ามไปยังคำสั่งที่ระบุโดยไม่มีเงื่อนไข
หมายเหตุ:
ออฟเซตสาขาต้องไม่ใช่ |
2a 30t | goto/32 +AAAAAAAA | A: ออฟเซตการแยกสาขาที่มีค่า (32 บิต) |
ข้ามไปยังคำสั่งที่ระบุโดยไม่มีเงื่อนไข |
2b 31t | packed-switch vAA, +BBBBBBBB (พร้อมข้อมูลเสริมตามที่ระบุไว้ด้านล่างใน "packed-switch-payload Format") |
A: ลงทะเบียนเพื่อทดสอบB: ออฟเซต "branch" ที่มีค่าลงนามไปยังคำสั่งจำลองข้อมูลตาราง
(32 บิต)
|
ข้ามไปยังคำสั่งใหม่โดยอิงตามค่าในรีจิสเตอร์ที่ระบุ โดยใช้ตารางออฟเซตที่สอดคล้องกับแต่ละค่าในช่วงจำนวนเต็มหนึ่งๆ หรือข้ามไปยังคำสั่งถัดไปหากไม่พบรายการที่ตรงกัน |
2c 31t | sparse-switch vAA, +BBBBBBBB (พร้อมข้อมูลเสริมตามที่ระบุไว้ด้านล่างในส่วน "sparse-switch-payload รูปแบบ") |
A: ลงทะเบียนเพื่อทดสอบB: ออฟเซต "branch" ที่มีค่าลงนามไปยังคำสั่งจำลองข้อมูลตาราง
(32 บิต)
|
ข้ามไปยังคำสั่งใหม่ตามค่าในรีจิสเตอร์ที่ระบุ โดยใช้ตารางคู่ค่า-ออฟเซ็ตที่จัดเรียง หรือข้ามไปยังคำสั่งถัดไปหากไม่พบรายการที่ตรงกัน |
2d..31 23x | cmpkind vAA, vBB, vCC 2d: cmpl-float (lt bias) 2e: cmpg-float (gt bias) 2f: cmpl-double (lt bias) 30: cmpg-double (gt bias) 31: cmp-long |
A: รีจิสเตอร์ปลายทาง (8 บิต)B: รีจิสเตอร์หรือคู่แหล่งที่มาแรกC: รีจิสเตอร์หรือคู่แหล่งที่มาที่ 2 |
ดำเนินการเปรียบเทียบแบบลอยตัวหรือ long ที่ระบุ โดยตั้งค่า a เป็น 0 หากเป็น b == c , 1 หากเป็น b > c หรือ -1 หากเป็น b < c
"bias" ที่แสดงสําหรับการดำเนินการแบบทศนิยมบ่งบอกวิธีจัดการการเปรียบเทียบ NaN โดยคำสั่ง "gt bias" จะแสดงผล 1 สำหรับการเปรียบเทียบ NaN และคำสั่ง "lt bias" จะแสดงผล -1
เช่น หากต้องการตรวจสอบว่าค่าทศนิยม |
32..37 22t | if-test vA, vB, +CCCC 32: if-eq 33: if-ne 34: if-lt 35: if-ge 36: if-gt 37: if-le |
A: รีจิสเตอร์แรกที่จะทดสอบ (4 บิต)B: รีจิสเตอร์ที่ 2 ที่จะทดสอบ (4 บิต)C: ออฟเซตการแยกสาขาที่มีค่าลงท้าย (16 บิต) |
ไปยังปลายทางที่ระบุหากค่าของรีจิสเตอร์ 2 รายการที่ระบุเปรียบเทียบกันได้ตามที่ระบุ
หมายเหตุ:
ออฟเซตสาขาต้องไม่ใช่ |
38..3d 21t | if-testz vAA, +BBBB 38: if-eqz 39: if-nez 3a: if-ltz 3b: if-gez 3c: if-gtz 3d: if-lez |
A: register to test (8 bits)B: signed branch offset (16 bits) |
ไปยังปลายทางที่ระบุหากค่าของรีจิสเตอร์ที่ระบุเปรียบเทียบกับ 0 ตามที่ระบุ
หมายเหตุ:
ออฟเซตสาขาต้องไม่ใช่ |
3e..43 10x | (ไม่ได้ใช้) | (ไม่ได้ใช้) | |
44..51 23x | arrayop vAA, vBB, vCC 44: aget 45: aget-wide 46: aget-object 47: aget-boolean 48: aget-byte 49: aget-char 4a: aget-short 4b: aput 4c: aput-wide 4d: aput-object 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-short |
A: รีจิสเตอร์ค่าหรือคู่ อาจเป็นแหล่งที่มาหรือปลายทาง
(8 บิต)B: รีจิสเตอร์อาร์เรย์ (8 บิต)C: รีจิสเตอร์อินเด็กซ์ (8 บิต) |
ดำเนินการกับอาร์เรย์ที่ระบุที่ดัชนีที่ระบุของอาร์เรย์ที่ระบุ โดยโหลดหรือจัดเก็บลงในรีจิสเตอร์ค่า |
52..5f 22c | iinstanceop vA, vB, field@CCCC 52: iget 53: iget-wide 54: iget-object 55: iget-boolean 56: iget-byte 57: iget-char 58: iget-short 59: iput 5a: iput-wide 5b: iput-object 5c: iput-boolean 5d: iput-byte 5e: iput-char 5f: iput-short |
A: รีจิสเตอร์ค่าหรือคู่ ซึ่งอาจเป็นต้นทางหรือปลายทาง
(4 บิต)B: รีจิสเตอร์ออบเจ็กต์ (4 บิต)C: ดัชนีการอ้างอิงช่องอินสแตนซ์ (16 บิต) |
ดำเนินการกับฟิลด์อินสแตนซ์ออบเจ็กต์ที่ระบุด้วยฟิลด์ที่ระบุ โดยโหลดหรือจัดเก็บลงในรีจิสเตอร์ค่า
หมายเหตุ: ออปโค้ดเหล่านี้เหมาะสําหรับการลิงก์แบบคงที่ ซึ่งจะเปลี่ยนอาร์กิวเมนต์ฟิลด์ให้เป็นการออฟเซตที่ตรงมากขึ้น |
60..6d 21c | sstaticop vAA, field@BBBB 60: sget 61: sget-wide 62: sget-object 63: sget-boolean 64: sget-byte 65: sget-char 66: sget-short 67: sput 68: sput-wide 69: sput-object 6a: sput-boolean 6b: sput-byte 6c: sput-char 6d: sput-short |
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: invoke-interface |
A: จำนวนคำอาร์กิวเมนต์ (4 บิต)B: ดัชนีการอ้างอิงเมธอด (16 บิต)C..G: รีจิสเตอร์อาร์กิวเมนต์ (4 บิตต่อรายการ)
|
เรียกใช้เมธอดที่ระบุ ระบบอาจจัดเก็บผลลัพธ์ (หากมี) ไว้กับตัวแปร move-result* ที่เหมาะสมเป็นคำสั่งถัดไปทันที
เมื่อ ในไฟล์ Dex เวอร์ชัน
หมายเหตุ: ออปโค้ดเหล่านี้เหมาะสําหรับการลิงก์แบบคงที่ การแก้ไขอาร์กิวเมนต์ของเมธอดให้เป็นออฟเซตที่ตรงกว่า (หรือคู่ของออฟเซต) |
73 10x | (ไม่ได้ใช้) | (ไม่ได้ใช้) | |
74..78 3rc | invoke-kind/range {vCCCC .. vNNNN}, meth@BBBB 74: invoke-virtual/range 75: invoke-super/range 76: invoke-direct/range 77: invoke-static/range 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 7b: neg-int 7c: not-int 7d: neg-long 7e: not-long 7f: neg-float 80: neg-double 81: int-to-long 82: int-to-float 83: int-to-double 84: long-to-int 85: long-to-float 86: long-to-double 87: float-to-int 88: float-to-long 89: float-to-double 8a: double-to-int 8b: double-to-long 8c: double-to-float 8d: int-to-byte 8e: int-to-char 8f: int-to-short |
A: รีจิสเตอร์หรือคู่ปลายทาง (4 บิต)B: รีจิสเตอร์หรือคู่ต้นทาง (4 บิต) |
ดำเนินการการดำเนินการแบบยูนาร์ที่ระบุในรีจิสเตอร์ต้นทาง โดยจัดเก็บผลลัพธ์ไว้ในรีจิสเตอร์ปลายทาง |
90..af 23x | binop vAA, vBB, vCC 90: add-int 91: sub-int 92: mul-int 93: div-int 94: rem-int 95: and-int 96: or-int 97: xor-int 98: shl-int 99: shr-int 9a: ushr-int 9b: add-long 9c: sub-long 9d: mul-long 9e: div-long 9f: rem-long a0: and-long a1: or-long a2: xor-long a3: shl-long a4: shr-long a5: ushr-long a6: add-float a7: sub-float a8: mul-float a9: div-float aa: rem-float ab: add-double ac: sub-double ad: mul-double ae: div-double af: rem-double |
A: รีจิสเตอร์หรือคู่ปลายทาง (8 บิต)B: รีจิสเตอร์หรือคู่แหล่งที่มาแรก (8 บิต)C: รีจิสเตอร์หรือคู่แหล่งที่มาที่ 2 (8 บิต) |
ดำเนินการแบบไบนารีที่ระบุในรีจิสเตอร์ต้นทาง 2 รายการ โดยจัดเก็บผลลัพธ์ไว้ในรีจิสเตอร์ปลายทาง
หมายเหตุ:
|
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 be: 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: รีจิสเตอร์หรือคู่แหล่งที่มาที่ 2 (4 บิต) |
ดำเนินการการดำเนินการแบบไบนารีที่ระบุในรีจิสเตอร์ต้นทาง 2 รายการ โดยจัดเก็บผลลัพธ์ไว้ในรีจิสเตอร์ต้นทางรายการแรก
หมายเหตุ:
ต่างจากการดำเนินการทางคณิตศาสตร์ |
d0..d7 22 วินาที | binop/lit16 vA, vB, #+CCCC d0: add-int/lit16 d1: rsub-int (reverse subtract) 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 บิต) |
ดำเนินการดำเนินการฐานสองที่ระบุในรีจิสเตอร์ที่ระบุ (อาร์กิวเมนต์แรก) และค่าตัวอักษร (อาร์กิวเมนต์ที่ 2) โดยจัดเก็บผลลัพธ์ไว้ในรีจิสเตอร์ปลายทาง
หมายเหตุ:
|
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 บิต) |
ดำเนินการการดำเนินการแบบไบนารีที่ระบุในรีจิสเตอร์ที่ระบุ (อาร์กิวเมนต์แรก) และค่าตัวอักษร (อาร์กิวเมนต์ที่ 2) โดยจัดเก็บผลลัพธ์ไว้ในรีจิสเตอร์ปลายทาง
หมายเหตุ: ดูรายละเอียดเกี่ยวกับความหมายของ |
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 ตัวรับต้องเป็นออบเจ็กต์ที่รองรับเมธอดแบบโพลิมอร์ฟิกของลายเซ็นที่เรียกใช้ การอ้างอิงโปรโตไทป์จะอธิบายประเภทอาร์กิวเมนต์ที่ระบุและประเภทผลลัพธ์ที่คาดไว้ Bytecode ของ invoke-polymorphic อาจแสดงข้อยกเว้นเมื่อดำเนินการ ข้อยกเว้นจะอธิบายไว้ในเอกสารประกอบของ 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* ที่เหมาะสมเป็นคำสั่งที่ตามมาทันทีคำสั่งนี้จะดำเนินการเป็น 2 ระยะ ได้แก่ การแก้ไขเว็บไซต์ที่เรียกใช้และการเรียกใช้เว็บไซต์ที่เรียกใช้ การแก้ไขเว็บไซต์การเรียกจะตรวจสอบว่าเว็บไซต์การเรียกที่ระบุมีอินสแตนซ์ java.lang.invoke.CallSite ที่เชื่อมโยงหรือไม่
หากไม่มี ระบบจะเรียกใช้เมธอดลิงก์บูตสตรีปสําหรับไซต์การเรียกที่ระบุโดยใช้อาร์กิวเมนต์ที่มีอยู่ในไฟล์ 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 ด้วยในกรณีต่อไปนี้
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
ชื่อ | รูปแบบ | คำอธิบาย |
---|---|---|
ident | ushort = 0x0100 | การระบุซูโดโค้ด |
ขนาด | ushort | จํานวนรายการในตาราง |
first_key | Int | ค่าสวิตช์เคสแรก (และต่ำสุด) |
เป้าหมาย | int[] | รายการเป้าหมายสาขาแบบสัมพัทธ์ size โดยเป้าหมายจะสัมพันธ์กับที่อยู่ของ opcode ของ Switch ไม่ใช่ของตารางนี้
|
หมายเหตุ: จํานวนหน่วยโค้ดทั้งหมดสําหรับอินสแตนซ์ของตารางนี้คือ (size * 2) + 4
รูปแบบ sparse-switch-payload
ชื่อ | รูปแบบ | คำอธิบาย |
---|---|---|
ident | ushort = 0x0200 | การระบุซูโดโค้ด |
ขนาด | ushort | จํานวนรายการในตาราง |
กุญแจ | int[] | รายการค่าคีย์ size จัดเรียงจากต่ำไปสูง |
เป้าหมาย | int[] | รายการเป้าหมายสาขาแบบสัมพัทธ์ size รายการ ซึ่งแต่ละรายการจะสอดคล้องกับค่าคีย์ที่ดัชนีเดียวกัน โดยเป้าหมายจะสัมพันธ์กับที่อยู่ของ opcode ของ Switch ไม่ใช่ของตารางนี้
|
หมายเหตุ: จํานวนหน่วยโค้ดทั้งหมดสําหรับอินสแตนซ์ของตารางนี้คือ (size * 4) + 2
รูปแบบ fill-array-data-payload
ชื่อ | รูปแบบ | คำอธิบาย |
---|---|---|
ident | ushort = 0x0300 | การระบุซูโดโค้ด |
element_width | ushort | จํานวนไบต์ในแต่ละองค์ประกอบ |
ขนาด | uint | จํานวนองค์ประกอบในตาราง |
ข้อมูล | ubyte[] | ค่าข้อมูล |
หมายเหตุ: จํานวนหน่วยโค้ดทั้งหมดสําหรับอินสแตนซ์ของตารางนี้คือ (size * element_width + 1) / 2 + 4
รายละเอียดการดำเนินการทางคณิตศาสตร์
หมายเหตุ: การดำเนินการกับเลขทศนิยมต้องเป็นไปตามกฎ IEEE 754 โดยใช้การปัดเศษไปยังค่าใกล้ที่สุดและการไหลเข้าทีละน้อย ยกเว้นในกรณีที่ระบุไว้เป็นอย่างอื่น
รหัสการดำเนินการ | ความหมายของ C | หมายเหตุ |
---|---|---|
neg-int | int32 a; int32 result = -a; |
2s-complement แบบยูนาร์ |
not-int | int32 a; int32 result = ~a; |
เติม 1 ให้กับเลขฐาน 2 |
neg-long | int64 a; int64 result = -a; |
2s-complement แบบยูนาร์ |
not-long | int64 a; int64 result = ~a; |
เติม 1 ให้กับเลขฐาน 2 |
neg-float | float a; float result = -a; |
การปฏิเสธจำนวนจุดลอยตัว |
neg-double | double a; double result = -a; |
การปฏิเสธจำนวนจุดลอยตัว |
int-to-long | int32 a; int64 result = (int64) a; |
ลงนามขยายเวลาของ int32 เป็น int64 |
int-to-float | int32 a; float result = (float) a; |
การแปลง int32 เป็น float โดยใช้การปัดเศษให้ใกล้เคียงที่สุด ซึ่งจะทำให้ค่าบางค่ามีความแม่นยำลดลง
|
int-to-double | int32 a; double result = (double) a; |
Conversion ของ int32 เป็น double |
long-to-int | int64 a; int32 result = (int32) a; |
การตัด int64 ให้เป็น int32 |
long-to-float | int64 a; float result = (float) a; |
การแปลง int64 เป็น float โดยใช้การปัดเศษให้ใกล้เคียงที่สุด ซึ่งจะทำให้ค่าบางค่ามีความแม่นยำลดลง
|
long-to-double | int64 a; double result = (double) a; |
การแปลง int64 เป็น double โดยใช้การปัดเศษให้ใกล้เคียงที่สุด ซึ่งจะทำให้ค่าบางค่ามีความแม่นยำลดลง
|
float-to-int | float a; int32 result = (int32) a; |
การแปลง float เป็น int32 โดยใช้การปัดเศษให้ใกล้กับ 0 NaN และ -0.0 (ศูนย์ลบ)
แปลงเป็นจํานวนเต็ม 0 ระบบจะแปลงค่าอินฟินิตี้และค่าที่มีค่ามากเกินกว่าจะแสดงเป็น 0x7fffffff หรือ -0x80000000 โดยขึ้นอยู่กับเครื่องหมาย
|
float-to-long | float a; int64 result = (int64) a; |
การแปลง float เป็น int64 โดยใช้การปัดเศษให้ใกล้กับ 0 กฎสำหรับกรณีพิเศษเดียวกันกับของ float-to-int จะมีผลที่นี่ ยกเว้นว่าค่าที่อยู่นอกช่วงจะแปลงเป็น 0x7fffffffffffffff หรือ -0x8000000000000000 ทั้งนี้ขึ้นอยู่กับเครื่องหมาย
|
float-to-double | float a; double result = (double) a; |
การแปลง float เป็น double โดยเก็บค่าไว้อย่างครบถ้วน
|
double-to-int | double a; int32 result = (int32) a; |
การแปลง double เป็น int32 โดยใช้การปัดเศษให้ใกล้กับ 0 กฎสำหรับกรณีพิเศษเดียวกันกับของ float-to-int มีผลบังคับใช้ที่นี่
|
double-to-long | double a; int64 result = (int64) a; |
การแปลง double เป็น int64 โดยใช้การปัดเศษให้ใกล้กับ 0 กฎสำหรับกรณีพิเศษเดียวกันกับfloat-to-long จะมีผลที่นี่
|
double-to-float | double a; float result = (float) a; |
การแปลง double เป็น float โดยใช้การปัดเศษให้ใกล้เคียงที่สุด ซึ่งจะทำให้ค่าบางค่ามีความแม่นยำลดลง
|
int-to-byte | int32 a; int32 result = (a << 24) >> 24; |
การลบ int32 เหลือ int8 , เครื่องหมาย
ขยายผลลัพธ์
|
int-to-char | int32 a; int32 result = a & 0xffff; |
การตัด int32 ให้เป็น uint16 โดยไม่มีการขยายเครื่องหมาย
|
int-to-short | int32 a; int32 result = (a << 16) >> 16; |
การลบ int32 เหลือ int16 , เครื่องหมาย
ขยายผลลัพธ์
|
add-int | int32 a, b; int32 result = a + b; |
การเพิ่มแบบเติมเต็ม 2 บิต |
sub-int | int32 a, b; int32 result = a - b; |
การลบแบบเติมเต็ม 2 บิต |
rsub-int | int32 a, b; int32 result = b - a; |
การลบแบบผกผันด้วยหลักการเติม 2 เท่า |
mul-int | int32 a, b; int32 result = a * b; |
การคูณแบบเติมเต็ม 2 บิต |
div-int | int32 a, b; int32 result = a / b; |
การหารแบบเติม 2 เข้าหา 0 ซึ่งปัดเศษเข้าหา 0 (นั่นคือ ปัดเศษให้เป็นจำนวนเต็ม) การดำเนินการนี้จะแสดง ArithmeticException หาก
b == 0
|
rem-int | int32 a, b; int32 result = a % b; |
เศษส่วนแบบเติมเต็ม 2 ฐานหลังการหาร เครื่องหมายของผลลัพธ์จะเหมือนกับเครื่องหมายของ a และสามารถระบุได้อย่างแม่นยำยิ่งขึ้นว่า result == a - (a / b) * b การดำเนินการนี้จะแสดงข้อผิดพลาด ArithmeticException หาก 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); |
เลื่อนไปทางซ้ายแบบบิต (โดยมีอาร์กิวเมนต์ที่มีการมาสก์) |
shr-int | int32 a, b; int32 result = a >> (b & 0x1f); |
เลื่อนไปทางขวาแบบลงนามแบบบิต (พร้อมอาร์กิวเมนต์ที่มีการมาสก์) |
ushr-int | uint32 a, b; int32 result = a >> (b & 0x1f); |
เลื่อนไปทางขวาแบบไม่ลงนามเชิงบิต (โดยมีอาร์กิวเมนต์ที่มีการมาสก์) |
add-long | int64 a, b; int64 result = a + b; |
การเพิ่มแบบเติมเต็ม 2 บิต |
sub-long | int64 a, b; int64 result = a - b; |
การลบแบบเติมเต็ม 2 บิต |
mul-long | int64 a, b; int64 result = a * b; |
การคูณแบบเติมเต็ม 2 บิต |
div-long | int64 a, b; int64 result = a / b; |
การหารแบบเติม 2 เข้าหา 0 (นั่นคือปัดเศษให้เป็นจำนวนเต็ม) การดำเนินการนี้จะแสดง ArithmeticException หาก
b == 0
|
rem-long | int64 a, b; int64 result = a % b; |
เศษส่วนแบบเติมเต็ม 2 ฐานหลังการหาร เครื่องหมายของผลลัพธ์จะเหมือนกับเครื่องหมายของ a และสามารถระบุได้อย่างแม่นยำยิ่งขึ้นว่า result == a - (a / b) * b การดำเนินการนี้จะแสดงข้อผิดพลาด ArithmeticException หาก 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); |
เลื่อนไปทางซ้ายแบบบิต (โดยมีอาร์กิวเมนต์ที่มีการมาสก์) |
shr-long | int64 a; int32 b; int64 result = a >> (b & 0x3f); |
เลื่อนไปทางขวาแบบลงนามแบบบิต (พร้อมอาร์กิวเมนต์ที่มีการมาสก์) |
ushr-long | uint64 a; int32 b; int64 result = a >> (b & 0x3f); |
เลื่อนไปทางขวาแบบไม่ลงนามเชิงบิต (โดยมีอาร์กิวเมนต์ที่มีการมาสก์) |
add-float | float a, b; float result = a + b; |
การเพิ่มแบบจุดลอยตัว |
องค์ประกอบย่อยของข้อความ | float a, b; float result = a - b; |
การลบทศนิยม |
mul-float | float a, b; float result = a * b; |
การคูณด้วยจุดลอยตัว |
div-float | float a, b; float result = a / b; |
การหารด้วยจุดลอยตัว |
rem-float | float a, b; float result = a % b; |
เศษทศนิยมหลังการหาร ฟังก์ชันนี้แตกต่างจากเศษ IEEE 754 และกำหนดไว้ดังนี้
result == a - roundTowardZero(a / b) * b
|
add-double | double a, b; double result = a + b; |
การเพิ่มแบบจุดลอยตัว |
คู่ย่อย | double a, b; double result = a - b; |
การลบทศนิยม |
mul-double | double a, b; double result = a * b; |
การคูณด้วยจุดลอยตัว |
div-double | double a, b; double result = a / b; |
การหารด้วยจุดลอยตัว |
rem-double | double a, b; double result = a % b; |
เศษทศนิยมหลังการหาร ฟังก์ชันนี้แตกต่างจากเศษ IEEE 754 และกำหนดไว้ดังนี้
result == a - roundTowardZero(a / b) * b
|