String instructions

Intermediate

The string instructions each do one step of a common job on a byte (the B forms) or a word (the W forms), and move SI and DI on by themselves:

InstructionDoes one step ofUses
MOVSBcopying: byte at DS:SI → ES:DISI, DI
LODSBreading: AL = byte at DS:SISI
STOSBfilling: byte at ES:DI = ALDI
CMPSBcomparing: byte at DS:SI with byte at ES:DISI, DI, the flags
SCASBsearching: AL with byte at ES:DIDI, the flags

After each step, SI and DI go up by 1 (2 for words) when the direction flag DF is 0 (set it with CLD), or down when DF is 1 (STD).

Repeating them

A prefix repeats the instruction, counting with CX:

PrefixRepeats while
REPCX is not 0 (with MOVSB, STOSB, LODSB)
REPECX is not 0 and the bytes are equal, ZF = 1 (with CMPSB, SCASB)
REPNECX is not 0 and they differ, ZF = 0 (with CMPSB, SCASB)

ES must point at the data too

The destination is ES:DI, the extra segment. In these programs the data segment is used for both, so set ES as well as DS:

    MOV AX, @DATA
    MOV DS, AX
    MOV ES, AX
; Copy a string with REP MOVSB, then print the copy.
.MODEL SMALL
.STACK 100H
.DATA
    SRC  DB 'Assembly$'
    LEN  EQU $ - SRC       ; 9, the $ included
    DEST DB LEN DUP(?)
.CODE
MAIN PROC
    MOV AX, @DATA
    MOV DS, AX
    MOV ES, AX             ; the destination is ES:DI
    CLD                    ; forwards
    LEA SI, SRC
    LEA DI, DEST
    MOV CX, LEN
    REP MOVSB              ; copy CX bytes
    LEA DX, DEST
    MOV AH, 9
    INT 21H
    MOV AH, 4CH
    INT 21H
MAIN ENDP
END MAIN
Open in compiler

REP MOVSB copies the whole string in one line; the visualizer shows each repetition as a step, with CX counting down.

Searching

REPNE SCASB scans until it finds AL (or CX runs out). Afterwards ZF = 1 means it was found, and DI is one past the match:

; Find the first 'm' in a string with REPNE SCASB and print its position.
.MODEL SMALL
.STACK 100H
.DATA
    TEXT DB 'assembly'
    LEN  EQU $ - TEXT
.CODE
MAIN PROC
    MOV AX, @DATA
    MOV DS, AX
    MOV ES, AX
    CLD
    LEA DI, TEXT
    MOV CX, LEN
    MOV AL, 'm'
    REPNE SCASB            ; compare AL with each byte until it matches
    JNE NOTFOUND           ; ZF = 0: it ran out of bytes
    LEA AX, TEXT
    SUB DI, AX             ; DI - start = one past the match
    MOV DX, DI             ; the position, counting from 1
    ADD DL, '0'
    MOV AH, 2
    INT 21H
    JMP DONE
NOTFOUND:
    MOV DL, '-'
    MOV AH, 2
    INT 21H
DONE:
    MOV AH, 4CH
    INT 21H
MAIN ENDP
END MAIN
Open in compiler

Common mistakes

  • Forgetting MOV ES, AX: MOVSB, STOSB, SCASB and CMPSB use ES:DI. StepVioz stops and says so.
  • Forgetting to set CX before REP.
  • Leaving DF set by an earlier STD, so the instructions run backwards. Use CLD.
  • Reading DI after a search as the match itself: it is one past it.

Quick check

1. Where does MOVSB copy a byte to?
2. CX = 5, DF = 0. After REP STOSB, what is CX?
3. What does CLD do?
4. After REPNE SCASB finds AL, where does DI point?
My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.