2012-10-25 9 views
76

thể trùng lặp:
x86 Assembly - ‘testl’ eax against eax?Điểm của bài kiểm tra% eax% eax

Tôi rất rất mới để lập trình ngôn ngữ lắp ráp, và tôi hiện đang cố gắng để đọc lắp ráp ngôn ngữ được tạo từ nhị phân. Tôi đã chạy qua số

test %eax,%eax 

hoặc test %rdi, %rdi, v.v ... Tôi rất bối rối về điều này. Giá trị trong %eax, %eax có giống nhau không? Nó là gì? Tôi đọc ở đâu đó rằng nó đang thực hiện các hoạt động AND ..... nhưng vì chúng có cùng giá trị, nó sẽ không trả về %eax?

Sau đây chỉ là một trường hợp mà tôi thấy việc sử dụng này:

400e6e:  85 c0     test %eax,%eax 
    400e70:  74 05     je  400e77 <phase_1+0x23> 

Tôi nghĩ je nhảy nếu hai giá trị được so sánh được bằng ...... tốt, vì %eax là tốt, chính nó, trong tình huống nào chúng ta KHÔNG nhảy?

Tôi là người mới bắt đầu lập trình nói chung, vì vậy tôi rất cảm kích nếu có ai đó có thể giải thích điều này với tôi. Cảm ơn!

+4

Vì một số câu trả lời có vẻ hơi không rõ ràng về nó, hãy để tôi chỉ ra rằng 'TEST' cập nhật các cờ khác ngoài' ZF'. Xem tham chiếu tập lệnh. – Jester

+0

@Jester cố định (trong câu trả lời của tôi), xin lỗi. –

+0

Một bản sao có thể khác: [Lệnh 'test' làm gì?] (Http://stackoverflow.com/q/6002079) – jww

Trả lời

95

CMP trừ các toán hạng và đặt cờ. Cụ thể, nó đặt cờ số không nếu chênh lệch bằng không (toán hạng bằng nhau).

TEST đặt cờ số 0, ZF, khi kết quả của thao tác AND bằng 0. Nếu hai toán hạng bằng nhau, bitwise AND của chúng bằng 0 khi cả hai đều bằng không. TEST cũng đặt cờ hiệu, SF, khi bit quan trọng nhất được đặt trong kết quả và cờ chẵn lẻ, PF, khi số bit thiết lập là chẵn.

JE [Jump if Equals] kiểm tra cờ 0 và nhảy nếu cờ được đặt. JE là bí danh của JZ [Nhảy nếu Zero] để trình tách rời không thể chọn một dựa trên mã opcode. JE được đặt tên như vậy vì cờ số không được đặt nếu đối số cho CMP bằng nhau.

Vì vậy,

TEST %eax, %eax 
JE 400e77 <phase_1+0x23> 

nhảy nếu %eax là zero.

+3

Tôi có thể tìm thông tin như thế này ở đâu? –

+5

cụ thể là? Danh sách các lệnh x86 [nằm trên Wikipedia] (http://en.wikipedia.org/wiki/X86_instruction_listings), cũng liên kết một [spec by Intel] (http://www.intel.com/content/www/ chúng tôi/vi/bộ xử lý/kiến ​​trúc-phần mềm-nhà phát triển-hướng dẫn sử dụng.html) cũng như [một tài liệu tham khảo khác (khá dễ đọc) về máy rút tiền] (http://web.archive.org/web/20100407092131/http://home .comcast.net/~ fbui/intel.html). [Hướng dẫn] (http://en.wikibooks.org/wiki/X86_Assembly) cũng có sẵn trên Wikibooks. –

+0

có, đây là thông tin tôi đang tìm kiếm –

9

Kiểm tra này nếu EAX bằng không. Hướng dẫn test thực hiện bitwise AND giữa các đối số và nếu EAX chứa 0, kết quả sẽ đặt ZF hoặc ZeroFlag.

+3

Đây là cách tiêu chuẩn để thực hiện. Người ta cũng có thể làm cmp% eax, 0 (tức thời) cho "rõ ràng cho người mới bắt đầu" nhưng điều đó sẽ mã hóa thành một lệnh dài hơn (còn ít hiệu quả hơn). –

2

Bạn nói đúng, rằng test "và" của hai toán hạng. Nhưng kết quả là bị loại bỏ, điều duy nhất ở lại, và đó là phần quan trọng, là những lá cờ. Chúng được thiết lập và đó là lý do tại sao lệnh test được sử dụng (và tồn tại).

JE nhảy không khi bình đẳng (nó có ý nghĩa khi lệnh trước là so sánh), nó thực sự làm gì, nó nhảy khi cờ ZF được đặt.Và vì nó là một trong những cờ được đặt bởi test, chuỗi lệnh này (kiểm tra x, x; je ...) có nghĩa là nó được nhảy khi x là 0.

Đối với các câu hỏi như thế này (và để biết thêm chi tiết) Tôi chỉ có thể giới thiệu một cuốn sách về hướng dẫn x86, ví dụ ngay cả khi nó thực sự lớn, tài liệu của Intel rất tốt và chính xác.

3

testand không phá hủy, nó không trả lại kết quả của thao tác nhưng nó đặt cờ đăng ký tương ứng. Để biết những gì nó thực sự kiểm tra cho bạn cần phải kiểm tra (các) hướng dẫn sau đây. Thường ra được sử dụng để kiểm tra một đăng ký chống lại 0, có thể kết hợp với một nhảy có điều kiện jz.

32

Một số lệnh x86 được thiết kế để rời khỏi nội dung của toán hạng (sổ đăng ký) như chúng và chỉ cần đặt/bỏ đặt cờ CPU nội bộ cụ thể như cờ zero (ZF). Bạn có thể nghĩ rằng ZF là một cờ boolean đúng/sai nằm bên trong CPU.

trong trường hợp cụ thể này, lệnh TEST thực hiện logic bit AND, hủy kết quả thực tế và đặt/hủy ZF theo kết quả của lôgic và: nếu kết quả bằng 0 thì ZF = 1, ngược lại đặt ZF = 0.

hướng dẫn nhảy có điều kiện như JE được thiết kế để nhìn vào ZF cho nhảy/notjumping nên sử dụng TEST và JE với nhau là tương đương để thực hiện một bước nhảy có điều kiện dựa trên giá trị của một thanh ghi cụ thể:

ví dụ:

TEST EAX, EAX
JE some_address

CPU sẽ nhảy đến "some_address" khi và chỉ khi ZF = 1, hay nói cách khác nếu và chỉ nếu AND (EAX, EAX) = 0 mà trong biến nó có thể xảy ra khi và chỉ khi EAX == 0

mã C tương đương là:

if(eax == 0) 
{ 
    goto some_address 
}