2014-05-16 15 views
8

Sự khác biệt giữa or eax,eaxtest eax,eax là gì? Tôi đã nhìn thấy trình biên dịch khác nhau sản xuất cả hai cho cùng một so sánh và như xa như tài liệu đi họ làm chính xác điều tương tự, vì vậy tôi tự hỏi tại sao họ không sử dụng tất cả test eax,eax. Suy nghĩ về nó and eax,eax sẽ thiết lập các lá cờ trong một thời trang giống hệt nhau hoặc là một trong hai nhưng tôi đã không nhìn thấy nó trong một trong hai freepascal, delphi, hoặc msVC++.Sự khác biệt giữa "hoặc eax, eax" và "kiểm tra eax, eax"

Tôi đã biên dịch một số khối asm trong delphi và kiểm tra nguồn lắp ráp và tất cả 3 biểu mẫu có độ dài chính xác như nhau trong mã opcodes và cũng đã kiểm tra hiệu suất intel PDF và nó cho biết chúng có cùng độ trễ và thông lượng.

Edit:
Câu hỏi đặt ra là đặc biệt về sự khác biệt giữa các trường hợp cụ thể test eax,eax, or eax,eaxand eax,eax. Tất cả 3 cung cấp kết quả hoàn toàn giống hệt nhau cho thanh ghi, cờ, độ dài opcode, độ trễ, thông lượng. Tuy nhiên, để thử nghiệm nếu 0, nếu không bằng 0, hoặc nếu đã ký, một số trình biên dịch sẽ sử dụng test eax,eax trong khi một số sử dụng or eax,eax và tôi đã tự hỏi tại sao chúng không phải là tất cả sử dụng test eax,eax vì nó làm cho mã rất rõ ràng hơn.

Edit2:
Để tham khảo tôi đang ở nhà và chỉ có và msvc cũ ++ và Delphi ở đây, nhưng thử nghiệm một biến nếu không, MSVC++ không test eax,eax, trong khi Delphi không or eax,eax.

+0

Dựa trên tên đăng ký, tôi đã đoán [tag: x86]. Nếu điều đó sai, vui lòng gắn thẻ lại câu hỏi của bạn với kiến ​​trúc bộ xử lý thích hợp. Có nhiều hơn một, và mỗi người có các ngôn ngữ lắp ráp khác nhau. –

+0

Bạn đã đúng với x86, điều xấu của tôi là không đặt nó ở đó. – Marladu

+0

Câu trả lời của tôi về bản sao liên kết có nhiều chi tiết hơn về lý do tại sao 'test' là tốt hơn, bao gồm một số lý do không được đề cập ở bất kỳ đâu. Lý do duy nhất những ngày này thậm chí còn xem xét 'hoặc giống nhau, cùng 'là đối với các CPU P6-gia đình khi viết lại một thanh ghi với chính nó giữ cho nó" sống "trong lõi ngoài trật tự, có thể tránh/giảm các quầy đọc khi các lệnh sau đọc cùng một thanh ghi. Tuy nhiên, sự kết hợp vĩ mô của kiểm tra/jcc thường lớn hơn điều đó, trừ khi thử nghiệm hiển thị một lợi ích điểm phát sóng cụ thể. Nhưng có lẽ đó, và không chỉ đơn giản là quán tính, là lý do tại sao Delphi sử dụng 'hoặc'. –

Trả lời

6

Nói chung, sự khác biệt duy nhất giữa testandtest <reg>, <reg> không sửa đổi các toán hạng của nó. Về cơ bản, test áp dụng thao tác and, loại bỏ phần không phải cờ của kết quả. Nếu toán hạng giống hệt nhau, kết quả sẽ giống nhau (như or).

test có thể là lựa chọn hướng dẫn cao cấp vì những thứ như hợp nhất vi mô. Kết quả là, test thường được ưu tiên trừ khi tính toán sẽ phải được lặp lại. Điều tương tự cũng xảy ra với cmp/sub.

Tìm kiếm tài liệu của Intel về "hợp nhất" và bạn nên tìm chi tiết.

+1

Tôi sẽ đặt thêm văn bản trong câu hỏi chính sau giây lát, nhưng câu hỏi đặt ra cho trường hợp cụ thể "kiểm tra eax, eax" "hoặc eax, eax" "và eax, eax", cho kết quả hoàn toàn giống hệt nhau cho thanh ghi, cờ và độ dài opcode. – Marladu

+1

'hoặc eax, eax' không sửa đổi' eax'. –

+0

Oh I _see_, bạn đang nói về trường hợp cụ thể khi các toán hạng giống nhau. Xin lỗi, tôi nên chọn nó. Tôi sẽ chỉnh sửa một chút. – gsg

2

Chỉ cần nhắc lại một chút, và thêm một chút vào, những gì @gsg chỉ ra, lệnh TEST thực hiện so sánh lô-gic logic (về cơ bản ANDing chúng bitwise nội bộ nhưng không lưu kết quả) của hai toán hạng và đặt cờ bộ xử lý theo kết quả của hoạt động đó. Lệnh OR thực hiện một OR hợp lý của nguồn với đích, lưu trữ kết quả trong đích và đặt cờ bộ vi xử lý theo kết quả. Cả hai đều ảnh hưởng đến cờ xử lý theo cùng một cách. Vì vậy, khi các toán hạng là giống hệt nhau, hành vi là như nhau. Không có sự khác biệt về cờ. Tuy nhiên, khi các toán hạng khác nhau, hành vi của chúng thì hoàn toàn khác. Bạn cũng có thể kiểm tra bằng không với and eax,eax cũng ảnh hưởng đến các cờ giống nhau.

+0

Bạn có thể nghĩ về giá trị của eax mà hướng dẫn cụ thể "kiểm tra eax, eax" "hoặc eax, eax" "và eax, eax" sẽ cung cấp cho một kết quả đăng ký hoặc cờ khác không? – Marladu

+0

@Marladu 'hoặc',' và' và 'test' ảnh hưởng đến cờ * giống hệt * (Tôi đã sửa câu trả lời của tôi) theo kết quả của thao tác. Vì vậy, khi các toán hạng giống hệt nhau (* ví dụ *, 'hoặc eax, eax',' kiểm tra eax, eax', 'và eax, eax') kết quả cờ giống nhau. Nếu toán hạng là khác nhau, sau đó 'test' và' và' sẽ cho kết quả cờ giống nhau vì cả hai đều thực hiện thao tác AND, nhưng 'test' sẽ không ảnh hưởng đến giá trị toán hạng. HOẶC có thể cho kết quả cờ khác nhau tùy thuộc vào các giá trị toán hạng khác nhau. – lurker

2

Mạch để xác định nội dung của eax sau test eax, eax giống như trước khi lệnh đơn giản hơn mạch cần thiết để đến kết luận đó cho or eax, eax. Vì lý do này, test là tốt hơn.

Một số trình biên dịch có thể đã tạo ra or tại một thời điểm khi nó không tạo ra bất kỳ sự khác biệt nào (trước khi thực hiện ngoài trật tự), nhưng nó sẽ tạo sự khác biệt với một số bộ vi xử lý lỗi thời. các bộ vi xử lý sẽ rất tinh vi đến nỗi chúng sẽ nhận ra or eax, eax là thực sự tương đương với test eax, eax).

tôi không thể tìm thấy một tài liệu tham khảo biện minh rằng một số bộ vi xử lý hiện đại đang thực sự có thể suy ra rằng or reg, reg không sửa đổi reg, nhưng here is một câu trả lời khẳng định nó là trường hợp cho xchg reg, reg.

+0

'0x90' (mã lệnh' xchg eax, reg' với reg = eax) là trường hợp đặc biệt: nó được nhận dạng là NOP thực, nhưng mã hóa 2 byte của cùng một lệnh bằng cách sử dụng opcode cho 'xchg r, r/m32', với MODRM mã hóa 'eax, eax' (hoặc bất kỳ khác, cùng) không phải là đặc biệt. Trong chế độ 32 bit '0x90' cũng là' xchg eax, eax', nhưng ở chế độ 64 bit 'xchg eax, eax' sẽ không mở rộng EAX thành RAX và' 0x90' không làm điều đó: [NOP có hướng dẫn tham khảo hướng dẫn sử dụng riêng của nó] (https://github.com/HJLebbink/asm-dude/wiki/NOP). Vì vậy, nếu bạn lắp ráp 'xchg eax, eax' ở chế độ x86-64, nó phải sử dụng mã hóa 2 byte. –

Các vấn đề liên quan