2012-06-24 23 views
68

Từ x86-64 Tour of Intel Manuals, tôi đọcTại sao lệnh x86-64 trên thanh ghi 32 bit không phải phần trên của thanh ghi 64 bit đầy đủ?

lẽ một thực tế đáng ngạc nhiên nhất là một lệnh như MOV EAX, EBX tự động zero trên 32 bit của RAX đăng ký.

Các tài liệu Intel (3.4.1.1 chung-Purpose Thanh ghi ở chế độ 64-Bit trong sổ tay cơ bản Kiến trúc) niêm yết ở cùng một nguồn cho chúng ta biết:

  • 64-bit toán hạng tạo ra một 64 -bit kết quả trong thanh ghi đích đích chung.
  • Toán hạng 32 bit tạo ra kết quả 32 bit, không được mở rộng đến kết quả 64 bit trong thanh ghi đích đích chung.
  • Toán hạng 8 bit và 16 bit tạo ra kết quả 8 bit hoặc 16 bit. 56 bit trên hoặc 48 bit (tương ứng) của thanh ghi đích đích không được sửa đổi bởi thao tác. Nếu kết quả của thao tác 8 bit hoặc 16 bit được dùng để tính toán địa chỉ 64 bit, hãy mở rộng đăng ký một cách rõ ràng đến 64 bit đầy đủ.

Trong x86-32 và lắp ráp x86-64, 16 hướng dẫn chút như

mov ax, bx 

không hiển thị loại hành vi "kỳ lạ" rằng từ trên của eax được zeroed.

Do đó: lý do khiến hành vi này được giới thiệu là gì? Ngay từ cái nhìn đầu tiên, nó có vẻ phi lý (nhưng lý do có thể là tôi quen với những điều kỳ quặc của x86-32 assembly).

+11

Nếu bạn sử dụng Google cho "Quầy đăng ký một phần", bạn sẽ tìm thấy khá nhiều thông tin về sự cố mà họ (hầu như chắc chắn) đang cố tránh. –

+3

http://stackoverflow.com/questions/25455447/x86-64-registers-rax-eax-ax-al-overwriting-full-register-contents –

+1

Không chỉ "hầu hết".Các lệnh AFAIK, * all * có toán hạng đích 'r32' bằng 0, cao hơn là hợp nhất. Ví dụ, một số assembly sẽ thay thế 'pmovmskb r64, xmm' bằng' pmovmskb r32, xmm', lưu một REX, vì phiên bản đích 64bit hoạt động giống nhau. Mặc dù [Phần hoạt động của sách hướng dẫn] (http://www.felixcloutier.com/x86/PMOVMSKB.html) liệt kê tất cả 6 kết hợp của nguồn 32/64bit đích và 64/128/256b riêng biệt, phần mở rộng bằng 0 của mẫu r32 sao chép phần mở rộng không rõ ràng của dạng r64. Tôi tò mò về việc thực hiện HW ... –

Trả lời

55

Tôi không phải là AMD hay nói cho họ, nhưng tôi cũng đã làm theo cách tương tự. Bởi vì zeroing nửa cao không tạo ra một sự phụ thuộc vào giá trị trước đó, rằng cpu sẽ phải chờ đợi. Cơ chế đổi tên đăng ký về cơ bản sẽ bị đánh bại nếu nó không được thực hiện theo cách đó. Bằng cách này, bạn có thể viết mã 32 bit nhanh ở chế độ 64bit mà không phải ngắt các phụ thuộc một cách rõ ràng mọi lúc. Nếu không có hành vi này, mọi lệnh 32bit đơn trong chế độ 64bit sẽ phải chờ đợi điều gì đó đã xảy ra trước đó, mặc dù phần cao đó hầu như không bao giờ được sử dụng.

Hành vi đối với hướng dẫn 16 bit là hướng dẫn lạ. Sự điên rồ phụ thuộc là một trong những lý do mà các hướng dẫn 16bit được tránh ngay bây giờ.

+7

Tôi không nghĩ rằng nó lạ, tôi nghĩ rằng họ không muốn phá vỡ quá nhiều và giữ các hành vi cũ ở đó. –

+3

@Alex khi họ giới thiệu chế độ 32 bit, không có hành vi cũ cho phần cao. Không có phần nào cao trước đó .. Tất nhiên sau đó nó không thể thay đổi được nữa. – harold

+1

Tôi đã nói về các toán hạng 16 bit, tại sao các bit trên không được lấy 0 trong trường hợp đó. Chúng không ở chế độ không 64 bit. Và điều đó cũng được giữ ở chế độ 64 bit. –

6

Nó chỉ đơn giản là tiết kiệm không gian trong hướng dẫn và tập lệnh. Bạn có thể chuyển các giá trị ngay lập tức nhỏ sang thanh ghi 64 bit bằng cách sử dụng các lệnh hiện có (32 bit).

Nó cũng giúp bạn không phải mã hóa 8 giá trị byte cho MOV RAX, 42, khi MOV EAX, 42 có thể được sử dụng lại.

Tối ưu hóa này không quan trọng đối với các op 8 và 16 bit (vì chúng nhỏ hơn) và việc thay đổi quy tắc cũng sẽ phá vỡ mã cũ.

+4

Nếu đó là chính xác, nó sẽ không có ý nghĩa hơn cho nó để đăng ký mở rộng chứ không phải là 0 mở rộng? –

+0

@Damien_The_Unbeliever Có thể. Nhưng zero-extension là cực kỳ rẻ. –

+2

@Alex: Và tiện ích mở rộng đăng nhập không phải là? Cả hai có thể được thực hiện rất rẻ trong phần cứng. – jalf