Thiết kế chung
- Mô hình máy và quy ước gọi nhằm mô phỏng gần đúng các cấu trúc thực tế phổ biến và quy ước gọi kiểu C:
- Máy này dựa trên đăng ký và các khung được cố định kích thước khi tạo.
Mỗi khung bao gồm một số lượng thanh ghi cụ thể (do phương thức chỉ định) cũng như mọi dữ liệu bổ trợ 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 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à có chiều rộng 32 bit. Các cặp thanh ghi liền kề được dùng cho các giá trị 64 bit. Không có yêu cầu căn chỉnh đối với các cặp thanh ghi.
- Khi được dùng cho các tệp tham chiếu đối tượng, các thanh ghi được coi là đủ rộng để lưu trữ chính xác một tệp tham chiếu như vậy.
- Về cách biểu diễn bit,
(Object) null == (int) 0
. - Các đối số N đến một phương thức sẽ nằm trong các thanh ghi N 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 thực thể được truyền một tham chiếu
this
làm đối số đầu tiên.
- Máy này dựa trên đăng ký và các khung được cố định kích thước khi tạo.
Mỗi khung bao gồm một số lượng thanh ghi cụ thể (do phương thức chỉ định) cũng như mọi dữ liệu bổ trợ 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à một 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 một cách vô cớ ở một loại cụ thể. Ví dụ: các lệnh di chuyển giá trị thanh ghi 32 bit mà không cần diễn giải không nhất thiết phải chỉ định liệu các lệnh đó có di chuyển số nguyên hay số thực.
- Có các nhóm hằng số được liệt kê và lập chỉ mục riêng biệt để tham chiếu đến các chuỗi, loại, trường và phương thức.
- Dữ liệu cố định bit được biểu thị cùng dòng trong luồng lệnh.
- Vì trong 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 chỉ được giới hạn ở việc chỉ xử lý 16 thanh ghi đầu tiên. Khi 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 cả một cặp lệnh
move
tổng 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, nội dung thanh ghi sẽ được di chuyển từ thanh ghi ban đầu sang thanh ghi thấp (trước thao tác) và/hoặc di chuyển từ thanh ghi kết quả thấp sang thanh ghi cao (sau thao tác). - Có một số "lệnh giả" được dùng để lưu trữ tải trọng dữ liệu có độ dài biến đổi, được các lệnh thông thường tham chiếu đến (ví dụ:
fill-array-data
). Không bao giờ được gặp các lệnh như vậy trong luồng thực thi thông thường. Ngoài ra, các lệnh phải nằm trên các độ dời mã byte có số chẵn (tức 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 thêm một lệnhnop
làm khoảng đệ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 hầu hết các công cụ sẽ chọn phát ra các hướng dẫn này ở cuối phương thức, vì nếu không, có thể cần thêm hướng dẫn để phân nhánh xung quanh các phương thức đó. - 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, dưới dạng tối ưu hoá liên kết tĩnh tại thời điểm cài đặt. Điều này giúp thực thi nhanh hơn sau khi biết được mối liên kết. Hãy xem tài liệu về định dạng hướng dẫn liên quan để biết các biến thể được đề xuất. Bạn nên sử dụng từ "đề xuất"; bạn không bắt buộc phải triển khai các tính năng này.
- Cú pháp và câu thần chú dành cho con người:
- Thứ tự đích đến rồi đến 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:
- Các mã opcode 32 bit loại chung không được đánh dấu.
- Mã opcode 64 bit loại chung có hậu tố là
-wide
. - Mã opcode dành riêng cho loại được thêm hậu tố là loại của mã đó (hoặc một chữ viết tắt rõ ràng), một trong các loại sau:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
.
- Một số mã opcode có hậu tố phân biệt để phân biệt các toán tử giống hệt nhau nhưng có bố cục lệnh hoặc tuỳ chọn khác nhau. Các hậu tố này được phân tách với tên chính bằng dấu gạch chéo
("
/
") và chủ yếu tồn tại để tạo ra mối liên kết một với 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 (tức là để giảm sự mơ hồ cho con người). - Trong phần mô tả ở đây, chiều rộng của một giá trị (chỉ báo, ví dụ: phạm vi của một hằng số hoặc số lượng thanh ghi có thể được định địa chỉ) được nhấn mạnh bằng cách sử dụng một ký tự cho mỗi chiều rộng 4 bit.
- Ví dụ: trong hướng dẫn "
move-wide/from16 vAA, vBBBB
":- "
move
" là mã opcode cơ sở, cho biết toán tử cơ sở (di chuyển giá trị của một thanh ghi). - "
wide
" là hậu tố tên, cho biết rằng lớp này hoạt động trên dữ liệu rộng (64 bit). - "
from16
" là hậu tố mã opcode, cho biết một biến thể có tham chiếu thanh ghi 16 bit làm nguồn. - "
vAA
" là thanh ghi đích (ngụ ý của toán tử; xin nhắc lại, quy tắc là đối số đích luôn đứng 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
.
- "
- Hãy xem tài liệu về định dạng lệnh để biết thêm thông tin chi tiết về các định dạng lệnh khác nhau (liệt kê trong phần "Op & Format" (Thao tác và định dạng)) cũng như thông tin chi tiết về cú pháp mã opcode.
- Hãy xem tài liệu về định dạng tệp
.dex
để biết thêm thông tin chi tiết về vị trí của mã byte trong bức tranh lớn hơn.
Tóm tắt về tập hợp mã byte
Toán tử và định dạng | Thuật nhớ / Cú pháp | Đối số | Mô tả |
---|---|---|---|
00 10x | nop | Chu kỳ chất thải.
Lưu ý: Các lệnh giả mang dữ liệu được gắn thẻ bằng mã opcode này, trong đó, byte thứ tự 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 sang một thanh ghi khác. |
02 22x | move/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 không phải đối tượng sang một thanh ghi khác. |
03 32x | move/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 sang một thanh ghi khác. |
04 12x | vA, vB trên toàn bộ thao tác di chuyển | Cặp thanh ghi đích A: (4 bit)Cặp thanh ghi nguồn B: (4 bit) |
Di chuyển nội dung của một cặp thanh ghi sang một cặp thanh ghi khác.
Lưu ý: Bạn có thể chuyển từ |
05 22x | move-wide/from16 vAA, vBBBB | Cặp thanh ghi đích A: (8 bit)Cặp thanh ghi nguồn B: (16 bit) |
Di chuyển nội dung của một cặp thanh ghi sang một cặp thanh ghi khác.
Lưu ý: Các điều cần cân nhắc khi triển khai cũng giống như |
06 32x | move-wide/16 vAAAA, vBBBB | Cặp thanh ghi đích A: (16 bit)Cặp thanh ghi nguồn B: (16 bit) |
Di chuyển nội dung của một cặp thanh ghi sang một cặp thanh ghi khác.
Lưu ý: Các điều cần cân nhắc khi triển khai cũng giống như |
07 12x | move-object 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 sang một thanh ghi 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 chứa đối tượng sang một thanh ghi 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 chứa đối tượng sang một thanh ghi khác. |
0a 11x | move-result vAA | A: thanh ghi đích (8 bit) |
Di chuyển kết quả không phải đối tượng gồm một từ của invoke-kind gần đây nhất vào thanh ghi được chỉ định.
Bạn phải thực hiện việc này dưới dạng hướng dẫn ngay sau một invoke-kind có kết quả (một từ, không phải đối tượng) không được bỏ qua; mọi vị trí khác đều không hợp lệ. |
0b 11x | move-result-wide vAA | Cặp thanh ghi đích A: (8 bit) |
Di chuyển kết quả từ hai từ của invoke-kind gần đây nhất vào cặp thanh ghi được chỉ định.
Bạn phải thực hiện việc này dưới dạng hướng dẫn ngay sau một invoke-kind có kết quả (từ đôi) không được bỏ qua; mọi vị trí khác đều 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 invoke-kind gần đây nhất vào thanh ghi được chỉ định. Bạn phải thực hiện việc này dưới dạng hướng dẫn ngay sau invoke-kind hoặc filled-new-array có kết quả (đối tượng) không được bỏ qua; mọi vị trí khác đều không hợp lệ. |
0 ngày 11 lần | move-exception vAA | A: thanh ghi đích (8 bit) |
Lưu một ngoại lệ vừa phát hiện 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ệ đã phát hiện không được bỏ qua và lệnh này chỉ được xuất hiện dưới dạng lệnh đầu tiên của trình xử lý ngoại lệ; mọi vị trí khác đều không hợp lệ. |
0e 10x | return-void | Trả về từ một phương thức void . |
|
11x | trả về vAA | A: thanh ghi giá trị trả về (8 bit) |
Trả về từ một phương thức trả về giá trị không phải đối tượng có chiều rộng đơn (32 bit). |
10 11x | vAA trên toàn lượt trả về | Cặp thanh ghi giá trị trả về A: (8 bit) |
Trả về từ một phương thức trả về giá trị có chiều 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 đã ký (4 bit) |
Di chuyển giá trị cố định đã cho (mở rộng dấ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: số nguyên có dấu (16 bit) |
Di chuyển giá trị cố định đã cho (mở rộng dấ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 tuỳ ý |
Di chuyển giá trị cố định đã cho vào thanh ghi đã chỉ định. |
15 21h | const/high16 vAA, #+BBBB0000 | A: thanh ghi đích (8 bit)B: số nguyên có dấu (16 bit) |
Di chuyển giá trị cố định đã cho (mở rộng về bên phải bằng 0 thành 32 bit) vào thanh ghi đã chỉ định. |
16 21 giây | const-wide/16 vAA, #+BBBB | A: thanh ghi đích (8 bit)B: số nguyên có dấu (16 bit) |
Di chuyển giá trị cố định đã cho (mở rộng dấ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: số nguyên có dấu (32 bit) |
Di chuyển giá trị cố định đã cho (mở rộng dấ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ố chiều rộng đôi tuỳ ý (64 bit) |
Di chuyển giá trị cố định đã cho vào cặp thanh ghi đã chỉ định. |
19 21h | const-wide/high16 vAA, #+BBBB000000000000 | A: thanh ghi đích (8 bit)B: số nguyên có dấu (16 bit) |
Di chuyển giá trị cố định đã cho (được mở rộng về bên phải bằng 0 thành 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ỉ mục chuỗi |
Di chuyển tệp tham chiếu đến chuỗi do chỉ mục đã cho chỉ định vào thanh ghi đã chỉ định. |
1b 31c | const-string/jumbo vAA, string@BBBBBBBB | A: thanh ghi đích (8 bit)B: chỉ mục chuỗi |
Di chuyển tệp tham chiếu đến chuỗi do chỉ mục đã cho chỉ định vào đăng ký đã chỉ định. |
1c 21c | const-class vAA, type@BBBB | thanh ghi đích A: (8 bit)chỉ mục loại B: |
Di chuyển một tệp tham chiếu đến lớp được chỉ định theo chỉ mục đã cho vào đăng ký đã chỉ định. Trong trường hợp loại được chỉ định là loại nguyên gốc, lớp này sẽ lưu trữ một tham chiếu đến lớp thoái hoá của loại nguyên gốc. |
1 ngày 11 lần | monitor-enter vAA | A: thanh ghi chứa tham chiếu (8 bit) |
Thu nạp màn hình cho đối tượng được chỉ định. |
1e 11x | monitor-exit vAA | A: thanh ghi chứa tham chiếu (8 bit) |
Giải phóng màn hình cho đối tượng được chỉ định.
Lưu ý: Nếu cần gửi một ngoại lệ, lệnh này phải thực hiện như thể máy tính đã vượt qua lệnh.
Bạn có thể xem đây là hướng dẫn thực thi thành công (theo một nghĩa nào đó) và ngoại lệ được gửi sau hướng dẫn nhưng trước khi hướng dẫn tiếp theo có cơ hội chạy. Định nghĩa này cho phép một phương thức sử dụng tính năng tổng hợp dọn dẹp màn hình (ví dụ: |
1f 21c | check-cast vAA, type@BBBB | A: thanh ghi chứa tham chiếu (8 bit)chỉ mục loại B: (16 bit) |
Gửi một ClassCastException nếu không thể truyền tham chiếu trong đăng ký đã cho sang loại được chỉ định.
Lưu ý: Vì |
20 22c | instance-of vA, vB, type@CCCC | A: thanh ghi đích (4 bit)B: thanh ghi chứa 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ực thể của loại đã cho hoặc 0 nếu không.
Lưu ý: Vì |
21 12x | array-length vA, vB | A: thanh ghi đích (4 bit)B: thanh ghi chứa tham chiếu mảng (4 bit) |
Lưu trữ trong đích đến đã cho, đăng ký độ dài của mảng được chỉ định, trong các mục nhập |
22 21c | new-instance vAA, type@BBBB | thanh ghi đích A: (8 bit)chỉ mục loại B: |
Tạo một thực thể mới của loại đã chỉ định, lưu trữ tham chiếu đến thực thể đó trong đích đến. Kiểu này phải tham chiếu đến một lớp không phải mảng. |
23 22c | new-array vA, vB, type@CCCC | A: thanh ghi đích (4 bit)B: thanh ghi kích thướcC: chỉ mục loại |
Tạo một mảng mới có loại và kích thước được chỉ định. Loại này phải là loại mảng. |
24 35c | filled-new-array {vC, vD, vE, vF, vG}, type@BBBB |
Kích thước mảng A: và số từ đối số (4 bit)Chỉ mục loại B: (16 bit)Bộ đăng ký đối số C..G: (mỗi bộ đăng ký 4 bit)
|
Tạo một mảng có loại và kích thước đã cho, điền nội dung được cung cấp vào mảng đó. Loại này phải là loại mảng. Nội dung của mảng phải là một từ (tức là không có mảng long hoặc double , nhưng các loại tham chiếu được chấp nhận). Thực thể được tạo được lưu trữ dưới dạng "kết quả" theo cách tương tự như các lệnh gọi phương thức lưu trữ kết quả của chúng, vì vậy, thực thể được tạo phải được chuyển sang một thanh ghi bằng lệnh move-result-object ngay sau đó (nếu bạn muốn sử dụng thực thể đó). |
25 3rc | filled-new-array/range {vCCCC .. vNNNN}, type@BBBB | A: kích thước mảng và số 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ó loại và kích thước đã cho, điền vào mảng đó bằng nội dung được cung cấp. Nội dung giải thích và quy định hạn chế giống như filled-new-array , như mô tả ở trên. |
26 31t | fill-array-data vAA, +BBBBBBBB (có dữ liệu bổ sung như được chỉ định
bên dưới trong "Định dạng fill-array-data-payload ") |
Tham chiếu mảng A: (8 bit)B: đã ký "nhánh" bù trừ cho hướng dẫn giả dữ liệu bảng
(32 bit)
|
Điền dữ liệu đã chỉ định vào mảng đã cho. Tham chiếu phải là một mảng các dữ liệu gốc và bảng dữ liệu phải khớp với mảng đó về loại và không được chứa nhiều phần tử hơn mức vừa với mảng. Tức 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, phần còn lại sẽ không được đặt. |
27 11x | gửi vAA | A: thanh ghi chứa ngoại lệ (8 bit) |
Đưa ra ngoại lệ đã chỉ định. |
28 10t | goto +AA | Độ lệch nhánh có dấu A: (8 bit) |
Chuyển đến hướng dẫn được chỉ định mà không có điều kiện.
Lưu ý: Độ dời nhánh không được là |
29 20t | goto/16 +AAAA | Độ lệch nhánh đã ký A: (16 bit) |
Chuyển đến hướng dẫn được chỉ định mà không có điều kiện.
Lưu ý: Độ dời nhánh không được là |
2a 30t | goto/32 +AAAAAAAA | Độ lệch nhánh đã ký A: (32 bit) |
Chuyển đến hướng dẫn được chỉ định mà không có điều kiện. |
2b 31t | packed-switch vAA, +BBBBBBBB (có dữ liệu bổ sung như
được chỉ định bên dưới trong "Định dạng packed-switch-payload ") |
Đăng ký A: để kiểm thửB: đã ký "nhánh" chênh lệch đến hướng dẫn 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 độ dời tương ứng với từng giá trị trong một phạm vi số nguyên cụ thể hoặc chuyển sang lệnh tiếp theo nếu không có giá trị nào khớp. |
2c 31t | sparse-switch vAA, +BBBBBBBB (có dữ liệu bổ sung như
được chỉ định bên dưới trong "Định dạng sparse-switch-payload ") |
Đăng ký A: để kiểm thửB: đã ký "nhánh" chênh lệch đến hướng dẫn 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 thứ tự của các cặp giá trị-chênh lệch hoặc chuyển sang lệnh tiếp theo nếu không có giá trị nào khớp. |
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: 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 phép so sánh dấu phẩy động hoặc 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 .
"Sai số" được liệt kê cho các phép toán dấu phẩy động cho biết cách xử lý các phép so sánh NaN : lệnh "sai số gt" trả về 1 cho các phép so sánh NaN và lệnh "sai số lt" trả về -1 .
Ví dụ: để kiểm tra xem có phải là dấu phẩy động |
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: thanh ghi đầu tiên để kiểm thử (4 bit)B: thanh ghi thứ hai để kiểm thử (4 bit)C: độ dời nhánh đã ký (16 bit) |
Chuyển hướng đến đích đã cho nếu giá trị của hai thanh ghi đã cho so sánh như đã chỉ định.
Lưu ý: Độ dời nhánh không được là |
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 |
đăng ký A: để kiểm thử (8 bit)B: độ dời nhánh có dấu (16 bit) |
Chuyển hướng đến đích đã cho nếu giá trị của thanh ghi đã cho so sánh với 0 như đã chỉ định.
Lưu ý: Độ dời nhánh không được là |
3e..43 10x | (không dùng) | (không 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: aget-short 4b: aput 4c: aput-wide 4d: aput-object 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-short |
Đăng ký giá trị hoặc cặp A: ; có thể là nguồn hoặc đích
(8 bit)B: đăng ký mảng (8 bit)C: đăng ký chỉ mục (8 bit) |
Thực hiện phép toán trên 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 | 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 |
Đăng ký giá trị hoặc cặp A: ; có thể là nguồn hoặc đích (4 bit)đăng ký đối tượng B: (4 bit)chỉ mục tham chiếu trường thực thể C: (16 bit) |
Thực hiện thao tác trường thực thể đối tượng đã xác định bằng trường đã xác định, tải hoặc lưu vào thanh ghi giá trị.
Lưu ý: Các mã opcode này là những ứng cử viên hợp lý để liên kết tĩnh, thay đổi đối số trường thành một độ dời trực tiếp hơn. |
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: thanh ghi giá trị hoặc cặp; có thể là nguồn hoặc đích
(8 bit)B: chỉ mục tham chiếu trường tĩnh (16 bit) |
Thực hiện thao tác trường tĩnh của đối tượng đã xác định bằng trường tĩnh đã xác định, tải hoặc lưu vào thanh ghi giá trị.
Lưu ý: Các mã opcode này là các ứng cử viên hợp lý để liên kết tĩnh, thay đổi đối số trường thành một độ dời trực tiếp hơn. |
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 |
Số từ đối số A: (4 bit)Chỉ mục tham chiếu phương thức B: (16 bit)Bộ đăng ký đối số C..G: (mỗi bộ đăng ký 4 bit)
|
Gọi phương thức được chỉ định. Kết quả (nếu có) có thể được lưu trữ bằng một biến thể move-result* thích hợp làm lệnh tiếp theo ngay lập tức.
Khi Trong tệp Dex phiên bản
Lưu ý: Các mã opcode này là các ứng cử viên hợp lý để liên kết tĩnh, thay đổi đối số phương thức thành một độ dời trực tiếp hơn (hoặc cặp độ dời đó). |
73 10x | (không dùng) | (không dùng) | |
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: số từ đối số (8 bit)B: chỉ mục 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. Hãy xem phần mô tả invoke-kind đầu tiên ở trên để biết thông tin chi tiết, lưu ý và đề xuất.
|
79..7a 10x | (không dùng) | (không dùng) | |
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: bộ nhớ đích hoặc cặp (4 bit)B: bộ nhớ nguồn hoặc cặp (4 bit) |
Thực hiện phép toán một ngôi đã 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: 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: cặp hoặc thanh ghi đích (8 bit)B: cặp hoặc thanh ghi nguồn đầu tiên (8 bit)C: cặp hoặc thanh ghi nguồn thứ hai (8 bit) |
Thực hiện phép toán 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 ý: 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 phép toán 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 ý: 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 (phép trừ đảo) 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: thanh ghi đích (4 bit)B: thanh ghi nguồn (4 bit)C: hằng số int đã ký (16 bit) |
Thực hiện toán tử nhị phân được chỉ định trên thanh ghi được chỉ định (đối số đầu tiên) và giá trị cố định (đố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 đã ký (8 bit) |
Thực hiện toán tử nhị phân được chỉ định trên thanh ghi được chỉ định (đối số đầu tiên) và giá trị cố định (đối số thứ hai), lưu trữ kết quả trong thanh ghi đích.
Lưu ý: Hãy xem bên dưới để biết thông tin chi tiết về ngữ nghĩa của |
e3..f9 10x | (không dùng) | (không dùng) | |
fa 45cc | invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH |
A: số từ đối số (4 bit) B: chỉ mục tham chiếu phương thức (16 bit) C: trình nhận (4 bit) D..G: thanh ghi đối số (mỗi thanh ghi 4 bit) H: chỉ mục 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ữ bằng một biến thể move-result* thích hợp làm lệnh tiếp theo ngay lập tức.Tham chiếu phương thức phải là đến 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 .Trình thu phải là một đối tượng hỗ trợ phương thức đa hình chữ ký đang được gọi. Tài liệu tham khảo nguyên mẫu mô tả các loại đối số được cung cấp và loại dữ liệu trả về dự kiến. Mã byte invoke-polymorphic có thể tạo ra ngoại lệ khi thực thi. Các trường hợp 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ó trong các tệp Dex từ phiên bản 038 trở lên.
|
fb 4rcc | invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH |
A: số từ đối số (8 bit) B: chỉ mục tham chiếu phương thức (16 bit) C: trình nhận (16 bit) H: chỉ mục tham chiếu nguyên mẫu (16 bit) N = A + C - 1
|
Gọi tay cầm phương thức được chỉ định. Hãy xem nội dung mô tả invoke-polymorphic ở trên để biết thông tin chi tiết.Có trong các tệp Dex từ phiên bản 038 trở đi.
|
fc 35c | invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB |
A: số từ đối số (4 bit) B: chỉ mục tham chiếu vị trí gọi (16 bit) C..G: thanh ghi đối số (mỗi thanh ghi 4 bit)
|
Giải quyết và gọi vị trí gọi được chỉ định.
Kết quả của lệnh gọi (nếu có) có thể được lưu trữ bằng một biến thể move-result* thích hợp làm lệnh tiếp theo ngay lập tức.Hướng dẫn này thực thi theo hai giai đoạn: phân giải vị trí gọi và gọi vị trí gọi. Độ phân giải vị trí gọi kiểm tra xem vị trí gọi được chỉ định có thực thể java.lang.invoke.CallSite 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 vị trí gọi được chỉ định sẽ được gọi bằng các đối số có trong tệp DEX (xem call_site_item). Phương thức trình liên kết khởi động trả về một thực thể java.lang.invoke.CallSite , sau đó sẽ được liên kết với vị trí gọi được chỉ định nếu không có mối liên kết nào. Một luồng khác có thể đã thực hiện liên kết trước, và nếu vậy, quá trình thực thi lệnh sẽ tiếp tục với thực thể java.lang.invoke.CallSite được liên kết đầu tiên.Thao tác gọi trang web được thực hiện trên mục tiêu java.lang.invoke.MethodHandle của thực thể
java.lang.invoke.CallSite đã phân giải. Mục tiêu được gọi như thể thực thi invoke-polymorphic (mô tả ở trên) bằng cách sử dụng tay cầm phương thức và đối số cho lệnh invoke-custom làm đối số cho lệnh gọi tay cầm phương thức chính xác.Ngoại lệ do phương thức trình liên kết khởi động tạo ra được gói trong java.lang.BootstrapMethodError . BootstrapMethodError cũng được nâng lên nếu:
038 trở lên.
|
fd 3rc | invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB |
A: số từ đối số (8 bit) B: chỉ mục tham chiếu vị trí 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 vị trí gọi. Hãy xem nội dung mô tả invoke-custom ở trên để biết thông tin chi tiết.Có 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ỉ mục xử lý phương thức (16 bit) |
Di chuyển tệp tham chiếu đến tay cầm phương thức do chỉ mục đã cho chỉ định vào thanh ghi đã chỉ định. Có 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 thức (16 bit) |
Di chuyển tệp tham chiếu đến nguyên mẫu phương thức do chỉ mục đã cho chỉ định vào đăng ký đã chỉ định. Có trong các tệp Dex từ phiên bản 039 trở đi.
|
định dạng packed-switch-payload
Tên | Định dạng | Mô tả |
---|---|---|
ident | ushort = 0x0100 | xác định mã giả |
size | ushort | số mục nhập trong bảng |
first_key | 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 nhánh tương đối size . Các mục tiêu này tương ứng với địa chỉ của mã opcode của nút chuyển, chứ không phải của bảng này.
|
Lưu ý: Tổng số đơn vị mã cho một thực thể của bảng này là (size * 2) + 4
.
định dạng tải trọng chuyển đổi thưa
Tên | Định dạng | Mô tả |
---|---|---|
ident | ushort = 0x0200 | xác định mã giả |
size | ushort | số mục nhập trong bảng |
khoá | int[] | danh sách các giá trị khoá 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 size , mỗi mục tiêu tương ứng với giá trị khoá ở cùng một chỉ mục. Các mục tiêu này tương ứng với địa chỉ của mã opcode của nút chuyển, chứ không phải của bảng này.
|
Lưu ý: Tổng số đơn vị mã cho một thực thể của bảng này là (size * 4) + 2
.
định dạng fill-array-data-payload
Tên | Định dạng | Mô tả |
---|---|---|
ident | ushort = 0x0300 | xác định mã giả |
element_width | ushort | số byte trong mỗi phần tử |
size | uint | số lượng phần tử trong bảng |
data | ubyte[] | giá trị dữ liệu |
Lưu ý: Tổng số đơn vị mã cho một thực thể của bảng này là (size * element_width + 1) / 2 + 4
.
Thông tin chi tiết về phép toán
Lưu ý: Các phép toán dấu phẩy động phải tuân theo quy tắc IEEE 754, sử dụng tính năng làm tròn đến số gần nhất và làm tròn dần, trừ phi có quy định khác.
Mã opcode | Ngữ nghĩa C | Ghi chú |
---|---|---|
neg-int | int32 a; int32 result = -a; |
Số nguyên dấu phẩy động bổ trợ hai. |
not-int | int32 a; int32 result = ~a; |
Số nguyên một chiều. |
neg-long | int64 a; int64 result = -a; |
Số nguyên một chiều bổ trợ hai. |
not-long | int64 a; int64 result = ~a; |
Số nguyên một chiều. |
số thực dấu phẩy động âm | float a; float result = -a; |
Biểu thức phủ định dấu phẩy động. |
neg-double | double a; double result = -a; |
Biểu thức phủ định dấu phẩy động. |
int-to-long | int32 a; int64 result = (int64) a; |
Mở rộng chữ ký của int32 thành int64 . |
int-to-float | int32 a; float result = (float) a; |
Chuyển đổi int32 thành float , sử dụng tính năng làm tròn đến số gần nhất. Điều này làm giảm độ chính xác cho một số giá trị.
|
int-to-double | int32 a; double result = (double) a; |
Chuyển đổi int32 thành double . |
long-to-int | int64 a; int32 result = (int32) a; |
Cắt bớt int64 thành int32 . |
long-to-float | int64 a; float result = (float) a; |
Chuyển đổi int64 thành float , sử dụng tính năng làm tròn đến số gần nhất. Điều này làm giảm độ chính xác cho một số giá trị.
|
long-to-double | int64 a; double result = (double) a; |
Chuyển đổi int64 thành double , sử dụng tính năng làm tròn đến số gần nhất. Điều này làm giảm độ chính xác cho một số giá trị.
|
float-to-int | float a; int32 result = (int32) a; |
Chuyển đổi float thành int32 , sử dụng tính năng làm tròn về 0. NaN và -0.0 (0 âm) chuyển đổi thành số nguyên 0 . Giá trị vô cực và giá trị có độ lớn quá lớn để biểu thị sẽ được chuyển đổi thành 0x7fffffff hoặc -0x80000000 tuỳ thuộc vào dấu.
|
float-to-long | float a; int64 result = (int64) a; |
Chuyển đổi float thành int64 , sử dụng tính năng làm tròn về 0. Các quy tắc trường hợp đặc biệt tương tự như đối với float-to-int sẽ áp dụng ở đây, ngoại trừ việc các giá trị nằm ngoài phạm vi sẽ được chuyển đổi thành 0x7fffffffffffffff hoặc -0x8000000000000000 tuỳ thuộc vào dấu.
|
float-to-double | float a; double result = (double) a; |
Chuyển đổi float thành double , giữ nguyên giá trị một cách chính xác.
|
double-to-int | double a; int32 result = (int32) a; |
Chuyển đổi double thành int32 , sử dụng tính năng làm tròn về 0. Các quy tắc trường hợp đặc biệt tương tự như đối với float-to-int cũng áp dụng ở đây.
|
double-to-long | double a; int64 result = (int64) a; |
Chuyển đổi double thành int64 , sử dụng tính năng làm tròn về 0. Các quy tắc trường hợp đặc biệt tương tự như đối với float-to-long cũng áp dụng ở đây.
|
double-to-float | double a; float result = (float) a; |
Chuyển đổi double thành float , sử dụng tính năng làm tròn đến số gần nhất. Điều này làm giảm độ chính xác cho một số giá trị.
|
int-to-byte | int32 a; int32 result = (a << 24) >> 24; |
Cắt bớt int32 thành int8 , ký hiệu mở rộng kết quả.
|
int-to-char | int32 a; int32 result = a & 0xffff; |
Cắt bớt int32 thành uint16 , mà không cần mở rộng dấu.
|
int-to-short | int32 a; int32 result = (a << 16) >> 16; |
Cắt bớt int32 thành int16 , ký hiệu mở rộng kết quả.
|
add-int | int32 a, b; int32 result = a + b; |
Cộng hai bổ sung. |
sub-int | int32 a, b; int32 result = a - b; |
Phép trừ bổ sung hai. |
rsub-int | int32 a, b; int32 result = b - a; |
Trừ đảo ngược bổ sung hai. |
mul-int | int32 a, b; int32 result = a * b; |
Nhân bổ trợ hai. |
div-int | int32 a, b; int32 result = a / b; |
Phép chia bổ trợ hai, làm tròn về 0 (tức là bị cắt bớt thành số nguyên). Thao tác này sẽ gửi ArithmeticException nếu b == 0 .
|
rem-int | int32 a, b; int32 result = a % b; |
Phần dư bổ trợ hai sau khi chia. Dấu của kết quả giống với dấu của a và được xác định chính xác hơn là result == a - (a / b) * b . Thao tác này sẽ gửi ArithmeticException nếu b == 0 .
|
and-int | int32 a, b; int32 result = a & b; |
Toán tử AND bit. |
or-int | int32 a, b; int32 result = a | b; |
Đảo bit OR. |
xor-int | int32 a, b; int32 result = a ^ b; |
XOR bit. |
shl-int | int32 a, b; int32 result = a << (b & 0x1f); |
Di chuyển bit sang trái (với đối số được che). |
shr-int | int32 a, b; int32 result = a >> (b & 0x1f); |
Chuyển sang phải đã ký bit (với đối số được che). |
ushr-int | uint32 a, b; int32 result = a >> (b & 0x1f); |
Di chuyển sang phải không dấu theo bit (với đối số được che). |
add-long | int64 a, b; int64 result = a + b; |
Cộng hai bổ sung. |
dài | int64 a, b; int64 result = a - b; |
Phép trừ bổ sung hai. |
mul-long | int64 a, b; int64 result = a * b; |
Nhân bổ trợ hai. |
div-long | int64 a, b; int64 result = a / b; |
Phép chia bổ trợ hai, làm tròn về 0 (tức là bị cắt bớt thành số nguyên). Thao tác này sẽ gửi ArithmeticException nếu b == 0 .
|
rem-long | int64 a, b; int64 result = a % b; |
Phần dư bổ trợ hai sau khi chia. Dấu của kết quả giống với dấu của a và được xác định chính xác hơn là result == a - (a / b) * b . Thao tác này sẽ gửi ArithmeticException nếu b == 0 .
|
and-long | int64 a, b; int64 result = a & b; |
Toán tử AND bit. |
or-long | int64 a, b; int64 result = a | b; |
Đảo bit OR. |
xor-long | int64 a, b; int64 result = a ^ b; |
XOR bit. |
shl-long | int64 a; int32 b; int64 result = a << (b & 0x3f); |
Di chuyển bit sang trái (với đối số được che). |
shr-long | int64 a; int32 b; int64 result = a >> (b & 0x3f); |
Chuyển sang phải đã ký bit (với đối số được che). |
ushr-long | uint64 a; int32 b; int64 result = a >> (b & 0x3f); |
Di chuyển sang phải không dấu theo bit (với đối số được che). |
add-float | float a, b; float result = a + b; |
Cộng dấu phẩy động. |
float phụ | float a, b; float result = a - b; |
Phép trừ dấu phẩy động. |
mul-float | float a, b; float result = a * b; |
Nhân dấu phẩy động. |
div-float | float a, b; float result = a / b; |
Phép chia dấu phẩy động. |
rem-float | float a, b; float result = a % b; |
Số dư dấu phẩy động sau khi chia. Hàm này khác với số dư IEEE 754 và được xác định là result == a - roundTowardZero(a / b) * b .
|
add-double | double a, b; double result = a + b; |
Cộng dấu phẩy động. |
sub-double | double a, b; double result = a - b; |
Phép trừ dấu phẩy động. |
mul-double | double a, b; double result = a * b; |
Nhân dấu phẩy động. |
div-double | double a, b; double result = a / b; |
Phép chia dấu phẩy động. |
rem-double | double a, b; double result = a % b; |
Số dư dấu phẩy động sau khi chia. Hàm này khác với phần dư IEEE 754 và được xác định là result == a - roundTowardZero(a / b) * b .
|