Thiết kế chung
- Mô hình máy và các quy ước gọi có nghĩa là gần như bắt chước các kiến trúc thực phổ biến và các quy ước gọi kiểu C:
- Máy dựa trên thanh ghi và các khung có kích thước cố định khi tạo. Mỗi khung bao gồm một số thanh ghi cụ thể (được chỉ định bởi phương thức) cũng như bất kỳ dữ liệu bổ trợ nào cần thiết để thực thi phương thức, chẳng hạn như (nhưng không giới hạn) bộ đếm chương trình và một tham chiếu đến tệp
.dex
có chứa phương thức . - Khi được sử dụng cho các giá trị bit (chẳng hạn như số nguyên và số dấu phẩy động), thanh ghi được coi là rộng 32 bit. Các cặp thanh ghi liền kề được sử dụng cho các giá trị 64 bit. Không có yêu cầu căn chỉnh cho các cặp thanh ghi.
- Khi được sử dụng cho các tham chiếu đối tượng, thanh ghi được coi là đủ rộng để chứa chính xác một tham chiếu như vậy.
- Về phương diện biểu diễn theo bit,
(Object) null == (int) 0
. - N đối số của một phương thức nằm trong N thanh ghi cuối cùng của khung gọi phương thức, theo thứ tự. Đối số rộng sử dụng hai thanh ghi. Các phương thức phiên bản được chuyển một tham chiếu
this
làm đối số đầu tiên của chúng.
- Máy dựa trên thanh ghi và các khung có kích thước cố định khi tạo. Mỗi khung bao gồm một số thanh ghi cụ thể (được chỉ định bởi phương thức) cũng như bất kỳ dữ liệu bổ trợ nào cần thiết để thực thi phương thức, chẳng hạn như (nhưng không giới hạn) bộ đếm chương trình và một tham chiếu đến tệp
- Đơn vị lưu trữ trong luồng lệnh là số lượng 16-bit không dấu. Một số bit trong một số lệnh bị bỏ qua / phải bằng không.
- Hướng dẫn không bị giới hạn một cách vô cớ đối với một loại cụ thể. Ví dụ, các lệnh di chuyển các giá trị thanh ghi 32 bit mà không cần diễn giải không phải chỉ định liệu chúng đang di chuyển int hay float.
- Có các nhóm hằng số được liệt kê và lập chỉ mục riêng cho các tham chiếu đến chuỗi, kiểu, trường và phương thức.
- Dữ liệu theo chiều dọc bit được biểu diễn trong dòng trong dòng lệnh.
- Bởi vì, trong thực tế, một phương thức cần nhiều hơn 16 thanh ghi là không phổ biến và bởi vì việc cần nhiều hơn 8 thanh ghi là điều khá phổ biến, nên nhiều lệnh bị giới hạn ở việc chỉ giải quyết 16 thanh ghi đầu tiên. Khi hợp lý có thể, các hướng dẫn cho phép tham chiếu đến tối đa 256 thanh ghi đầu tiên. Ngoài ra, một số lệnh có các biến thể cho phép số lượng thanh ghi lớn hơn nhiều, bao gồm một cặp lệnh
move
bắt tất cả có thể giải quyết các thanh ghi trong phạm viv0
-v65535
. Trong trường hợp một biến thể lệnh không có sẵn để giải quyết một thanh ghi mong muốn, thì nội dung thanh ghi sẽ được chuyển từ thanh ghi ban đầu sang thanh ghi thấp (trước khi hoạt động) và / hoặc chuyển từ thanh ghi kết quả thấp lên cao. đăng ký (sau khi hoạt động). - Có một số "lệnh giả" được sử dụng để chứa các trọng tải dữ liệu có độ dài thay đổi, được tham chiếu bởi các lệnh thông thường (ví dụ:
fill-array-data
). Không bao giờ được gặp các hướng dẫn như vậy trong quá trình thực thi thông thường. Ngoài ra, các hướng dẫn phải được đặt trên các hiệu số bytecode được đánh số chẵn (nghĩa là, căn chỉnh 4 byte). Để đáp ứng yêu cầu này, các công cụ tạo dex phải phát ra một lệnhnop
bổ sung như một bộ đệm nếu lệnh như vậy không được đánh dấu. Cuối cùng, mặc dù không bắt buộc, người ta mong đợi rằng hầu hết các công cụ sẽ chọn phát ra các lệnh này ở cuối các phương thức, vì nếu không sẽ có trường hợp cần các lệnh bổ sung để phân nhánh xung quanh chúng. - Khi được cài đặt trên một hệ thống đang chạy, một số hướng dẫn có thể bị thay đổi, thay đổi định dạng của chúng, như một cách tối ưu hóa liên kết tĩnh trong thời gian cài đặt. Điều này cho phép thực thi nhanh hơn khi đã biết liên kết. Xem tài liệu định dạng hướng dẫn liên quan để biết các biến thể được đề xuất. Từ "đề nghị" được sử dụng một cách khuyên nhủ; không bắt buộc phải thực hiện những điều này.
- Cú pháp con người và ghi nhớ:
- Thứ tự đích-sau đó-nguồn cho các đối số.
- Một số mã opcode có hậu tố tên phân biệt để chỉ ra (các) loại mà chúng hoạt động:
- Loại mã quang 32-bit chung không được đánh dấu.
- Loại mã quang 64-bit chung được gắn với
-wide
. - Các mã opcode cụ thể cho loại được ghi kèm theo loại của chúng (hoặc viết tắt đơn giản), một trong số:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
- Một số mã opcodes có hậu tố phân biệt để phân biệt các hoạt động giống hệt nhau có bố cục hoặc tùy chọn hướng dẫn khác nhau. Các hậu tố này được phân tách khỏi tên chính bằng dấu gạch chéo ("
/
") và chủ yếu tồn tại để tạo ánh xạ một-một với các hằng số tĩnh trong mã tạo và diễn giải các tệp thực thi (nghĩa là, để giảm sự mơ hồ cho con người). - Trong các mô tả ở đây, chiều rộng của một giá trị (ví dụ, cho biết phạm vi của một hằng số hoặc số lượng thanh ghi có thể được giải quyết) được nhấn mạnh bằng cách sử dụng một ký tự trên bốn bit chiều rộng.
- Ví dụ: trong hướng dẫn "
move-wide/from16 vAA, vBBBB
":- "
move
" là opcode cơ sở, cho biết hoạt động cơ sở (di chuyển giá trị của thanh ghi). - "
wide
" là hậu tố tên, cho biết rằng nó hoạt động trên dữ liệu rộng (64 bit). - "
from16
" là hậu tố opcode, chỉ ra một biến thể có tham chiếu thanh ghi 16 bit làm nguồn. - "
vAA
" là thanh ghi đích (được ngụ ý bởi hoạt động; một lần nữa, quy tắc là các đối số đích luôn đến trước), thanh ghi này phải nằm trong phạm viv0
-v255
. - "
vBBBB
" là thanh ghi nguồn, phải nằm trong dảiv0
-v65535
.
- "
- Xem tài liệu định dạng hướng dẫn để biết thêm chi tiết về các định dạng hướng dẫn khác nhau (được liệt kê trong "Op & Format") cũng như chi tiết về cú pháp opcode.
- Xem tài liệu định dạng tệp
.dex
để biết thêm chi tiết về vị trí của mã bytecode phù hợp với bức tranh lớn hơn.
Tóm tắt bộ mã bytecode
Op & Định dạng | Ghi nhớ / Cú pháp | Tranh luận | Sự mô tả |
---|---|---|---|
00 10x | nop | Các chu trình thải. Lưu ý: Các lệnh giả mang dữ liệu được gắn thẻ với opcode này, trong trường hợp này byte bậc cao của đơn vị opcode cho biết bản chất của dữ liệu. Xem "Định dạng | |
01 12x | di chuyển vA, vB | A: thanh ghi đích (4 bit)B: thanh ghi nguồn (4 bit) | Di chuyển nội dung của một thanh ghi không phải đối tượng này sang một thanh ghi khác. |
02 22x | di chuyển / từ 16 vAA, vBBBB | A: thanh ghi đích (8 bit)B: thanh ghi nguồn (16 bit) | Di chuyển nội dung của một thanh ghi không phải đối tượng này sang một thanh ghi khác. |
03 32x | di chuyển / 16 vAAAA, vBBBB | A: thanh ghi đích (16 bit)B: thanh ghi nguồn (16 bit) | Di chuyển nội dung của một thanh ghi không phải đối tượng này sang một thanh ghi khác. |
04 12x | di chuyển rộng vA, vB | A: cặp thanh ghi đích (4 bit)B: cặp thanh ghi nguồn (4 bit) | Di chuyển nội dung của cặp thanh ghi này sang cặp thanh ghi khác. Lưu ý: Việc chuyển từ |
05 22x | di chuyển rộng / từ 16 vAA, vBBBB | A: cặp thanh ghi đích (8 bit)B: cặp thanh ghi nguồn (16 bit) | Di chuyển nội dung của cặp thanh ghi này sang cặp thanh ghi khác. Lưu ý: Các cân nhắc triển khai cũng giống như |
06 32x | di chuyển rộng / 16 vAAAA, vBBBB | A: cặp thanh ghi đích (16 bit)B: cặp thanh ghi nguồn (16 bit) | Di chuyển nội dung của cặp thanh ghi này sang cặp thanh ghi khác. Lưu ý: Các cân nhắc triển khai cũng giống như |
07 12x | đối tượng di chuyển vA, vB | A: thanh ghi đích (4 bit)B: thanh ghi nguồn (4 bit) | Di chuyển nội dung của một thanh ghi mang đối tượng này sang một thanh ghi mang đối tượng khác. |
08 22x | move-object / from16 vAA, vBBBB | A: thanh ghi đích (8 bit)B: thanh ghi nguồn (16 bit) | Di chuyển nội dung của một thanh ghi mang đối tượng này sang một thanh ghi mang đối tượng khác. |
09 32x | move-object / 16 vAAAA, vBBBB | A: thanh ghi đích (16 bit)B: thanh ghi nguồn (16 bit) | Di chuyển nội dung của một thanh ghi mang đối tượng này sang một thanh ghi mang đối tượng khác. |
0a 11x | kết quả di chuyển vAA | A: thanh ghi đích (8 bit) | Di chuyển kết quả không phải đối tượng một từ của loại lệnh gọi gần đây invoke- kind vào thanh ghi được chỉ định. Điều này phải được thực hiện dưới dạng lệnh ngay sau một invoke- kind mà kết quả (một từ, không phải đối tượng) không bị bỏ qua; bất kỳ nơi nào khác là không hợp lệ. |
0b 11x | chuyển-kết quả-rộng vAA | A: cặp thanh ghi đích (8 bit) | Di chuyển kết quả từ kép của kiểu gọi gần đây invoke- kind vào cặp thanh ghi được chỉ định. Điều này phải được thực hiện dưới dạng lệnh ngay sau một invoke- kind mà kết quả (từ kép) không bị bỏ qua; bất kỳ nơi nào khác là không hợp lệ. |
0c 11x | move-result-object vAA | A: thanh ghi đích (8 bit) | Di chuyển kết quả đối tượng của kiểu gọi gần đây invoke- kind vào thanh ghi được chỉ định. Điều này phải được thực hiện dưới dạng lệnh ngay sau một invoke- kind filled-new-array mà kết quả (đối tượng) của nó không bị bỏ qua; bất kỳ nơi nào khác là không hợp lệ. |
0ngày 11x | di chuyển ngoại lệ vAA | A: thanh ghi đích (8 bit) | Lưu một ngoại lệ vừa bắt được vào thanh ghi đã cho. Đây phải là lệnh đầu tiên của bất kỳ trình xử lý ngoại lệ nào mà ngoại lệ bắt được không được bỏ qua, và lệnh này chỉ được xuất hiện như là lệnh đầu tiên của trình xử lý ngoại lệ; bất kỳ nơi nào khác là không hợp lệ. |
0e 10x | trả về vô hiệu | Trả về từ một phương thức void . | |
0f 11x | trả lại vAA | A: thanh ghi giá trị trả về (8 bit) | Trả về từ phương thức trả về giá trị không phải đối tượng một chiều rộng (32 bit). |
10 11x | trả về toàn bộ vAA | A: cặp thanh ghi giá trị trả về (8 bit) | Trả về từ phương thức trả về giá trị độ rộng kép (64-bit). |
11 11x | đối tượng trả về vAA | A: thanh ghi giá trị trả về (8 bit) | Trả về từ một phương thức trả về đối tượng. |
12 11n | const / 4 vA, # + B | A: thanh ghi đích (4 bit)B: int có dấu (4 bit) | Di chuyển giá trị chữ đã cho (dấu mở rộng đến 32 bit) vào thanh ghi được chỉ định. |
13 giây 21 | const / 16 vAA, # + BBBB | A: thanh ghi đích (8 bit)B: int có dấu (16 bit) | Di chuyển giá trị chữ đã cho (dấu mở rộng đến 32 bit) vào thanh ghi được chỉ định. |
14 31i | const vAA, # + BBBBBBBB | A: thanh ghi đích (8 bit)B: hằng số 32 bit tùy ý | Di chuyển giá trị chữ đã cho vào thanh ghi được chỉ định. |
15 21h | const / high16 vAA, # + BBBB0000 | A: thanh ghi đích (8 bit)B: int có dấu (16 bit) | Di chuyển giá trị chữ đã cho (phải-không-mở rộng thành 32 bit) vào thanh ghi được chỉ định. |
16 21 | const-wide / 16 vAA, # + BBBB | A: thanh ghi đích (8 bit)B: int có dấu (16 bit) | Di chuyển giá trị chữ đã cho (dấu mở rộng thành 64 bit) vào cặp thanh ghi được chỉ định. |
17 31i | const-wide / 32 vAA, # + BBBBBBBB | A: thanh ghi đích (8 bit)B: int có dấu (32 bit) | Di chuyển giá trị chữ đã cho (dấu mở rộng thành 64 bit) vào cặp thanh ghi được chỉ định. |
18 51l | const-wide vAA, # + BBBBBBBBBBBBBBBB | A: thanh ghi đích (8 bit)B: hằng số độ rộng kép (64-bit) tùy ý | Di chuyển giá trị chữ đã cho vào cặp thanh ghi được chỉ định. |
19 21h | const-wide / high16 vAA, # + BBBB000000000000 | A: thanh ghi đích (8 bit)B: int có dấu (16 bit) | Di chuyển giá trị chữ đã cho (phải-không-mở rộng thành 64 bit) vào cặp thanh ghi được chỉ định. |
1a 21c | const-string vAA, string @ BBBB | A: thanh ghi đích (8 bit)B: chỉ số chuỗi | Di chuyển một tham chiếu đến chuỗi được chỉ định bởi chỉ mục đã cho vào thanh ghi được chỉ định. |
1b 31c | const-string / jumbo vAA, string @ BBBBBBBB | A: thanh ghi đích (8 bit)B: chỉ số chuỗi | Di chuyển một tham chiếu đến chuỗi được chỉ định bởi chỉ mục đã cho vào thanh ghi được chỉ định. |
1c 21c | const-class vAA, nhập @ BBBB | A: thanh ghi đích (8 bit)B: loại chỉ mục | Di chuyển một tham chiếu đến lớp được chỉ định bởi chỉ mục đã cho vào thanh ghi được chỉ định. Trong trường hợp kiểu được chỉ định là kiểu nguyên thủy, điều này sẽ lưu trữ một tham chiếu đến lớp suy biến của kiểu nguyên thủy. |
1ngày 11x | monitor-enter vAA | A: thanh ghi mang tham chiếu (8 bit) | Mua màn hình cho đối tượng được chỉ định. |
1e 11x | theo dõi-thoát vAA | A: thanh ghi mang tham chiếu (8 bit) | Nhả màn hình cho đối tượng được chỉ định. Lưu ý: Nếu lệnh này cần phải ném một ngoại lệ, nó phải làm như vậy nếu máy tính đã nâng cao hơn lệnh. Có thể hữu ích khi nghĩ về điều này khi lệnh thực thi thành công (theo một nghĩa nào đó), và ngoại lệ được ném sau lệnh nhưng trước khi lệnh tiếp theo có cơ hội chạy. Định nghĩa này giúp cho một phương pháp có thể sử dụng khối bắt tất cả (ví dụ: |
1f 21c | kiểm tra truyền vAA, nhập @ BBBB | A: thanh ghi mang tham chiếu (8 bit)B: loại chỉ mục (16 bit) | Ném một ClassCastException nếu tham chiếu trong thanh ghi đã cho không thể được truyền sang kiểu được chỉ định. Lưu ý: Vì |
20 22c | phiên bản của vA, vB, loại @ CCCC | A: thanh ghi đích (4 bit)B: thanh ghi mang tham chiếu (4 bit)C: loại chỉ mục (16 bit) | Lưu trữ trong thanh ghi đích đã cho 1 nếu tham chiếu được chỉ định là một thể hiện của kiểu đã cho, hoặc 0 nếu không. Lưu ý: Vì |
21 12x | độ dài mảng vA, vB | A: thanh ghi đích (4 bit)B: thanh ghi mang tham chiếu mảng (4 bit) | Lưu trữ trong thanh ghi đích đã cho độ dài của mảng được chỉ định, trong các mục nhập |
22 21c | vAA phiên bản mới, nhập @ BBBB | A: thanh ghi đích (8 bit)B: loại chỉ mục | Xây dựng một phiên bản mới của kiểu được chỉ định, lưu trữ một tham chiếu đến nó trong đích. Kiểu phải tham chiếu đến một lớp không phải là mảng. |
23 22c | mảng mới vA, vB, loại @ CCCC | A: thanh ghi đích (4 bit)B: kích thước đăng kýC: loại chỉ mục | Xây dựng một mảng mới với kiểu và kích thước được chỉ định. Kiểu phải là kiểu mảng. |
24 35c | mới-đầy-mảng {vC, vD, vE, vF, vG}, loại @ BBBB | A: kích thước mảng và số lượng từ đối số (4 bit)B: loại chỉ mục (16 bit)C..G: thanh ghi đối số (mỗi thanh ghi 4 bit) | Xây dựng một mảng có kiểu và kích thước đã cho, điền vào nó với nội dung được cung cấp. Kiểu phải là kiểu mảng. Nội dung của mảng phải là một từ đơn (nghĩa là không có mảng long hoặc double , nhưng các kiểu tham chiếu được chấp nhận). Cá thể đã xây dựng được lưu trữ dưới dạng "kết quả" giống như cách mà các lệnh gọi phương thức lưu trữ kết quả của chúng, do đó, cá thể đã xây dựng phải được chuyển đến một thanh ghi có lệnh move-result-object ngay sau đó (nếu nó được sử dụng ). |
25 3rc | đầy-mới-mảng / dải ô {vCCCC .. vNNNN}, nhập @ BBBB | A: kích thước mảng và số lượng từ đối số (8 bit)B: loại chỉ mục (16 bit)C: thanh ghi đối số đầu tiên (16 bit)N = A + C - 1 | Xây dựng một mảng có kiểu và kích thước đã cho, điền vào nó với nội dung được cung cấp. Giải thích và hạn chế cũng giống như filled-new-array , được mô tả ở trên. |
26 31t | lấp đầy-mảng-dữ liệu vAA, + BBBBBBBB (với dữ liệu bổ sung như được chỉ định bên dưới trong "Định dạng fill-array-data-payload ") | A: tham chiếu mảng (8 bit)B: offset "nhánh" đã ký thành lệnh giả dữ liệu bảng (32 bit) | Điền vào mảng đã cho với dữ liệu được chỉ định. Tham chiếu phải là một mảng nguyên thủy và bảng dữ liệu phải khớp với nó về kiểu và không được chứa nhiều phần tử hơn sẽ phù hợp với mảng. Nghĩa là, mảng có thể lớn hơn bảng và nếu vậy, chỉ các phần tử ban đầu của mảng được thiết lập, để lại phần còn lại. |
27 11x | ném vAA | A: thanh ghi mang ngoại lệ (8 bit) | Ném ngoại lệ được chỉ định. |
28 10t | goto + AA | A: độ lệch nhánh có dấu (8 bit) | Chuyển đến hướng dẫn được chỉ định một cách vô điều kiện. Lưu ý: Độ lệch nhánh không được bằng |
29 20t | goto / 16 + AAAA | A: độ lệch nhánh có dấu (16 bit) | Chuyển đến hướng dẫn được chỉ định một cách vô điều kiện. Lưu ý: Độ lệch nhánh không được bằng |
2a 30t | goto / 32 + AAAAAAAA | A: độ lệch nhánh có dấu (32 bit) | Chuyển đến hướng dẫn được chỉ định một cách vô điều kiện. |
2b 31t | đóng gói-chuyển đổi vAA, + BBBBBBBB (với dữ liệu bổ sung như được chỉ định bên dưới trong "Định dạng packed-switch-payload ") | A: đăng ký để kiểm traB: offset "nhánh" đã ký thành lệnh giả dữ liệu bảng (32 bit) | Chuyển đến một lệnh mới dựa trên giá trị trong thanh ghi đã cho, sử dụng bảng hiệu số tương ứng với mỗi giá trị trong một phạm vi tích phân cụ thể hoặc chuyển sang lệnh tiếp theo nếu không có kết quả phù hợp. |
2c 31t | vAA chuyển đổi thưa thớt, + BBBBBBBB (với dữ liệu bổ sung như được chỉ định bên dưới trong "Định dạng sparse-switch-payload chuyển đổi chậm") | A: đăng ký để kiểm traB: offset "nhánh" đã ký thành lệnh giả dữ liệu bảng (32 bit) | Chuyển đến một lệnh mới dựa trên giá trị trong thanh ghi đã cho, sử dụng một bảng có thứ tự các cặp giá trị-bù trừ hoặc chuyển sang lệnh tiếp theo nếu không có khớp. |
2d..31 23x | cmp loại vAA, vBB, vCC 2d: cmpl-float (lt bias) 2e: cmpg-float (thiên vị gt) 2f: cmpl-double (lt bias) 30: cmpg-double (gt bias) 31: cmp-long | A: thanh ghi đích (8 bit)B: thanh ghi nguồn đầu tiên hoặc cặpC: thanh ghi nguồn thứ hai hoặc cặp | Thực hiện phép so sánh long hoặc dấu phẩy động được chỉ ra, đặt a thành 0 nếu b == c , 1 nếu b > c , hoặc -1 nếu b < c . "Độ lệch" được liệt kê cho các phép toán dấu phẩy động cho biết cách so sánh NaN được xử lý như thế nào: lệnh "gt bias" trả về 1 cho phép so sánh NaN và lệnh "lt bias" trả về -1 . Ví dụ, để kiểm tra xem dấu phẩy động |
32..37 22t | if- kiểm tra vA, vB, + CCCC 32: if-eq 33: if-ne 34: nếu-lt 35: if-ge 36: if-gt 37: if-le | A: đăng ký đầu tiên để kiểm tra (4 bit)B: thanh ghi thứ hai để kiểm tra (4 bit)C: độ lệch nhánh có dấu (16 bit) | Nhánh tới đích đã cho nếu giá trị của hai thanh ghi đã cho so sánh như được chỉ định. Lưu ý: Độ lệch nhánh không được bằng |
38..3d 21t | if- kiểm tra z vAA, + BBBB 38: if-eqz 39: if-nez 3a: if-ltz 3b: if-gez 3c: if-gtz 3d: if-lez | A: đăng ký để kiểm tra (8 bit)B: độ lệch nhánh có dấu (16 bit) | Nhánh tới đích đã cho nếu giá trị của thanh ghi đã cho so sánh với 0 như được chỉ định. Lưu ý: Độ lệch nhánh không được bằng |
3e..43 10x | (không sử dụng) | (không sử dụng) | |
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: ngắn hạn 4b: aput 4c: rộng rãi 4d: aput-object 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-short | A: thanh ghi giá trị hoặc cặp; có thể là nguồn hoặc đích (8 bit)B: thanh ghi mảng (8 bit)C: thanh ghi chỉ mục (8 bit) | Thực hiện thao tác mảng đã xác định tại chỉ mục đã xác định của mảng đã cho, tải hoặc lưu trữ vào thanh ghi giá trị. |
52..5f 22c | tôi instanceop vA, vB, field @ CCCC 52: iget 53: toàn bộ 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: thanh ghi giá trị hoặc cặp; có thể là nguồn hoặc đích (4 bit)B: thanh ghi đối tượng (4 bit)C: chỉ mục tham chiếu trường cá thể (16 bit) | Thực hiện thao tác trường cá thể đối tượng đã xác định với trường đã xác định, tải hoặc lưu trữ vào thanh ghi giá trị. Lưu ý: Các mã opcode này là ứng cử viên hợp lý cho liên kết tĩnh, thay đổi đối số trường thành một phần bù trực tiếp hơn. |
60..6d 21c | s staticop vAA, trường @ BBBB 60: sget 61: rộng rãi 62: sget-object 63: sget-boolean 64: sget-byte 65: sget-char 66: sget-short 67: sput 68: rộng rãi 69: sput-object 6a: sput-boolean 6b: sput-byte 6c: sput-char 6d: sput-short | A: thanh ghi giá trị hoặc cặp; có thể là nguồn hoặc đích (8 bit)B: chỉ số tham chiếu trường tĩnh (16 bit) | Thực hiện thao tác trường tĩnh đối tượng đã xác định với trường tĩnh đã xác định, tải hoặc lưu trữ vào thanh ghi giá trị. Lưu ý: Các mã opcode này là ứng cử viên hợp lý cho liên kết tĩnh, thay đổi đối số trường thành một phần bù trực tiếp hơn. |
6e..72 35c | gọi loại {vC, vD, vE, vF, vG}, meth @ BBBB 6e: gọi-ảo 6f: gọi siêu cấp 70: gọi trực tiếp 71: gọi tĩnh 72: giao diện gọi | A: số từ đối số (4 bit)B: chỉ số tham chiếu phương thức (16 bit)C..G: thanh ghi đối số (mỗi thanh ghi 4 bit) | Gọi phương pháp được chỉ định. Kết quả (nếu có) có thể được lưu trữ với một biến thể move-result* thích hợp làm hướng dẫn ngay sau đó. Khi Trong tệp Dex phiên bản Lưu ý: Các mã opcode này là ứng cử viên hợp lý cho liên kết tĩnh, thay đổi đối số phương thức thành một phần bù trực tiếp hơn (hoặc cặp của chúng). |
73 10x | (không sử dụng) | (không sử dụng) | |
74..78 3rc | gọi- loại / phạm vi {vCCCC .. vNNNN}, meth @ BBBB 74: gọi-ảo / phạm vi 75: gọi siêu cấp / phạm vi 76: gọi trực tiếp / phạm vi 77: gọi-tĩnh / phạm vi 78: gọi giao diện / phạm vi | A: số từ đối số (8 bit)B: chỉ số tham chiếu phương thức (16 bit)C: thanh ghi đối số đầu tiên (16 bit)N = A + C - 1 | Gọi phương pháp được chỉ định. Xem mô tả invoke- kind đầu tiên ở trên để biết chi tiết, cảnh báo và đề xuất. |
79..7a 10x | (không sử dụng) | (không sử dụng) | |
7b..8f 12x | unop vA, vB 7b: neg-int 7c: not-int 7d: neg-long 7e: không lâu 7f: neg-float 80: neg-double 81: int-to-long 82: int-to-float 83: int-to-double 84: long-to-int 85: lâu nổi 86: dài-to-gấp đôi 87: float-to-int 88: float-to-long 89: float-to-double 8a: double-to-int 8b: dài gấp đôi 8c: double-to-float 8d: int-to-byte 8e: int-to-char 8f: int-to-short | A: thanh ghi đích hoặc cặp (4 bit)B: thanh ghi nguồn hoặc cặp (4 bit) | Thực hiện thao tác đơn nguyên đã xác định trên thanh ghi nguồn, lưu trữ kết quả trong thanh ghi đích. |
90..af 23x | binop vAA, vBB, vCC 90: add-int 91: int phụ 92: đa int 93: div-int 94: rem-int 95: và-int 96: hoặc-int 97: xor-int 98: shl-int 99: shr-int 9a: ushr-int 9b: thêm dài 9c: tiểu dài 9d: đa dài 9e: div-long 9f: rem-long a0: and-long a1: hoặc-dài a2: xor-long a3: dài a4: dài 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: thanh ghi đích hoặc cặp (8 bit)B: thanh ghi nguồn đầu tiên hoặc cặp (8 bit)C: thanh ghi nguồn thứ hai hoặc cặp (8 bit) | Thực hiện thao tác nhị phân đã xác định trên hai thanh ghi nguồn, lưu trữ kết quả trong thanh ghi đích. Lưu ý: Trái ngược với các phép toán |
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: đích và thanh ghi nguồn đầu tiên hoặc cặp (4 bit)B: thanh ghi nguồn thứ hai hoặc cặp (4 bit) | Thực hiện thao tác nhị phân đã xác định trên hai thanh ghi nguồn, lưu trữ kết quả trong thanh ghi nguồn đầu tiên. Lưu ý: Trái ngược với các phép toán |
d0..d7 22 giây | binop / lit16 vA, vB, # + CCCC d0: add-int / lit16 d1: rsub-int (trừ ngược) d2: mul-int / lit16 d3: div-int / lit16 d4: rem-int / lit16 d5: and-int / lit16 d6: hoặc-int / lit16 d7: xor-int / lit16 | A: thanh ghi đích (4 bit)B: thanh ghi nguồn (4 bit)C: hằng số int có dấu (16 bit) | Thực hiện op nhị phân được chỉ định trên thanh ghi được chỉ định (đối số đầu tiên) và giá trị chữ (đối số thứ hai), lưu trữ kết quả trong thanh ghi đích. Lưu ý: |
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: thanh ghi đích (8 bit)B: thanh ghi nguồn (8 bit)C: hằng số int có dấu (8 bit) | Thực hiện op nhị phân được chỉ định trên thanh ghi được chỉ định (đối số đầu tiên) và giá trị chữ (đối số thứ hai), lưu trữ kết quả trong thanh ghi đích. Lưu ý: Xem bên dưới để biết chi tiết về ngữ nghĩa của |
e3..f9 10x | (không sử dụng) | (không sử dụng) | |
fa 45cc | gọi đa hình {vC, vD, vE, vF, vG}, meth @ BBBB, proto @ HHHH | A: số từ đối số (4 bit)B: chỉ số tham chiếu phương thức (16 bit)C: bộ thu (4 bit)D..G: thanh ghi đối số (mỗi thanh ghi 4 bit)H: chỉ số tham chiếu nguyên mẫu (16 bit) | Gọi phương thức đa hình chữ ký được chỉ định. Kết quả (nếu có) có thể được lưu trữ với một biến thể move-result* thích hợp làm hướng dẫn ngay sau đó.Tham chiếu phương thức phải là phương thức đa hình chữ ký, chẳng hạn như java.lang.invoke.MethodHandle.invoke hoặc java.lang.invoke.MethodHandle.invokeExact .Người nhận phải là một đối tượng hỗ trợ phương thức đa hình chữ ký đang được gọi. Tham chiếu nguyên mẫu mô tả các kiểu đối số được cung cấp và kiểu trả về dự kiến. Bytecode invoke-polymorphic có thể tăng các ngoại lệ khi nó thực thi. Các ngoại lệ được mô tả trong tài liệu API cho phương thức đa hình chữ ký đang được gọi.Trình bày trong các tệp Dex từ phiên bản 038 trở đi. |
fb 4rcc | gọi đa hình / dải ô {vCCCC .. vNNNN}, meth @ BBBB, proto @ HHHH | A: số từ đối số (8 bit)B: chỉ số tham chiếu phương thức (16 bit)C: bộ thu (16 bit)H: chỉ số tham chiếu nguyên mẫu (16 bit)N = A + C - 1 | Gọi phương thức xử lý được chỉ định. Xem mô tả invoke-polymorphic ở trên để biết chi tiết.Trình bày trong các tệp Dex từ phiên bản 038 trở đi. |
fc 35c | gọi tùy chỉnh {vC, vD, vE, vF, vG}, call_site @ BBBB | A: số từ đối số (4 bit)B: chỉ số tham chiếu trang web cuộc gọi (16 bit)C..G: thanh ghi đối số (mỗi thanh ghi 4 bit) | Giải quyết và gọi trang web cuộc gọi được chỉ định. Kết quả từ lệnh gọi (nếu có) có thể được lưu trữ với một biến thể move-result* thích hợp làm lệnh ngay sau đó.Lệnh này thực hiện trong hai giai đoạn: giải quyết cuộc gọi trang web và gọi trang web gọi. Độ phân giải trang web cuộc gọi kiểm tra xem trang web cuộc gọi được chỉ định có phiên bản java.lang.invoke.CallSite được liên kết hay không. Nếu không, phương thức trình liên kết bootstrap cho địa chỉ cuộc gọi được chỉ định sẽ được gọi bằng cách sử dụng các đối số có trong tệp DEX (xem call_site_item ). Phương thức trình liên kết bootstrap trả về một cá thể java.lang.invoke.CallSite sau đó sẽ được liên kết với trang web gọi được chỉ định nếu không có liên kết nào tồn tại. Một luồng khác có thể đã thực hiện liên kết trước và nếu vậy thì việc thực thi lệnh sẽ tiếp tục với phiên bản java.lang.invoke.CallSite được liên kết đầu tiên.Lời gọi trang web được thực hiện trên đích java.lang.invoke.MethodHandle của phiên bản java.lang.invoke.CallSite đã phân giải. Đích được gọi như thể đang thực thi lệnh invoke-polymorphic (được mô tả ở trên) bằng cách sử dụng phương thức xử lý và các đối số cho lệnh invoke-custom như các đối số cho một lệnh gọi xử lý phương thức chính xác.Các ngoại lệ được đưa ra bởi phương thức trình liên kết bootstrap được bao bọc trong một java.lang.BootstrapMethodError . Lỗi BootstrapMethodError cũng được nâng lên nếu:
038 trở đi. |
fd 3rc | gọi ra-tùy chỉnh / phạm vi {vCCCC .. vNNNN}, call_site @ BBBB | A: số từ đối số (8 bit)B: chỉ số tham chiếu trang web cuộc gọi (16 bit)C: thanh ghi đối số đầu tiên (16-bit)N = A + C - 1 | Giải quyết và gọi một trang web cuộc gọi. Xem mô tả invoke-custom ở trên để biết chi tiết.Trình bày trong các tệp Dex từ phiên bản 038 trở đi. |
fe 21c | const-method-handle vAA, method_handle @ BBBB | A: thanh ghi đích (8 bit)B: chỉ số xử lý phương thức (16 bit) | Di chuyển một tham chiếu đến xử lý phương thức được chỉ định bởi chỉ mục đã cho vào thanh ghi được chỉ định. Trình bày trong các tệp Dex từ phiên bản 039 trở đi. |
ff 21c | const-method-type vAA, proto @ BBBB | A: thanh ghi đích (8 bit)B: tham chiếu nguyên mẫu phương pháp (16 bit) | Di chuyển một tham chiếu đến nguyên mẫu phương thức được chỉ định bởi chỉ mục đã cho vào thanh ghi được chỉ định. Trình bày trong các tệp Dex từ phiên bản 039 trở đi. |
định dạng đóng gói-chuyển-tải
Tên | Định dạng | Sự mô tả |
---|---|---|
danh tính | ushort = 0x0100 | xác định mã giả chọn |
kích thước | ushort | số lượng mục nhập trong bảng |
khóa đầu tiên | int | giá trị trường hợp chuyển đổi đầu tiên (và thấp nhất) |
mục tiêu | int [] | danh sách các mục tiêu chi nhánh tương đối về size . Các mục tiêu liên quan đến địa chỉ của mã chuyển đổi, không phải của bảng này. |
Lưu ý: Tổng số đơn vị mã cho một phiên bản của bảng này là (size * 2) + 4
.
định dạng chuyển mạch thưa thớt
Tên | Định dạng | Sự mô tả |
---|---|---|
danh tính | ushort = 0x0200 | xác định mã giả chọn |
kích thước | ushort | số lượng mục nhập trong bảng |
chìa khóa | int [] | danh sách các giá trị khóa size , được sắp xếp từ thấp đến cao |
mục tiêu | int [] | danh sách các mục tiêu nhánh tương đối về size , mỗi mục tiêu tương ứng với giá trị khóa tại cùng một chỉ mục. Các mục tiêu liên quan đến địa chỉ của mã chuyển đổi, không phải của bảng này. |
Lưu ý: Tổng số đơn vị mã cho một phiên bản của bảng này là (size * 4) + 2
.
điền-mảng-dữ liệu-định dạng tải trọng
Tên | Định dạng | Sự mô tả |
---|---|---|
danh tính | ushort = 0x0300 | xác định mã giả chọn |
phần tử_ width | ushort | số byte trong mỗi phần tử |
kích thước | uint | số phần tử trong bảng |
dữ liệu | ubyte [] | giá trị dữ liệu |
Lưu ý: Tổng số đơn vị mã cho một phiên bản của bảng này là (size * element_width + 1) / 2 + 4
.
Chi tiết hoạt động toán học
Lưu ý: Các phép toán dấu phẩy động phải tuân theo các quy tắc IEEE 754, sử dụng quy trình làm tròn đến gần nhất và dần dần, trừ khi có quy định khác.
Opcode | C Ngữ nghĩa | Ghi chú |
---|---|---|
neg-int | int32 a; int32 kết quả = -a; | Bổ sung hai lá một. |
not-int | int32 a; kết quả int32 = ~ a; | Phần bổ sung đơn nhất. |
dài hạn | int64 a; int64 kết quả = -a; | Bổ sung hai lá một. |
không lâu | int64 a; kết quả int64 = ~ a; | Phần bổ sung đơn nhất. |
Neg-float | phao 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 . |