REPNE and REPNZ name the F2h prefix. In front of SCAS or CMPS it repeats while CX is not 0 and the compare finds the elements different. Each round: stop if CX = 0, compare once, step SI / DI, decrease CX, stop if ZF = 1. Its main use is REPNE SCASB: search ES:DI for the byte in AL.
| Ends because | ZF | Where |
|---|---|---|
| a match was found | 1 | DI is one past the match |
| CX ran out, no match | 0 | DI is past the searched block |
| CX was 0 at the start | unchanged | nothing searched |
Test ZF (JE found / JNE not found) and not CX: a match on the last element leaves CX = 0 as well. Going forward over bytes the match is at DI - 1, its 0-based index is DI - start - 1, and N - CX elements were looked at.
CLDMOV DI, OFFSET TXT1MOV CX, 8 ; length of the textMOV AL, 'w'REPNE SCASB ; stop at the first "w"JNE MISS1MOV AX, DISUB AX, OFFSET TXT1 + 1 ; 0-based index: 3ADD AL, '0' ; digit -> characterMOV DL, ALMOV AH, 02h ; DOS: print DLINT 21hJMP DONE1MISS1:MOV DL, '-'MOV AH, 02hINT 21hDONE1:TXT1 DB 'hi world'
With CX = 0FFFFh and AL = 0 the same search measures a 0-terminated string (see SCASB / SCASW). REPNE CMPSB finds the first position where two strings hold the same byte, which is less common.
Pitfalls: forgetting CLD, forgetting that the search is in ES (set it in an .EXE), and reading DI as the match itself instead of one past it. In front of MOVS, STOS or LODS use REP, not REPNE.