2012-11-11 38 views
5

Tôi đang viết trình biên dịch cho các lệnh CPU x86/x64 và tôi không thể tìm ra ý nghĩa của địa chỉ 'chuyển vị'. Ví dụ: hướng dẫn Thêm được nêu chi tiết tại đây: http://www.c-jump.com/CIS77/CPU/x86/X77_0150_encoding_add_edx_displacement.htmx86/x64 Thêm Chuyển địa chỉ

Tôi chỉ đang cố triển khai lệnh thêm nơi đăng ký được thêm vào địa chỉ bộ nhớ bình thường. Vấn đề là, địa chỉ là 'địa chỉ dịch chuyển'. Điều đó có nghĩa là địa chỉ là một giá trị đã ký tên là giá trị bù trừ từ vị trí lệnh?

+3

Bạn có tạo mã lắp ráp không? Bạn không thể tạo mã C, hoặc sử dụng LLVM? Hoặc phát ra mã máy với http://code.google.com/p/asmjit/ hoặc các thư viện khác? Bạn có hiểu rõ tập lệnh x86/64 không? Bạn đã nghiên cứu http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html –

Trả lời

9

Có một vài hình thức khác nhau của toán hạng gián tiếp trong x86:

  1. [reg]
  2. [reg + chuyển]
  3. [chuyển]
  4. [reg * liên tục + reg ]
  5. [reg * constant + reg + displacement]

"Chuyển vị" chỉ là một hằng số được thêm vào phần còn lại của địa chỉ. Trong trường hợp không có thành phần nào của địa chỉ khác với hằng số, nó vẫn được gọi là "chuyển vị".Điều này chủ yếu cho sự nhất quán với các hình thức giải quyết khác.

Một cách khác để nhìn vào nó là tất cả các địa chỉ có dạng

[reg * liên tục + reg + chuyển]

Với mỗi thành phần cho phép giá trị 0.

Biểu mẫu [displacement] chỉ là mã hóa trong đó tất cả các thành phần khác với chuyển vị là zero.

Là một trình biên dịch, hai dạng cuối cùng đặc biệt thú vị. Họ làm cho nó dễ dàng để mã hóa những thứ như pArray[index]->field + 1 trong một hướng dẫn duy nhất.

+0

Ok vậy làm thế nào [reg * constant + reg + displacement] được mã hóa thành lệnh máy? Nói rằng tôi có một mảng tại vị trí bộ nhớ 0x00000001 và tôi muốn truy cập vào chỉ mục của nó là AL. Tôi đoán tôi muốn sử dụng hướng dẫn di chuyển và làm MOV AH 0x00000001 [AL]. Tôi nghĩ đó chỉ là [reg + displacement]. Phần 6 của trang này cho thấy mã hóa byte R/M nhưng nó thực sự khó hiểu: http://www.c-jump.com/CIS77/CPU/x86/lecture.html –

+0

Hãy xem tập 2 của hướng dẫn sử dụng. Mỗi lệnh chỉ định các dạng mã hóa của nó. Các dạng mã hóa liệt kê các toán hạng r/m chấp nhận các toán hạng đăng ký hoặc bộ nhớ trong byte mod/rm. –

+0

Hãy xem tập 2 của hướng dẫn sử dụng. Mỗi lệnh chỉ định các dạng mã hóa của nó. Các dạng mã hóa liệt kê các toán hạng r/m chấp nhận các toán hạng đăng ký hoặc bộ nhớ trong byte mod/rm. Trong chương 2 của tập 2, phần 2.1 có một bảng cho thấy ý nghĩa của byte mod/m. Các biểu mẫu có [-] [-] được liệt kê biểu thị một bảng mã sử dụng byte SIB. Địa chỉ SIB có dạng reg * constant + reg. Một số dạng của byte mod/rm chỉ ra rằng byte SIB được theo sau bởi một sự dịch chuyển. Chúng cung cấp reg * constant + reg + constant. Có một bảng giải thích SIB là tốt. –

3

Không có "bổ sung đặc biệt nào có chuyển vị", trang đó đang gây nhầm lẫn không cần thiết - đây chỉ là một phần của mã hóa toán bộ nhớ thông thường.

add là một hướng dẫn khá chuẩn đó được mã hoá theo cùng một cách như tất cả các alu-ops là: có một trường hợp đặc biệt cho việc sử dụng al là điểm đến và ngay lập tức như một nguồn (04 ib), sử dụng ax/eax/rax là điểm đến và ngay lập tức dưới dạng nguồn (+ 05 imm), ba phiên bản add r/m, imm (một cho 8bit đích, một cho điểm đến rộng hơn và nguồn 8 bit có dấu mở rộng, một cho điểm đến rộng hơn và nguồn rộng), và dĩ nhiên là add r, r/madd r/m, r.

Đây chỉ là trường hợp đặc biệt của add r, r/m, trong đó r/m có dạng chuyển vị: xem chú thích số 1 của ModRM encoding.

Vì vậy, chúng chỉ có nghĩa là add edx, [sdword]. (nhưng họ đã mã hóa sai trường reg, edx tương ứng với 010, không 011)

+0

Vì vậy, để thêm nói AL (8 bit đăng ký 0) vào vị trí bộ nhớ 0x00000000, CPU sẽ chấp nhận (trong hex) 00 05 00000000? –

+0

@RyanBrown có, điều đó sẽ hoạt động – harold

4

Trang đó không chính xác. "Thêm rằng có một chuyển" mà nó nói về đề cập đến các hình thức add r[16|32], r/m[16|32] hoặc add edx, [0xdisp] như bạn có thể nhìn thấy nó trong một đầu ra của disassembler. Giả sử nó đang nói về hướng dẫn ADD với opcode 0x03,

  • Encoding điểm đến edx đăng ký và xác định trọng lượng rẽ 32-bit như địa chỉ hiệu quả trong byte ModR/M sẽ cung cấp cho nó giá trị của 0x15 (tham khảo Intel ® 64 và Hướng dẫn sử dụng phần mềm kiến ​​trúc sư IA-32 Tập 2, trang 41, bảng 2-2).
  • Hiệu ứng của hướng dẫn này là thêm từ dword tại địa chỉ bộ nhớ disp vào nội dung của edx.
  • Mã hóa thực tế của lệnh sẽ do đó: \x03\x15\x00\x00\x00\x01, để dịch chuyển 1 byte.
Các vấn đề liên quan