Trong bài này, tôi xin phép giới thiệu về kiến trúc, định dạng của lệnh được sử dụng trong các chế độ protected mode, real-address mode và virtual mode trong kiến trúc 8086.
Hình trên mô tả kiến trúc tập lệnh theo một tập các định dạng hay còn gọi là các thành phần của một lệnh. Đối với mỗi lệnh thành phần đầu tiên là Instruction Prefixes, tiếp theo là Opcode chính, rồi đến một khuôn dạng được đặc tả ( an addressing-form specifier ) bao gồm ModR/M byte và đôi khi còn có thêm SIB byte, địa chỉ dịch chuyển (address displacement), và cuối cùng là một immediate data field. Các thành phần này sẽ được tôi mô tả chi tiết ở ngay bên dưới.
Intruction Prefixes
Trong kiến trúc 8086 Được chia làm 4 nhóm, mỗi nhóm được xác định bởi một prefix code. Đối với mỗi lệnh, nó sẽ chỉ có ý nghĩa nếu được thêm vào phía trước. Và mỗi nhóm này đều có thể thêm vào trước 1 lệnh theo bất cứ thứ tự nào nhưng phải có liên quan tới nhau. Group 1 – Nhóm 1 là tập của các lệnh Lock và Repeat Prefixes:
- Lock prefix sử dụng encoded là F0h.
- REPNE/ REPNZ sử dụng encoded là F2h. Repeat-Not-Zero prefix chỉ được áp dụng cho string và các lệnh vào ra. ( F2h cũng là thành phần prefix bắt buộc cho một số câu lệnh).
- REPE/ REPZ được encode là F3h. Repeat prefix cũng chỉ được áp dụng cho string và các lệnh vào ra. ( Tương tự như F2h, F3h cũng là thành phần prefix bắt buộc cho một số câu lệnh).
Group 2 – Nhóm 2 là tập các Segment Override Prefixes:
- 2Eh – CS segment override.
- 36h – SS segment override.
- 3Eh – DS segment override.
- 26h – ES segment override.
- 64h – FS segment override.
- 65h – GS segment override.
Nhóm này được dự trự để được sử dụng cho các lệnh nhảy.
- Rẽ nhánh:
- 2Eh: lệnh rẽ nhánh không được thực hiện.
- 3Eh: lệnh rẽ nhánh được thực hiện.
Hai mã này chỉ được sử dụng với các lệnh nhảy Jcc. Group 3: Độ rộng của Toán Hạng được encoded với prefix là 66h. Group 4: Độ rộng của Địa Chỉ được encoded với prefix là 67h. LOCK prefix (F0h) chỉ ra một lệnh sẽ được sử dụng share memory một cách duy nhât trong một môi trường multiprocessor. Repeat prefix (F2h, F3h) chỉ ra rằng lệnh đó sẽ được thưc hiện với mỗi phần tử của một xâu (string). Chúng ta chỉ sử dụng những prefix này cho string và những câu lệnh vào ra ( I/O íntruction ) ví dụ như: MOVS, CMPS, SCAS, LOGS, STOS, INS và OUTS…
Opcodes
Một opcode chính ( primary opcode )có thể có độ dài từ 1 tới 3 bytes. Đôi khi có 3 bit của trường opcode được encoded in ModR/M byte. Một vài trường nhỏ hơn có thể được định nghĩa bên trong primary opcode. Những trường này được dùng xác định hướng của lệnh, kích thước của displacement, register encoding, condition codes, hoặc là sign extension.
- Two-byte opcode format và tập lệnh SIMD chứa đựng:
- Một escape opcode byte là 0Fh.
- Một mandatory prefix ( 66h, F2h, hoặc là F3h), một escape opcode byte, và opcode byte thứ 2.
- Three-byte opcode format:
- Một escape opcode byte là 0Fh và 2 opcode byte điều kiện thêm vào.
- Một mandatory prefix ( 66h, F2h, hoặc là F3h), và 2 opcode byte điều kiện thêm vào.
ModR/M và SIB Bytes
Các lệnh tham chiếu tới toán hạng trong bộ nhớ có một byte chỉ ra dạng của cụ thể của một addressing-form. ModR/M bao gồm 3 trường, mỗi trường chứa đựng các thông tin sau:
- Trường mod kết hợp với trường r/m tạo thành 32 kiểu giá trị. Trong đó là 8 thanh ghi và 24 chế độ định địa chỉ.
- Trường reg/opcode chỉ ra hoặc là số thanh ghi hoặc ba bit để chỉ ra thông tin của opcode.
- Trường r/m có thể chỉ ra một thanh ghi như 1 toán hạng hoặc nó có thể kết hợp với trường mod để mã hóa 1 chế độ định địa chỉ. Đôi khi sự kết hợp của trường mod và trường r/m dùng để diễn tả thông tin opcode cho một vài lệnh.
Một phần trong ModR/M byte sẽ định rõ là lệnh đó có cần thêm một Second Addressing byte ( SIB byte ) hay không. Base-Plus-Index và Scale-Plus-Index dạng của chế độ định địa chỉ 32 bit yêu cầu SIB byte. Một SIB byte yêu cầu các trường sau:
- Trường Scale chỉ ra scale factor.
- Trường Index chỉ ra số thứ tự của thanh ghi của thanh ghi chỉ số ( index register ).
- Trường Base chỉ ra số thứ tự thanh ghi của thanh ghi cơ sở ( base register ).
Displacement và Immediate Bytes:
- Một vài chế độ định địa chỉ bao gồm một Displacement theo ngay sau ModR/M byte ( hoặc theo sau SIB byte nếu nó có mặt). Nếu một Displacement được chỉ ra, nó có thể là 1, 2, 4 bytes.
- Nếu một lệnh chỉ ra một toán hạng Immediate. Thì toán hạng luôn được theo sau bởi Immediate Nếu Immediate được chỉ ra, nó cũng có thể là 1, 2, 4 bytes.
Ở phần này, tôi đã trình bày các khái niệm cơ bản về về kiến trúc, định dạng của lệnh được sử dụng cho các chế độ protected mode, real-address mode và virtual mode trong kiến trúc 8086. Một số từ chuyên môn tôi không dịch hoàn toàn sang tiếng Việt để các bạn dễ hiểu hơn và tiện tra cứu. Dựa trên kiến thức để về phần này các bạn có thể hiểu hơn về một chương trình shell code đơn giản ở dạng binary hoặc hex. Mở rộng hơn nữa, trong bài sau tôi sẽ trình bày cách sử dụng kiến thức phần này để tiến hành nhận diện một số biến thể của polymorphic virus.