Skip to content

String Processing

string instructions can do block worth of processing and hence are also called block processing.
There are 5 processing blocks.
There is a prefix which does the operation over a chunk of data instead of single memory cell called REP.

The DI and SI are used in these instructions.
When we need a source, the DS:SI holds the memory address pointer to it.
When we need a destination, the ES:DI holds the memory address pointer to it.
These instructions can work from start of memory to the end or from end to the start.
This direction is controlled by Direction Flag.

If this flag is 0 then we are in auto increment mode and is done by cld statement (clear direction)
If this flag is 1 then we are in _auto decrement mode and is done by std statement (set direction)

STOS

Stands for store string.
It is used to either transfer a byte from AL or a word from AX to the ES:DI and increments DI by 1 if STOSB was used or 2 if STOSW was used.
If the Direction Flag is set, then it is decremented.

If REP is used, the instruction will be repeated CX times and it also decrements CX as well.

LODS

Stands for load string.
It stores the value from DS:SI into AL or AX and SI is incremented
The REP prefix is not used since the previous values of AX would be overwritten and hence, useless.

SCAS

Stands for scan string.
It compares the bytes or words in AL or AX registers with the value stored in ES:DI and updates the flags.
The prefixes REPE (repeat while equal) or REPNE (repeat while not equal) are used with it.

MOVS

Stands for move string.
This instruction transfer byte or word from DS:SI to ES:DI.

CMPS

Stands for compare string.
This subtracts DS:SI from ES:DI
It also uses REPE and REPNE and repeats until the blocks of memory are either keep being equal or not equal depending on which one was used.

REP Prefix

Repeats a string instruction CX times.

REPE and REPNE Prefixes

REPE repeats a string instruction if the zero flag is 1.
REPNE repeats a string instruction if the zero flag is 0.

STOS Example - Clearing the Screen

[org 0x0100]
jmp start

; subroutine to clear the screen
clrscr: 
    push es
    push ax
    push cx
    push di
    mov ax, 0xb800
    mov es, ax        ; point es to video base
    xor di, di        ; point di to top left column
    mov ax, 0x0720    ; space char in normal attribute
    mov cx, 2000      ; number of screen locations
    cld               ; auto increment mode
    rep stosw         ; clear the whole screen
    pop di
    pop cx
    pop ax
    pop es
    ret

start: 
    call clrscr       ; call clrscr subroutine
    mov ax, 0x4c00    ; terminate program
    int 0x21          ; interrupt to DOS

LODS Example - String Printing

[org 0x0100]
jmp start

message: 
    db 'hello world'  ; string to be printed
length: 
    dw 11             ; length of string

; subroutine to clear the screen
clrscr: 
    push es
    push ax
    push cx
    push di
    mov ax, 0xb800
    mov es, ax        ; point es to video base
    xor di, di        ; point di to top left column
    mov ax, 0x0720    ; space char in normal attribute
    mov cx, 2000      ; number of screen locations
    cld               ; auto increment mode
    rep stosw         ; clear the whole screen
    pop di
    pop cx
    pop ax
    pop es
    ret

; subroutine to print a string
; takes the x position, y position, attribute, address of string, and its length as parameters
printstr: 
    push bp
    mov bp, sp
    push es
    push ax
    push cx
    push si
    push di
    mov ax, 0xb800
    mov es, ax        ; point es to video base
    mov al, 80        ; load al with columns per row
    mul byte [bp+10]  ; multiply with y position
    add ax, [bp+12]   ; add x position
    shl ax, 1         ; turn into byte offset
    mov di, ax        ; point di to required location
    mov si, [bp+6]    ; point si to string
    mov cx, [bp+4]    ; load length of string in cx
    mov ah, [bp+8]    ; load attribute in ah
    cld               ; auto increment mode
nextchar: 
    lodsb             ; load next char in al
    stosw             ; print char/attribute pair
    loop nextchar     ; repeat for the whole string
    pop di
    pop si
    pop cx
    pop ax
    pop es
    pop bp
    ret 10

start: 
    call clrscr       ; call the clrscr subroutine
    mov ax, 30
    push ax           ; push x position
    mov ax, 20
    push ax           ; push y position
    mov ax, 1         ; blue on black attribute
    push ax           ; push attribute
    mov ax, message
    push ax           ; push address of message
    push word [length] ; push message length
    call printstr     ; call the printstr subroutine
    mov ax, 0x4c00    ; terminate program
    int 0x21          ; interrupt to DOS

SCAS Example - String Length

[org 0x0100]
jmp start

message: 
    db 'hello world', 0 ; null terminated string

; subroutine to clear the screen
clrscr: 
    push es
    push ax
    push cx
    push di
    mov ax, 0xb800
    mov es, ax        ; point es to video base
    xor di, di        ; point di to top left column
    mov ax, 0x0720    ; space char in normal attribute
    mov cx, 2000      ; number of screen locations
    cld               ; auto increment mode
    rep stosw         ; clear the whole screen
    pop di
    pop cx
    pop ax
    pop es
    ret

; subroutine to print a string
; takes the x position, y position, attribute, and address of a null
; terminated string as parameters
printstr: 
    push bp
    mov bp, sp
    push es
    push ax
    push cx
    push si
    push di
    push ds
    pop es            ; load ds in es
    mov di, [bp+4]    ; point di to string
    mov cx, 0xffff    ; load maximum number in cx
    xor al, al        ; load a zero in al
    repne scasb       ; find zero in the string
    mov ax, 0xffff    ; load maximum number in ax
    sub ax, cx        ; find change in cx
    dec ax            ; exclude null from length
    jz exit           ; no printing if string is empty
    mov cx, ax        ; load string length in cx
    mov ax, 0xb800
    mov es, ax        ; point es to video base
    mov al, 80        ; load al with columns per row
    mul byte [bp+8]   ; multiply with y position
    add ax, [bp+10]   ; add x position
    shl ax, 1         ; turn into byte offset
    mov di, ax        ; point di to required location
    mov si, [bp+4]    ; point si to string
    mov ah, [bp+6]    ; load attribute in ah
    cld               ; auto increment mode
nextchar: 
    lodsb             ; load next char in al
    stosw             ; print char/attribute pair
    loop nextchar     ; repeat for the whole string
exit: 
    pop di
    pop si
    pop cx
    pop ax
    pop es
    pop bp
    ret 8

start: 
    call clrscr       ; call the clrscr subroutine
    mov ax, 30
    push ax           ; push x position
    mov ax, 20
    push ax           ; push y position
    mov ax, 1         ; blue on black attribute
    push ax           ; push attribute
    mov ax, message
    push ax           ; push address of message
    call printstr     ; call the printstr subroutine
    mov ax, 0x4c00    ; terminate program
    int 0x21          ; interrupt to DOS

LES and LDS Instructions

LES loads ES register and LDS loads DS register into other registers from memory addresses.

ldi si, [bp + 4]

This snippet will load SI from [bp + 4] and DS from [bp + 6].
This is according to the fact that the segment value should be pushed on the stack first and offset value should be pushed on the stack later.

LES and LDS Example

[org 0x0100]
jmp start

message: 
    db 'hello world', 0 ; null terminated string

; subroutine to calculate the length of a string
; takes the segment and offset of a string as parameters
strlen: 
    push bp
    mov bp, sp
    push es
    push cx
    push di
    les di, [bp+4]    ; point es:di to string
    mov cx, 0xffff    ; load maximum number in cx
    xor al, al        ; load a zero in al
    repne scasb       ; find zero in the string
    mov ax, 0xffff    ; load maximum number in ax
    sub ax, cx        ; find change in cx
    dec ax            ; exclude null from length
    pop di
    pop cx
    pop es
    pop bp
    ret 4

; subroutine to print a string
; takes the x position, y position, attribute, and address of a null
; terminated string as parameters
printstr: 
    push bp
    mov bp, sp
    push es
    push ax
    push cx
    push si
    push di
    push ds           ; push segment of string
    mov ax, [bp+4]
    push ax           ; push offset of string
    call strlen       ; calculate string length 
    cmp ax, 0         ; is the string empty
    jz exit           ; no printing if string is empty
    mov cx, ax        ; save length in cx
    mov ax, 0xb800
    mov es, ax        ; point es to video base
    mov al, 80        ; load al with columns per row
    mul byte [bp+8]   ; multiply with y position
    add ax, [bp+10]   ; add x position
    shl ax, 1         ; turn into byte offset
    mov di, ax        ; point di to required location
    mov si, [bp+4]    ; point si to string
    mov ah, [bp+6]    ; load attribute in ah
    cld               ; auto increment mode
nextchar: 
    lodsb             ; load next char in al
    stosw             ; print char/attribute pair
    loop nextchar     ; repeat for the whole string
exit: 
    pop di
    pop si
    pop cx
    pop ax
    pop es
    pop bp
    ret 8

start: 
    call clrscr       ; call the clrscr subroutine
    mov ax, 30
    push ax           ; push x position
    mov ax, 20
    push ax           ; push y position
    mov ax, 0x71      ; blue on white attribute
    push ax           ; push attribute
    mov ax, message
    push ax           ; push address of message
    call printstr     ; call the printstr subroutine
    mov ax, 0x4c00    ; terminate program
    int 0x21          ; interrupt to DOS

MOVS Example - Screen Scrolling

[org 0x0100]
jmp start

; subroutine to scroll up the screen
; takes the number of lines to scroll as parameter
scrollup: 
    push bp
    mov bp, sp
    push ax
    push cx
    push si
    push di
    push es
    push ds

    mov ax, 80         ; load chars per row in ax
    mul byte [bp+4]    ; calculate source position
    mov si, ax         ; load source position in si
    push si            ; save position for later use
    shl si, 1          ; convert to byte offset
    mov cx, 2000       ; number of screen locations
    sub cx, ax         ; count of words to move
    mov ax, 0xb800
    mov es, ax         ; point es to video base
    mov ds, ax         ; point ds to video base
    xor di, di         ; point di to top left column
    cld                ; set auto increment mode
    rep movsw          ; scroll up
    mov ax, 0x0720     ; space in normal attribute
    pop cx             ; count of positions to clear
    rep stosw          ; clear the scrolled space

    pop ds
    pop es
    pop di
    pop si
    pop cx
    pop ax
    pop bp
    ret 2

start: 
    mov ax, 5
    push ax            ; push number of lines to scroll
    call scrollup      ; call the scroll up subroutine
    mov ax, 0x4c00     ; terminate program
    int 0x21           ; interrupt to DOS

CMPS Example - String Comparison

[org 0x0100]
jmp start

msg1: db 'hello world', 0
msg2: db 'hello WORLD', 0
msg3: db 'hello world', 0

; subroutine to compare two strings
; takes segment and offset pairs of two strings to compare
; returns 1 in ax if they match and 0 otherwise
strcmp: 
    push bp
    mov bp, sp
    push cx
    push si
    push di
    push es
    push ds

    lds si, [bp+4]    ; point ds:si to first string
    les di, [bp+8]    ; point es:di to second string

    push ds           ; push segment of first string
    push si           ; push offset of first string
    call strlen       ; calculate string length
    mov cx, ax        ; save length in cx

    push es           ; push segment of second string
    push di           ; push offset of second string
    call strlen       ; calculate string length
    cmp cx, ax        ; compare length of both strings
    jne exitfalse     ; return 0 if they are unequal

    mov ax, 1         ; store 1 in ax to be returned
    repe cmpsb       ; compare both strings
    jcxz exitsimple   ; are they successfully compared

exitfalse: 
    mov ax, 0         ; store 0 to mark unequal

exitsimple: 
    pop ds
    pop es
    pop di
    pop si
    pop cx
    pop bp
    ret 8

start: 
    push ds           ; push segment of first string
    mov ax, msg1
    push ax           ; push offset of first string
    push ds           ; push segment of second string
    mov ax, msg2
    push ax           ; push offset of second string
    call strcmp       ; call strcmp subroutine

    push ds           ; push segment of first string
    mov ax, msg1
    push ax           ; push offset of first string
    push ds           ; push segment of third string
    mov ax, msg3
    push ax           ; push offset of third string
    call strcmp       ; call strcmp subroutine

    mov ax, 0x4c00    ; terminate program
    int 0x21          ; interrupt to DOS

Exercises