Có thể là "dễ nhất" hoặc đơn giản nhất, "không quan tâm đến chi tiết" trả lời cách xác định là:
; here ebx is some value, flags are set to anything
test ebx,ebx ; CF=0, ZF=0/1 according to ebx
jz whereToJumpWhenZero
; "non-zero ebx" will go here
; Or you can use the inverted "jnz" jump to take
; a branch when value was not zero instead of "jz".
Có một lý do chi tiết về các cờ đang được đặt, v.v. :)
Làm thế nào để thiết lập một số đăng ký khác (Tôi sẽ chọn eax
) 1 khi ebx
là zero, và đến 0 khi ebx
là (cách không phá hoại cho ebx
chính nó) khác không:
xor eax,eax ; eax = 0 (upper 24 bits needed to complete "al" later)
test ebx,ebx ; test ebx, if it is zero (ZF=0/1)
setz al ; al = 1/0 when ZF=1/0 (eax = 1/0 too)
hoặc làm thế nào để chuyển đổi ebx
mình thành 1/0 khi ebx
là zero/non-zero:
neg ebx ; ZF=1/0 for zero/non-zero, CF=not(ZF)
sbb ebx,ebx ; ebx = 0/-1 for CF=0/1
inc ebx ; 1 when ebx was 0 at start, 0 otherwise
hoặc làm thế nào để chuyển đổi ebx
mình thành 1/0 khi 012.là zero/khác không, biến thể khác (nhanh hơn trên "P6" để lõi "Haswell"):
test ebx,ebx ; ZF=1/0 for zero/non-zero ebx
setz bl ; bl = 1/0 by ZF (SETcc can target only 8b r/m)
movzx ebx,bl ; ebx = bl extended to 32 bits by zeroes
vv, vv ... Nó phụ thuộc những gì xảy ra trước khi thử nghiệm của bạn, và cũng là những gì bạn thực sự muốn là đầu ra của thử nghiệm, có nhiều cách cách khác nhau (tối ưu cho các tình huống khác nhau và tối ưu cho các CPU mục tiêu khác nhau).
tôi sẽ thêm vài tình huống hơn rất phổ biến ... Một phản loop xuống đếm từ N đến zero, để lần N vòng:
mov ebx,5 ; loop 5 times
exampleLoop:
; ... doing something, preserving ebx
dec ebx
jnz exampleLoop ; loop 5 times till ebx is zero
Làm thế nào để xử lý 5 yếu tố của word
(16b) mảng (truy cập chúng trong mảng [0], mảng [1], ...thứ tự):
mov ebx,-5
lea esi,[array+5*2]
exampleLoop:
mov ax,[esi+ebx*2] ; load value from array[i]
; process it ... and preserve esi and ebx
inc ebx
jnz exampleLoop ; loop 5 times till ebx is zero
Một ví dụ nữa, tôi bằng cách nào đó như thế này rất nhiều:
Làm thế nào để thiết lập mục tiêu đăng ký (eax
trong ví dụ) để ~ 0 (-1)/0 khi ebx
là zero/khác không và bạn đã có giá trị 1
trong một số đăng ký (ecx
trong ví dụ):
; ecx = 1, ebx = some value
cmp ebx,ecx ; cmp ebx,1 => CF=1/0 for ebx zero/non-zero
sbb eax,eax ; eax = -1 (~0)/0 for CF=1/0 ; ebx/ecx intact
Các -1 có thể trông như thực tế là 1 (cho mục đích lập chỉ mục s ít nhất), nhưng -1 hoạt động cũng như bitmask đầy đủ cho hoạt động hơn nữa and/xor/or
, vì vậy đôi khi nó là thuận tiện hơn.
Bạn đang sử dụng ít nhất 80386 hướng dẫn ('ebx' không tồn tại trên 8086). Ngoài ra, câu trả lời phụ thuộc vào hướng dẫn trước mã này, sự hiện diện của giá trị bằng không có thể sắp xếp "rò rỉ" theo các hướng dẫn trước đó, tiết kiệm cho bạn nhiều hơn ở bài kiểm tra, nếu không thành ngữ thường là 'test ebx, ebx' để đặt ZF. Sau đó, để biến ZF thành giá trị 0/1 trong ebx là một câu chuyện khác, nơi 'test' đó có thể không phải là một phần của giải pháp tối ưu. Hãy quyết định, cho dù bạn muốn xác định nếu đăng ký là số không, hoặc nếu bạn muốn thiết lập một số đăng ký để 0/1 theo nó. # 'mov ebx, 0' =' xor ebx, ebx' khi bạn có thể tiêu diệt cờ. – Ped7g
Để minh họa quan điểm của tôi (tầm quan trọng của chi tiết), hãy nói lệnh sửa đổi cuối cùng (cờ và ebx) trước điều này là 'neg ebx'. Sau đó, 'sbb ebx, ebx' sẽ đặt' ebx' thành -1 khi 'ebx' bằng 0 và 0 cho giá trị khác 0 (tiếp theo là' neg ebx' sẽ biến nó thành 0/1 cách làm việc ban đầu của bạn). – Ped7g
không hoạt động với tôi. –