LOOPE subtracts 1 from CX, without changing the flags, and jumps if CX ≠ 0 and ZF = 1. ZF comes from the instruction before it, normally a CMP. So the loop continues while the items keep matching and stops at the first difference or when the count runs out. LOOPZ is the same instruction (opcode E1h).

Here it skips leading spaces. LODSB loads a byte and advances SI without touching the flags, so the CMP result reaches LOOPE intact:

Prints "Hi!".
CLD
MOV SI, OFFSET TEXT2
MOV CX, 6 ; the six characters before CR LF
SKIP2:
LODSB ; AL = [SI], SI + 1
CMP AL, " "
LOOPE SKIP2 ; on while it is a space
JE ALLSP1 ; ZF still 1: nothing but spaces
DEC SI ; back to the first non-space
MOV DX, SI
MOV AH, 09h ; print from there
INT 21h
ALLSP1:
TEXT2 DB " Hi!", 13, 10, "$"

Pitfalls

After the loop, ask ZF why it stopped, not CX: a difference found on the very last item also leaves CX = 0. As with LOOP, starting with CX = 0 means 65536 rounds, so guard with JCXZ; and the instruction is SHORT only. For plain memory comparisons REPE CMPSB does the same job in one instruction. In 32-bit code the 386 counts in ECX.