test
giống như and
, ngoại trừ nó chỉ viết CỜ, để lại cả hai yếu tố đầu vào chưa được sửa đổi. Với hai đầu vào khác nhau, nó rất hữu ích để kiểm tra xem một số bit có bằng không hoặc nếu ít nhất một giá trị được đặt. (ví dụ.test al, 3
đặt ZF nếu EAX là bội số của 4 (và do đó có cả 2 bit thấp của nó bằng 0).
test eax,eax
bộ tất cả các lá cờ chính xác cùng một cách mà cmp eax, 0
sẽ:
- CF và HÀNH xóa (AND/TEST luôn luôn làm điều đó, và trừ không bao giờ tạo ra một carry)
- ZF, SF và PF theo giá trị trong EAX. (
a = a&a = a-0
)
(Ngoại trừ các lỗi thời cờ AF (phụ-carry, được sử dụng bởi các hướng dẫn ASCII/BCD). TEST leaves it undefined, nhưng CMP sets it "according to the result". Kể từ khi trừ zero không thể tạo ra một carry từ 4 đến chút 5th, CMP nên luôn luôn rõ ràng AF).
KIỂM TRA nhỏ hơn (không có ngay) và đôi khi nhanh hơn (có thể kết hợp macro thành uop so sánh và chi nhánh trên nhiều CPU hơn trong nhiều trường hợp hơn CMP). That makes test
the preferred idiom for testing a register for zero or not.
Lý do phổ biến duy nhất để sử dụng CMP với 0 ngay lập tức là khi bạn muốn so sánh với toán hạng bộ nhớ (ví dụ: cmpb $0, (%esi)
để kiểm tra byte không kết thúc ở cuối chuỗi C-style dài) .
AVX512F thêm kortestw k1, k2
và AVX512DQ/BW (Skylake nhưng không KNL) thêm ktestb/w/d/q k1, k2
, mà hoạt động trên AVX512 thanh ghi mặt nạ (k0..k7) nhưng vẫn thiết FLAGS thường xuyên như test
không, giống như cách mà số nguyên OR
hoặc AND
hướng dẫn.
kortestw k1,k1
là cách thành ngữ này sang cành/cmovcc/setcc dựa trên một AVX512 so sánh kết quả, thay thế SSE/AVX2 (v)pmovmskb/ps/pd
+ test
hoặc cmp
.
Sử dụng jz
vs je
thể gây nhầm lẫn.
jz
and je
are literally the same instruction, tức là cùng một mã opcode trong mã máy. Họ làm điều tương tự, nhưng có ý nghĩa ngữ nghĩa khác nhau cho con người. Disassemblers (và đầu ra asm thường từ các trình biên dịch) sẽ chỉ bao giờ sử dụng một, do đó sự khác biệt ngữ nghĩa bị mất.
cmp
và sub
đặt ZF khi hai đầu vào của chúng bằng nhau (tức là kết quả trừ là 0). je
(nhảy nếu bằng nhau) là từ đồng nghĩa có liên quan về ngữ nghĩa.
test %eax,%eax
/and %eax,%eax
lại đặt ZF khi kết quả bằng 0, nhưng không có kiểm tra "bình đẳng". ZF sau khi kiểm tra không cho bạn biết liệu hai toán hạng có bằng nhau hay không. Vì vậy, jz
(nhảy nếu không) là từ đồng nghĩa ngữ nghĩa có liên quan.
Tôi đã chỉnh sửa để biến câu trả lời phổ biến này trở thành câu trả lời hợp lý hơn cho "điều TEST này là gì, và nó khác với CMP" như thế nào. Xem câu trả lời của riêng tôi tiếp tục cho ý kiến về ý nghĩa ngữ nghĩa của JE đồng nghĩa và JZ. Vui lòng xem lại chỉnh sửa của tôi vì nó khá lớn và đó vẫn là câu trả lời của bạn. –
@PeterCordes Tôi đánh giá cao ý định, nhưng tôi sẽ hoàn nguyên chỉnh sửa của bạn. 1. "Tiếng nói" của bạn rất khác so với tôi, và ngay bây giờ nó đọc rất giống câu trả lời của bạn hơn tôi. 2. Có nhiều vấn đề hơn là xác nhận táo bạo rằng các cờ xuất hiện chính xác theo cùng một cách giữa 'test' và' cmp'. Vâng, tôi hiểu đó là niềm tin của bạn dựa trên những bình luận của bạn với Cody. Tuy nhiên, đặt nó vào bài viết của tôi là một vấn đề khác; nó không phải là một khẳng định tôi sẵn sàng đứng, đơn giản chỉ vì _I không biết_ nếu nó giống hệt nhau trong mọi trường hợp. –
@PeterCordes Tôi hiểu mong muốn có một câu trả lời "kinh điển", nhưng tôi nghĩ câu trả lời của bạn phải bơi hoặc chìm trên những giá trị riêng của nó, chứ không phải là câu trả lời được chấp nhận. Tôi đã phải làm điều đó cho một số câu trả lời của tôi cho câu hỏi rất phổ biến quá, giống như [nổi mồi điểm một] (http://stackoverflow.com/a/27030789/13), mà tại thời điểm gửi bài của tôi câu trả lời đã có câu trả lời khác với 500+ upvotes. –