Thiết kế chung
- Mô hình máy và các quy ước gọi điện nhằm mục đích mô phỏng gần đúng các kiến trúc thực tế phổ biến và các quy ước gọi điện kiểu C:
- Máy hoạt động 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ố lượng thanh ghi cụ thể (được chỉ định bởi phương thức) cũng như mọi dữ liệu bổ sung 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à tham chiếu đến tệp
.dex
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), các 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, các thanh ghi được coi là đủ rộng để chứa chính xác một tham chiếu như vậy.
- Về mặt biểu diễn theo bit,
(Object) null == (int) 0
. - N đối số cho 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 tiêu thụ hai thanh ghi. Các phương thức instance được truyền tham chiếu
this
làm đối số đầu tiên của chúng.
- Máy hoạt động 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ố lượng thanh ghi cụ thể (được chỉ định bởi phương thức) cũng như mọi dữ liệu bổ sung 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à tham chiếu đến tệp
- Đơn vị lưu trữ trong luồng lệnh là số lượng không dấu 16 bit. Một số bit trong một số lệnh bị bỏ qua/phải bằng 0.
- Hướng dẫn không bị giới hạn vô cớ ở 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 thông dịch không cần phải xác định xem chúng đang di chuyển kiểu int hay float.
- Có các nhóm hằng số được liệt kê và lập chỉ mục riêng để tham chiếu đến chuỗi, loại, trường và phương thức.
- Dữ liệu bằng chữ theo bit được biểu diễn nội dòng trong luồng lệnh.
- Bởi vì, trên thực tế, hiếm khi một phương thức cần nhiều hơn 16 thanh ghi và vì việc cần nhiều hơn 8 thanh ghi là khá phổ biến nên nhiều lệnh bị giới hạn chỉ giải quyết 16 thanh ghi đầu tiên. Khi có thể, các lệnh cho phép tham chiếu tới 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 di
move
hợp có thể xử lý các thanh ghi trong phạm viv0
–v65535
. Trong trường hợp không có biến thể lệnh để giải quyết một thanh ghi mong muốn, dự kiến nội dung thanh ghi sẽ được chuyển từ thanh ghi ban đầu sang thanh ghi thấp (trước khi thực hiện thao tác) và/hoặc chuyển từ thanh ghi kết quả thấp sang thanh ghi cao. đăng ký (sau khi hoạt động). - Có một số "lệnh giả" được sử dụng để chứa tải trọng dữ liệu có độ dài thay đổi, được tham chiếu bằng các hướng dẫn thông thường (ví dụ:
fill-array-data
). Những hướng dẫn như vậy không bao giờ được gặp trong quá trình thực thi thông thường. Ngoài ra, các lệnh phải được đặt trên các offset mã byte được đánh số chẵn (nghĩa là được 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 dưới dạng bộ đệm nếu lệnh đó không được căn chỉnh. Cuối cùng, mặc dù không bắt buộc, nhưng dự kiến là hầu hết các công cụ sẽ chọn đưa ra các hướng dẫn này ở cuối các phương thức, vì nếu không thì có thể sẽ cần các hướng dẫn bổ sung để phân nhánh xung quanh chúng. - Khi được cài đặt trên 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, dưới dạng tối ưu hóa liên kết tĩnh tại thời điểm cài đặt. Điều này cho phép thực hiện nhanh hơn khi biết được mối 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ừ "gợi ý" được sử dụng một cách khôn ngoan; không bắt buộc phải thực hiện những điều này.
- Cú pháp và cách ghi nhớ của con người:
- Thứ tự đích-sau-nguồn cho các đối số.
- Một số opcode có hậu tố tên phân biệt để chỉ ra (các) loại chúng hoạt động:
- Các mã opcode 32-bit chung không được đánh dấu.
- Các mã opcode 64-bit chung có hậu tố là
-wide
. - Các mã opcode dành riêng cho loại được gắn với loại của chúng (hoặc viết tắt đơn giản), một trong:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
.
- Một số opcode 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 lệnh 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 ra á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, độ rộng của một giá trị (ví dụ: biểu thị phạm vi của hằng số hoặc số lượng thanh ghi có thể được xử lý) đượ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 lệnh "
move-wide/from16 vAA, vBBBB
":- "
move
" là opcode cơ sở, biểu thị thao tác cơ bản (di chuyển giá trị của thanh ghi). - "
wide
" là hậu tố tên, biểu thị rằng nó hoạt động trên dữ liệu rộng (64 bit). - "
from16
" là hậu tố opcode, biểu thị 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 phép toán; một lần nữa, quy tắc là các đối số đích luôn đến trước), phải nằm trong phạm viv0
–v255
. - "
vBBBB
" là thanh ghi nguồn, phải nằm trong phạm viv0
–v65535
.
- "
- Xem tài liệu định dạng lệnh để biết thêm chi tiết về các định dạng lệnh khác nhau (được liệt kê trong phần "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í phù hợp của mã byte trong bức tranh lớn hơn.
Tóm tắt bộ bytecode
Hoạt động & Định dạng | Ghi nhớ/Cú pháp | Tranh luận | Sự miêu tả |
---|---|---|---|
00 10x | không | Chu kỳ chất thải. Lưu ý: Các lệnh giả mang dữ liệu được gắn thẻ opcode này, trong trường hợp đó 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 phi đố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 phi đố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 phi đố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 chứa đối tượng này sang một thanh ghi chứa đối tượng khác. |
08 22x | đối tượng di chuyển/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 chứa đối tượng này sang một thanh ghi chứa đối tượng khác. |
09 32x | đối tượng 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 chứa đối tượng này sang một thanh ghi chứa đố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ả phi đối tượng gồm một từ của invoke- kind gần đây nhất vào thanh ghi được chỉ định. Điều này phải được thực hiện dưới dạng hướng dẫn ngay sau một invoke- kind mà kết quả (một từ, không phải đối tượng) không được bỏ qua; bất cứ nơi nào khác là không hợp lệ. |
0b 11x | di chuyển toàn bộ kết quả vAA | A: cặp thanh ghi đích (8 bit) | Di chuyển kết quả hai từ của invoke- kind gần đây nhất vào cặp thanh ghi được chỉ định. Điều này phải được thực hiện dưới dạng hướng dẫn ngay sau một invoke- kind mà kết quả (từ kép) không được bỏ qua; bất cứ nơi nào khác là không hợp lệ. |
0c 11x | di chuyển-kết quả-đối tượng vAA | A: thanh ghi đích (8 bit) | Di chuyển kết quả đối tượng của invoke- kind gần đây nhất vào thanh ghi được chỉ định. Điều này phải được thực hiện dưới dạng hướng dẫn ngay sau một invoke- kind hoặc filled-new-array mà kết quả (đối tượng) của nó không được bỏ qua; bất cứ nơi nào khác là không hợp lệ. |
0d 11x | ngoại lệ di chuyển vAA | A: thanh ghi đích (8 bit) | Lưu một ngoại lệ vừa bắt được vào sổ đăng ký đã 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ị bắt không được bỏ qua và lệnh này chỉ phải xảy ra dưới dạng lệnh đầu tiên của trình xử lý ngoại lệ; bất cứ nơi nào khác là không hợp lệ. |
0e 10x | trả lại khoảng trống | 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 có độ rộng đơn (32-bit). |
10 11x | vAA toàn diện | A: cặp thanh ghi giá trị trả về (8 bit) | Trả về từ phương thức trả về giá trị độ rộng gấp đôi (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ị bằng chữ đã cho (kéo dài ký hiệu thành 32 bit) vào thanh ghi đã chỉ định. |
13 21 giây | const/16 vAA, #+BBBB | A: thanh ghi đích (8 bit)B: int có dấu (16 bit) | Di chuyển giá trị bằng chữ đã cho (kéo dài ký hiệu thành 32 bit) vào thanh ghi đã 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ị bằng chữ đã cho vào thanh ghi đã 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ị bằng chữ đã cho (mở rộng bằng 0 sang phải 32 bit) vào thanh ghi đã chỉ định. |
16 21 giây | const-wide/16 vAA, #+BBBB | A: thanh ghi đích (8 bit)B: int có dấu (16 bit) | Di chuyển giá trị bằng chữ đã cho (kéo dài ký hiệu thành 64 bit) vào cặp thanh ghi đã 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ị bằng chữ đã cho (kéo dài ký hiệu thành 64 bit) vào cặp thanh ghi đã 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ị bằng chữ đã cho vào cặp thanh ghi đã 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ị bằng chữ đã cho (mở rộng bằng 0 sang phải 64 bit) vào cặp thanh ghi đã 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 đã 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 đã chỉ định. |
1c 21c | const-class vAA, type@BBBB | A: thanh ghi đích (8 bit)B: chỉ mục loại | Di chuyển một tham chiếu đến lớp được chỉ định bởi chỉ mục đã cho vào thanh ghi đã chỉ định. Trong trường hợp kiểu được chỉ định là 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. |
1d 11x | màn hình nhập vAA | A: thanh ghi mang tham chiếu (8 bit) | Thu thập màn hình cho đối tượng được chỉ định. |
1e 11x | thoát màn hình 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 đưa ra một ngoại lệ thì nó phải thực hiện như thể máy tính đã vượt qua lệnh đó. Có thể hữu ích khi coi đây là lệnh thực thi thành công (theo một nghĩa nào đó) và ngoại lệ được đưa ra sau lệnh nhưng trước khi lệnh tiếp theo có cơ hội chạy. Định nghĩa này cho phép một phương thức có thể sử dụng khối bắt tất cả dọn dẹp màn hình (ví dụ: |
1f 21c | kiểm tra vAA, type@BBBB | A: thanh ghi mang tham chiếu (8 bit)B: chỉ mục loại (16 bit) | Ném ClassCastException nếu tham chiếu trong thanh ghi đã cho không thể chuyển sang loại đã chỉ định. Lưu ý: Vì |
20 22c | phiên bản của vA, vB, type@CCCC | A: thanh ghi đích (4 bit)B: thanh ghi mang tham chiếu (4 bit)C: chỉ mục loại (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 loại đã 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ữ tại đích đã cho, đăng ký độ dài của mảng được chỉ định, trong các mục |
22 21c | vAA phiên bản mới, type@BBBB | A: thanh ghi đích (8 bit)B: chỉ mục loại | Xây dựng một phiên bản mới của loại được chỉ định, lưu trữ một tham chiếu đến nó ở đích. Loại này phải tham chiếu đến một lớp không có mảng. |
23 22c | mảng mới vA, vB, type@CCCC | A: thanh ghi đích (4 bit)B: thanh ghi kích thướcC: chỉ mục loại | Xây dựng một mảng mới có kiểu và kích thước được chỉ định. Kiểu này phải là kiểu mảng. |
24 35c | mảng mới được điền {vC, vD, vE, vF, vG}, type@BBBB | A: kích thước mảng và số lượng từ đối số (4 bit)B: chỉ mục loại (16 bit)C..G: thanh ghi đối số (mỗi thanh ghi 4 bit) | Tạo một mảng có kiểu và kích thước nhất định, điền nội dung được cung cấp vào mảng đó. Kiểu này phải là kiểu mảng. Nội dung của mảng phải là một từ (nghĩa là không có mảng long hoặc double nhưng có thể chấp nhận các loại tham chiếu). Phiên bản được xây dựng được lưu trữ dưới dạng "kết quả" giống như cách các hướng dẫn gọi phương thức lưu trữ kết quả của chúng, do đó, phiên bản được xây dựng phải được chuyển đến một thanh ghi với lệnh move-result-object ngay sau đó (nếu nó được sử dụng ). |
25 3rc | điền-mảng/dải mới {vCCCC .. vNNNN}, type@BBBB | A: kích thước mảng và số lượng từ đối số (8 bit)B: chỉ mục loại (16 bit)C: thanh ghi đối số đầu tiên (16 bit)N = A + C - 1 | Tạo một mảng có kiểu và kích thước nhất định, điền nội dung được cung cấp vào mảng đó. Việc làm rõ và hạn chế cũng giống như filled-new-array được mô tả ở trên. |
26 31t | fill-array-data 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: phần bù "nhánh" đã ký cho 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 mức vừa với trong 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 đặt, để 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 | đi đến +AA | A: offset nhánh có dấu (8 bit) | Nhảy vô điều kiện đến hướng dẫn được chỉ định. Lưu ý: Độ lệch nhánh không được bằng |
29 20t | goto/16 +AAAA | A: offset nhánh có dấu (16 bit) | Nhảy vô điều kiện đến hướng dẫn được chỉ định. Lưu ý: Độ lệch nhánh không được bằng |
2a 30t | goto/32 +AAAAAAAA | A: offset nhánh có dấu (32 bit) | Nhảy vô điều kiện đến hướng dẫn được chỉ định. |
2b 31t | chuyển mạch đóng gó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: phần bù "nhánh" đã ký cho lệnh giả dữ liệu bảng (32 bit) | Chuyển sang lệnh mới dựa trên giá trị trong thanh ghi đã cho, sử dụng bảng bù tương ứng với từng 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 khớp. |
2c 31t | thưa-chuyển đổi vAA, +BBBBBBBB (với dữ liệu bổ sung như được chỉ định bên dưới trong " Định dạng sparse-switch-payload ") | A: đăng ký kiểm traB: phần bù "nhánh" đã ký cho lệnh giả dữ liệu bảng (32 bit) | Chuyển sang lệnh mới dựa trên giá trị trong thanh ghi đã cho, sử dụng bảng theo thứ tự gồm các cặp giá trị bù hoặc chuyển sang lệnh tiếp theo nếu không khớp. |
2d..31 23x | cmp loại vAA, vBB, vCC 2d: cmpl-float (lt thiên vị) 2e: cmpg-float (gt thiên vị) 2f: cmpl-double (lt thiên vị) 30: cmpg-double (gt thiên vị) 31: dài cmp | A: thanh ghi đích (8 bit)B: thanh ghi hoặc cặp nguồn đầu tiênC: thanh ghi hoặc cặp nguồn thứ hai | Thực hiện dấu phẩy động hoặc so sánh long được chỉ định, đặ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 xử lý so sánh NaN : hướng dẫn "gt Bias" trả về 1 đối với so sánh NaN và hướng dẫn "lt Bias" trả về -1 . Ví dụ: để kiểm tra xem có dấu phẩy động |
32..37 22t | if- kiểm tra vA, vB, +CCCC 32: nếu-eq 33: nếu-ne 34: nếu-lt 35: nếu-ge 36: if-gt 37: nếu-le | A: đăng ký đầu tiên để kiểm tra (4 bit)B: thanh ghi thứ hai để kiểm tra (4 bit)C: offset nhánh có dấu (16 bit) | Phân nhánh tới đích đã cho nếu giá trị của hai thanh ghi đã cho so sánh như đã chỉ định. Lưu ý: Độ lệch nhánh không được bằng |
38..3ngày 21t | if- kiểm tra z vAA, +BBBB 38: if-eqz 39: if-nez 3a: if-ltz 3b: nếu-gez 3c: if-gtz 3d: if-lez | A: đăng ký để kiểm tra (8 bit)B: offset nhánh có dấu (16 bit) | Phân nhánh tới đích đã cho nếu giá trị của thanh ghi đã cho so sánh với 0 như đã 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 | mảng vAA, vBB, vCC 44: tuổi 45: toàn bộ độ tuổi 46: tuổi-đối tượng 47: aget-boolean 48: tuổi-byte 49: tuổi-char 4a: tuổi ngắn 4b: aput 4c: aput-wide 4d: aput-đối tượng 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-ngắn | A: thanh ghi hoặc cặp giá trị; 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 vào thanh ghi giá trị. |
52..5f 22c | i instanceop vA, vB, field@CCCC 52: quên 53: iget-wide 54: iget-đối tượng 55: iget-boolean 56: iget-byte 57: iget-char 58: iget-ngắn 59: đầu vào 5a: toàn iput 5b: đối tượng iput 5c: iput-boolean 5d: iput-byte 5e: iput-char 5f: iput-ngắn | A: thanh ghi hoặc cặp giá trị; có thể là nguồn hoặc đích (4 bit)B: thanh ghi đối tượng (4 bit)C: chỉ số tham chiếu trường mẫu (16 bit) | Thực hiện thao tác trường đối tượng được xác định với trường được xác định, tải hoặc lưu trữ vào thanh ghi giá trị. Lưu ý: Các 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 phần bù trực tiếp hơn. |
60..6d 21c | s staticop vAA, field@BBBB 60: sget 61: sget-rộng 62: sget-đối tượng 63: sget-boolean 64: sget-byte 65: sget-char 66: sget-ngắn 67: nhổ nước bọt 68: toàn miệng 69: đối tượng phun ra 6a: dữ liệu-boolean 6b: byte dữ liệu 6c: char-char 6d: ngắn mạch | A: thanh ghi hoặc cặp giá trị; 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 được xác định với trường tĩnh được xác định, tải hoặc lưu trữ vào thanh ghi giá trị. Lưu ý: Các 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 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 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 thức đượ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 như lệnh tiếp theo ngay lập tức. Khi Trong tệp Dex phiên bản Lưu ý: Các 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 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 /range {vCCCC .. vNNNN}, meth@BBBB 74: gọi-ảo/phạm vi 75: gọi siêu/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 thức đượ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 | bỏ mở vA, vB 7b: phủ định 7c: không-int 7d: âm dài 7e: không lâu 7f: âm-float 80: âm-kép 81: từ dài đến dài 82: int-to-float 83: int-to-double 84: dài đến int 85: nổi dài 86: dài đến gấp đôi 87: float-to-int 88: nổi đến dài 89: nổi lên gấp đôi 8a: gấp đôi thành int 8b: dài gấp đôi 8c: nổi gấp đôi 8d: int-to-byte 8e: int-to-char 8f: int-to-ngắn | 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 nhất đã xác định trên thanh ghi nguồn, lưu kết quả vào thanh ghi đích. |
90..af 23x | binop vAA, vBB, vCC 90: bổ sung 91: int phụ 92: đa-int 93: chia-int 94: còn lại 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: hơi dài 9d: mul-long 9e: div-dài 9f: rem-dài a0: và-dài a1: hoặc-dài a2: xor-dài a3: shl-dài a4: dài a5: ushr-dài a6: thêm float a7: phao phụ a8: mul-float a9: div-float aa: rem-float ab: cộng gấp đôi ac: gấp đôi quảng cáo: mul-double ae: div-đôi af: rem-double | A: thanh ghi đích hoặc cặp (8 bit)B: thanh ghi hoặc cặp nguồn đầu tiên (8 bit)C: thanh ghi hoặc cặp nguồn thứ hai (8 bit) | Thực hiện thao tác nhị phân đã xác định trên hai thanh ghi nguồn, lưu kết quả vào 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: int phụ/2addr b2: mul-int/2addr b3: div-int/2addr b4: rem-int/2addr b5: and-int/2addr b6: hoặc-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 là: div-long/2addr bạn trai: 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: thanh ghi hoặc cặp đích và nguồn đầu tiên (4 bit)B: thanh ghi hoặc cặp nguồn thứ hai (4 bit) | Thực hiện thao tác nhị phân đã xác định trên hai thanh ghi nguồn, lưu kết quả vào thanh ghi nguồn đầu tiên. Lưu ý: Trái ngược với các phép toán |
d0..d7 22s | binop /lit16 vA, vB, #+CCCC d0: bổ sung/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ố thứ nhất) và giá trị bằng chữ (đối số thứ hai), lưu kết quả vào 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 đ: and-int/lit8 de: hoặc-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 thao tác nhị phân được chỉ định trên thanh ghi được chỉ định (đối số thứ nhất) và giá trị bằng chữ (đối số thứ hai), lưu kết quả vào 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: máy 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 như lệnh tiếp theo ngay lập tức.Tham chiếu phương thức phải là một 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 loại đối số được cung cấp và loại trả về dự kiến. Mã byte invoke-polymorphic có thể đưa ra 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.Có mặt trong file Dex từ phiên bản 038 trở đi. |
fb 4rcc | gọi-đa hình/phạm vi {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: máy 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.Có mặt trong file 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 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 như lệnh tiếp theo ngay lập tức.Lệnh này thực hiện theo hai giai đoạn: phân giải trang cuộc gọi và gọi trang cuộc gọi. Độ phân giải trang cuộc gọi sẽ kiểm tra xem trang 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 khởi động cho trang 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 phiên bản java.lang.invoke.CallSite sau đó sẽ được liên kết với trang cuộc 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ệnh gọi trang web được thực hiện trên mục tiêu java.lang.invoke.MethodHandle của phiên bản java.lang.invoke.CallSite đã giải quyết. Mục tiêu được gọi như thể đang thực thi 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 làm đối số cho 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 liên kết bootstrap được gói trong java.lang.BootstrapMethodError . BootstrapMethodError cũng được nêu ra nếu:
038 trở đi. |
fd 3rc | gọi-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.Có mặt trong file Dex từ phiên bản 038 trở đi. |
ngày 21c | const-phương thức-xử lý vAA, phương thức_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 phần điều khiển phương thức được chỉ định bởi chỉ mục đã cho vào thanh ghi đã chỉ định. Có mặt trong tệp Dex từ phiên bản 039 trở đi. |
ff 21c | const-phương thức-loại vAA, proto@BBBB | A: thanh ghi đích (8 bit)B: tham chiếu nguyên mẫu phương thức (16 bit) | Di chuyển 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 đã chỉ định. Có mặt trong tệp Dex từ phiên bản 039 trở đi. |
định dạng tải trọng chuyển mạch đóng gói
Tên | Định dạng | Sự miêu tả |
---|---|---|
nhận dạng | ushort = 0x0100 | xác định mã giả |
kích cỡ | ngắn gọn | số mục 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 có size tương đối. Các mục tiêu liên quan đến địa chỉ của opcode 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 tải trọng chuyển đổi thưa thớt
Tên | Định dạng | Sự miêu tả |
---|---|---|
nhận dạng | ushort = 0x0200 | xác định mã giả |
kích cỡ | ngắn gọn | số mục trong bảng |
phím | 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 có size tương đối, mỗi mục tiêu tương ứng với giá trị khóa ở cùng một chỉ mục. Các mục tiêu liên quan đến địa chỉ của opcode 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
.
định dạng tải trọng dữ liệu mảng-dữ liệu
Tên | Định dạng | Sự miêu tả |
---|---|---|
nhận dạng | ushort = 0x0300 | xác định mã giả |
phần tử_width | ngắn gọn | số byte trong mỗi phần tử |
kích 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 hoạt động của dấu phẩy động phải tuân theo các quy tắc IEEE 754, sử dụng dòng chảy từ vòng đến gần nhất và dần dần, trừ khi có quy định khác.
Mã lệnh | Ngữ nghĩa C | Ghi chú |
---|---|---|
phủ định | int32 một; kết quả int32 = -a; | Hai phần bù đơn nhất. |
không-int | int32 một; kết quả int32 = ~a; | Những cái đơn nhất-bổ sung. |
dài âm | int64 một; kết quả int64 = -a; | Hai phần bù đơn nhất. |
không dài | int64 một; kết quả int64 = ~a; | Những cái đơn nhất-bổ sung. |
phủ định nổi | thả nổi một; kết quả nổi = -a; | Phủ định dấu phẩy động. |
âm đôi | gấp đôi; kết quả kép = -a; | Phủ định dấu phẩy động. |
int-to-long | int32 a; kết quả int64 = (int64) a; | Ký tên mở rộng int32 vào int64 . |
int-to-float | int32 a; kết quả float = (float) a; | Chuyển đổi int32 thành float , sử dụng tròn sang gần nhất. Điều này mất độ chính xác cho một số giá trị. |
Int-to-do đôi | int32 a; Kết quả kép = (gấp đôi) a; | Chuyển đổi int32 thành double . |
dài hạn | int64 a; kết quả int32 = (int32) a; | Cắt ngắn int64 thành int32 . |
dài đến chỗ | int64 a; kết quả float = (float) a; | Chuyển đổi int64 thành float , sử dụng tròn sang gần nhất. Điều này mất độ chính xác cho một số giá trị. |
dài đến đôi | int64 a; Kết quả kép = (gấp đôi) a; | Chuyển đổi int64 thành double , sử dụng tròn sang gần nhất. Điều này mất độ chính xác cho một số giá trị. |
Float-to-int | nổi a; kết quả int32 = (int32) a; | Chuyển đổi float sang int32 , sử dụng TOPARD-TOWARD-ZERO. NaN và -0.0 (số 0 âm) chuyển đổi sang số nguyên 0 . Sự vô cùng và giá trị có độ lớn quá lớn được biểu diễn được chuyển đổi thành 0x7fffffff hoặc -0x80000000 tùy thuộc vào dấu hiệu. |
Float-to-Long | nổi a; kết quả int64 = (int64) a; | Chuyển đổi float sang int64 , sử dụng TOPARD-TOWARD-ZERO. Các quy tắc trường hợp đặc biệt tương tự như đối với áp dụng float-to-int ở đây, ngoại trừ các giá trị ngoài phạm vi được chuyển đổi thành 0x7fffffffffffffff hoặc -0x8000000000000000 tùy thuộc vào dấu hiệu. |
Float-to-do đôi | nổi a; Kết quả kép = (gấp đôi) a; | Chuyển đổi float double , bảo tồn chính xác giá trị. |
hai lần | gấp đôi; kết quả int32 = (int32) a; | Chuyển đổi double thành int32 , sử dụng TOPARD-TOWARD-ZERO. Các quy tắc trường hợp đặc biệt tương tự như đối với các float-to-int đã áp dụng ở đây. |
hai lần | gấp đôi; kết quả int64 = (int64) a; | Chuyển đổi double thành int64 , sử dụng TOPARD-TOWARD-ZERO. Các quy tắc trường hợp đặc biệt tương tự như đối với áp dụng float-to-long ở đây. |
gấp đôi để nổi | gấp đôi; kết quả float = (float) a; | Chuyển đổi double thành float , sử dụng tròn sang gần nhất. Điều này mất độ chính xác cho một số giá trị. |
int-to-byte | int32 a; Kết quả int32 = (A << 24) >> 24; | Cắt ngắn int32 đến int8 , dấu hiệu mở rộng kết quả. |
int-to-sar. | int32 a; Kết quả int32 = A & 0xffff; | Cắt ngắn int32 sang uint16 , không có phần mở rộng dấu hiệu. |
int-to-short | int32 a; Kết quả int32 = (A << 16) >> 16; | Cắt ngắn int32 đến int16 , dấu hiệu mở rộng kết quả. |
add-int | int32 a, b; kết quả int32 = a + b; | Bổ sung TWOS-Cao bổ. |
Sub-int | int32 a, b; kết quả int32 = a - b; | TWOS-CUNG CẤP TUYỆT VỜI. |
rsub-int | int32 a, b; kết quả int32 = b - a; | TWOS-CUNG CẤP TUYỆT VỜI Đảo ngược. |
Mul-int | int32 a, b; kết quả int32 = a * b; | TWOS-CUNG CẤP TUYỆT VỜI. |
Div-int | int32 a, b; kết quả int32 = a / b; | Bộ phận bổ sung twos, làm tròn về 0 (nghĩa là bị cắt ngắn thành số nguyên). Điều này ném ArithmeticException nếu b == 0 . |
REM-INT | int32 a, b; kết quả int32 = a % b; | TWOS-CUỘC SỐNG còn lại sau khi phân chia. Dấu hiệu của kết quả giống như của a , và nó được xác định chính xác hơn là result == a - (a / b) * b . Điều này ném ArithmeticException nếu b == 0 . |
và-int | int32 a, b; Kết quả int32 = A & B; | Bitwise và. |
hoặc-int | int32 a, b; Kết quả int32 = A | b; | BitWise hoặc. |
Xor-int | int32 a, b; kết quả int32 = a ^ b; | BitWise XOR. |
shl-int | int32 a, b; kết quả int32 = a << (b & 0x1f); | Bitwise chuyển sang trái (với đối số đeo mặt nạ). |
Shr-int | int32 a, b; kết quả int32 = a >> (b & 0x1f); | Bitwise đã ký hợp đồng bên phải (với đối số đeo mặt nạ). |
ushr-int | uint32 a, b; kết quả int32 = a >> (b & 0x1f); | Bitwise không dấu sự thay đổi bên phải (với đối số đeo mặt nạ). |
Thêm dài | int64 a, b; kết quả int64 = a + b; | Bổ sung TWOS-Cao bổ. |
phụ dài | int64 a, b; kết quả int64 = a - b; | TWOS-CUNG CẤP TUYỆT VỜI. |
Mul-dài | int64 a, b; kết quả int64 = a * b; | TWOS-CUNG CẤP TUYỆT VỜI. |
Div-dài | int64 a, b; kết quả int64 = a / b; | Bộ phận bổ sung twos, làm tròn về 0 (nghĩa là bị cắt ngắn thành số nguyên). Điều này ném ArithmeticException nếu b == 0 . |
REM dài | int64 a, b; kết quả int64 = a % b; | TWOS-CUỘC SỐNG còn lại sau khi phân chia. Dấu hiệu của kết quả giống như của a , và nó được xác định chính xác hơn là result == a - (a / b) * b . Điều này ném ArithmeticException nếu b == 0 . |
và dài | int64 a, b; Kết quả int64 = A & B; | Bitwise và. |
hoặc dài | int64 a, b; Kết quả int64 = A | b; | BitWise hoặc. |
Xor-dài | int64 a, b; kết quả int64 = a ^ b; | BitWise XOR. |
SHL-dài | int64 a; int32 b; kết quả int64 = a << (b & 0x3f); | Bitwise chuyển sang trái (với đối số đeo mặt nạ). |
SHR-dài | int64 a; int32 b; kết quả int64 = a >> (b & 0x3f); | Bitwise đã ký hợp đồng bên phải (với đối số đeo mặt nạ). |
ushr-dài | uint64 a; int32 b; kết quả int64 = a >> (b & 0x3f); | Bitwise không dấu sự thay đổi bên phải (với đối số đeo mặt nạ). |
Thêm phao | nổi a, b; kết quả float = a + b; | Bổ sung điểm nổi. |
Sploat | nổi a, b; kết quả float = a - b; | Phép trừ điểm nổi. |
mul-float | nổi a, b; kết quả float = a * b; | Nhân hóa điểm nổi. |
DIV-FLOAT | nổi a, b; kết quả float = a / b; | Phân chia điểm nổi. |
Rem-phao | nổi a, b; kết quả float = a % b; | Điểm nổi còn lại sau khi chia. Hàm này khác với phần còn lại của IEEE 754 và được xác định là result == a - roundTowardZero(a / b) * b . |
Thêm nhân đôi | Nhân đôi A, B; Kết quả kép = a + b; | Bổ sung điểm nổi. |
phụ | Nhân đôi A, B; Kết quả kép = a - b; | Phép trừ điểm nổi. |
mul-nhân đôi | Nhân đôi A, B; Kết quả kép = a * b; | Nhân hóa điểm nổi. |
Div-nhân đôi | Nhân đôi A, B; Kết quả kép = a / b; | Phân chia điểm nổi. |
rem-nhân đôi | Nhân đôi A, B; Kết quả kép = A % B; | Điểm nổi còn lại sau khi chia. Hàm này khác với phần còn lại của IEEE 754 và được xác định là result == a - roundTowardZero(a / b) * b . |