Assembly Language (Lab 8)
String Primitives Instructions
Agenda
MOVSx
CMPSx
SCANSx
STOSx
LODSx
2D Arrays
Assignment
Replace x with B,
W and D
B = Byte
W = Word
D = Dword
Introduction
String Primitives
These instructions use memory operands pointed by the
ESI register or EDI register or both.
Used register(s) is automatically incremented or
decremented after instruction execution based on the
Direction flag (a bit in the EFLAGS register).
If the direction flag is cleared (DF = 0), registers are incremented.
Otherwise (DF = 1), they are decremented.
Direction flag can be set by std instruction, and cleared by cld
instruction
String Primitives
They often used with repeat prefix which allows them to
be automatically repeated using ECX as a counter. So, you
can process an entire array or string using only single
instruction.
The following repeat prefixes are used:
REP inst_Name
String Primitives
When repeat prefix is used, the sequence of its operation
is as follows:
1. Test repeat condition(s) [ECX > 0 and zero flag status
with REPE and REPNE]
2. If test success, perform the instruction (in addition to
incrementing or decrementing ESI or EDI or both).
Otherwise, skip the entire instruction.
MOVSx (Move)
MOVSB / MOVSW / MOVSD Instructions
These instructions copy data pointed by ESI to the
memory location pointed by EDI. They are used with
repeat prefixes to copy arrays and strings.
It’s Like:
T
H
E
T
H
E
ESIEDI
ESI
ESI
EDI
EDI
MOV [EDI], [ESI]
[Hands On] Copy an Array
Use string primitive instructions to copy items from
double word array to another, then display the output
.data
source dword 10,20,30,40,50
target dword 5 dup(?)
.code
main proc
cld ;clear direction flag. Move forward
mov ecx, lengthof source
mov esi, offset source
mov edi, offset target
rep movsd
; display the target array
mov edx, OFFSET target
mov ecx, lengthof target
L1:
MOV eax, [edx]
CALL WriteInt
CALL CRLF
ADD edx, TYPE target
LOOP L1
exit
main endp
end main
CMPSx (Compare)
CMPSB / CMPSW / CMPSD
These instructions compare a memory operand pointed
by ESI (source) with the memory operand pointed by EDI
(destination).
They actually subtract target from source and set flags
according to the result like CMP instruction.
It’s Like:
CMP [EDI], [ESI]
Example
.DATA
SOURCE DWORD 1234h
TARGET DWORD 5678h
.CODE
MOV ESI, OFFSET SOURCE
MOV EDI, OFFSET TARGET
CMPSD ;like cmp [EDI], [ESI]
JA l1
JMP l2
[Solved Example] CMP 2 Strings
Compare two strings assuming that both strings have the
same size.
.data
source byte 'ameen'
target byte 'ayman'
strSmall byte "source is smaller",0
strGreat byte "source is greater",0
strEqual byte "both strings are equal",0
.code
main proc
cld ;clear the direction flag
mov esi, offset source
mov edi, offset target
mov ecx, lengthof source
repe cmpsb ;compare the 2 arrays and stop at the first
mismatch
jb source_smaller ;check last char in source and last
ja source_greater ;char in dest
mov edx, offset strEqual
jmp done
source_smaller:
mov edx, offset strSmall
jmp done
source_greater:
mov edx, offset strGreat
done:
call writestring
call Crlf
exit
main endp
end main
[Hands On] CMP 2 Strs with Diff Len
Implement the same previous example but assume the
strings have different length
Key Idea:
1.Loop for the length of the minimum
2.Handle case JB and JA like pervious
3.In case of having the same chars check the length of
each
.data
source byte 'ameen'
target byte 'ayman'
strSmall byte "source is smaller",0
strGreat byte "source is greater",0
strEqual byte "both strings are equal",0
.code
main proc
cld ;clear the direction flag
mov esi, offset source
mov edi, offset target
mov ecx, lengthof source
mov eax, lengthof target ;EAX = length of target string
.if ecx > eax
mov ecx, eax
.endif
repe cmpsb ;compare the 2 arrays and stop at the first mismatch
jb source_smaller ;check last char in source and last char in dest
ja source_greater
.if eax < lengthof source ;if both chars are equal then
jmp source_greater ;check the length of each one
.elseif eax > lengthof source
jmp source_smaller
.else
mov edx, offset strEqual
jmp done
.endif
source_smaller:
mov edx, offset strSmall
jmp done
source_greater:
mov edx, offset strGreat
done:
call writestring
call Crlf
exit
main endp
SCASB / SCASW / SCASD Instructions
Compare a value in AL/AX/EAX to a byte, word, or double
word addressed by EDI respectively.
They are useful when looking for a single value in an array or
a string.
1. Start = EDI
2. Inversed Index = ECX
3. What to search for = AL/AX/EAX
4. Return the index if exists in ECX register
 It counts from the end of the array
20
[Hands On] Find ‘W’
Write an assembly program the search for letter ‘w’ in a
given string
It’s a sequential search…
.data
str1 byte "hello world",0
.code
main proc
cld
mov edi, offset str1
mov ecx, lengthof str1
mov al, 'w'
repne scasb ;scan string till 'w' is found
jne not_found ;'w' is not found, jump to not_found label
;Otherwise, ecx has the index of that character but
reversed
;So, make eax = lengthof(str1) - ecx - 1
mov eax, lengthof str1 - 1
sub eax, ecx
jmp done
not_found:
mov eax, -1
done: ;eax has the index of the char OR -1 if not found
call writeint
exit
main endp
STOSx (Store)
STOSB / STOSW / STOSD Instructions
These instructions store the content of AL/AX/EAX into
memory at the offset pointed to by EDI.
They are useful for filling all elements of a string or array
with a single value.
It’s Like
MOV BYTE PTR [EDI], AL
MOV WORD PTR [EDI], AX
MOV DWORD PTR [EDI], EAX
[Solved Example] Fill an Array
Uses string primitive instructions to initialize an array by a
specific value.
It reminds me with DUP API ;)
Use an already defined word array with length 20
Init. it with 5
.data
arr1 word 20 dup (?)
.code
main proc
cld
mov edi, offset arr1
mov ecx, lengthof arr1
mov ax, 5 ;save number you want to initialize with in
the AX
rep stosw ;set all items in arr1 by AX value
;display the array elements
mov ecx , lengthof arr1
mov esi, offset arr1
L1:
movzx eax, WORD PTR[esi]
call writeInt
Call CRLF
LOOP L1
exit
main endp
end main
LODSx (Load)
The inverse of STOSx
LODSB / LODSW / LODSD Instructions
These instructions load a byte, word, or double word
from memory at ESI into AL/AX/EAX respectively.
REP prefix is rarely used with them as each new value
loaded into accumulator overwrites its previous
contents.
MOV AL, BYTE PTR [ESI]
MOV AX, WORD PTR [ESI]
MOV EAX, DWORD PTR [ESI]
[Hands On] Array Multiplier
Write an assembly program the multiply a Dword array with
10
Example
You have a fixed array 1, 2, 3, 4, 5
Print 10, 20, 30, 40, 50
Key Idea
1. Load array element by element
2. Multiply loaded element by 10
3. Store element
.data
arr1 dword 1, 2, 3, 4, 5
multiplier dword 10
.code
main proc
cld
mov esi, offset arr1 ;initialize ESI for LODSD
instruction
mov edi, esi ;initialize EDI for STOSD instruction
mov ecx, lengthof arr1
l1:
lodsd ;mov eax, [esi]
mul multiplier ;edx:eax = eax * multiplier
stosd ;mov [edi], eax
loop l1
;display array elements…
mov ecx, lengthof arr1
mov esi, offset arr1
L2:
mov eax, [esi] ;Or use LODSB instruction…
call writeInt
call crlf
add esi, type arr1
Loop L2
exit
main endp
end main
2D Arrays!
Two Dimensional Arrays
Multi-dimensional arrays in assembly are defined as
single dimensional arrays… WHY??
For example, a 2D array can be defined as 1D array where
rows are concatenated in a single row.
Accessing items in 2D arrays can be done by indirect
memory addressing mode using a base register and an
index register like [ebx+esi].
In such addressing mode, a base register (i.e. ebx) should contain
the row offset while an index register (i.e. esi) should contain the
column offset.
[Solved Example] Sum 2D Arr
Given 2D array
Calculate it’s sum in the EAX
Then display it
Questions?
1. 2D Array how to declare?
2. How to parse/navigate from row to row?  key idea
include irvine32.inc
.data
table1 dword 1, 2, 3, 4
dword 5, 6, 7, 8
dword 9, 10, 11, 12
;the same as: table1 dword 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12
ncol dword 4
.code
Sum2DArr proto table: PTR DWORD, nrow:DWORD, ncol:DWORD
main proc
invoke Sum2DArr, offset table1, 3, 4
call writeint
call CrLf
exit
main endp
Sum2DArr proc USES esi ecx ebx edx,
table: PTR DWORD, nrows:DWORD, ncols:DWORD
mov esi, table ;ESI = start of 1st row
mov ecx, nrows ;ECX: # of rows
; will be used as a row index
mov edx, ncols
shl edx, 2 ;EDX: # of bytes in each row (ncols*4)
mov ebx, 0 ;col index
mov eax, 0 ;EAX: accumulator for the result
l1:
.while ebx < ncols
add eax, [esi+4*ebx]
inc ebx
.endw
mov ebx,0 ;Reset col. Index for each row
add esi, edx ;ESI: points to the next row
loop l1
ret
Sum2DArr endp
[Hands On] Sum i Col. In 2D Arr
Calculate the sum of a given column in a 2D array
USING PROC 
Given in .data
table1 dword 1, 2, 3, 4
dword 5, 6, 7, 8
dword 9, 10, 11, 12
Col to be summed = 3
Sum = 24
include irvine32.inc
.data
table1 dword 1, 2, 3, 4
dword 5, 6, 7, 8
dword 9, 10, 11, 12
;the same as: table1 dword 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12
ncol dword 4
.code
SumCol proto table: PTR DWORD, nrow:DWORD, ncol:DWORD,
icol:DWORD
main proc
invoke SumCol, offset table1, 3, 4, 3
call writeint
call CrLf
exit
main endp
SumCol proc USES esi ecx ebx edx,
table: PTR DWORD, nrows:DWORD, ncols:DWORD, icol:DWORD
mov esi, table ;ESI: points to the beginning of array
(1st row) base reg
mov ecx, nrows ;ECX: # of rows
; will be used as a row index
mov edx, ncols
shl edx, 2 ;EDX: # of bytes in each row (ncols*4)
mov ebx, icol ;EBX: index of target column
mov eax, 0 ;EAX: accmulator for the result
l1:
add eax, [esi+4*ebx]
add esi, edx ;ESI: points to the next row
loop l1
ret
SumCol endp
end main
Assignment
You Must Use PROC in Your Solution…
asm_strCat
1. Write a procedure named asm_strCat that
concatenates a source string to the end of a target string.
Use string primitive instructions when is possible.
asm_strFind
2. Write a procedure named asm_strFind that searches
for a string inside a target string and returns the first
matching position if any. Use string primitive instructions
when is possible.
asm_strRemove
3. Write a procedure named asm_strRemove that
removes n characters from a string. This procedure
should take a pointer to a string, the position in the string
where the character are to be removed and number of
characters to be removed n. Use string primitive
instructions when is possible.
Questions?!
Thanks!

[ASM]Lab8

  • 1.
    Assembly Language (Lab8) String Primitives Instructions
  • 2.
  • 3.
  • 4.
    String Primitives These instructionsuse memory operands pointed by the ESI register or EDI register or both. Used register(s) is automatically incremented or decremented after instruction execution based on the Direction flag (a bit in the EFLAGS register). If the direction flag is cleared (DF = 0), registers are incremented. Otherwise (DF = 1), they are decremented. Direction flag can be set by std instruction, and cleared by cld instruction
  • 5.
    String Primitives They oftenused with repeat prefix which allows them to be automatically repeated using ECX as a counter. So, you can process an entire array or string using only single instruction. The following repeat prefixes are used: REP inst_Name
  • 6.
    String Primitives When repeatprefix is used, the sequence of its operation is as follows: 1. Test repeat condition(s) [ECX > 0 and zero flag status with REPE and REPNE] 2. If test success, perform the instruction (in addition to incrementing or decrementing ESI or EDI or both). Otherwise, skip the entire instruction.
  • 7.
  • 8.
    MOVSB / MOVSW/ MOVSD Instructions These instructions copy data pointed by ESI to the memory location pointed by EDI. They are used with repeat prefixes to copy arrays and strings. It’s Like: T H E T H E ESIEDI ESI ESI EDI EDI MOV [EDI], [ESI]
  • 9.
    [Hands On] Copyan Array Use string primitive instructions to copy items from double word array to another, then display the output
  • 10.
    .data source dword 10,20,30,40,50 targetdword 5 dup(?) .code main proc cld ;clear direction flag. Move forward mov ecx, lengthof source mov esi, offset source mov edi, offset target rep movsd ; display the target array mov edx, OFFSET target mov ecx, lengthof target L1: MOV eax, [edx] CALL WriteInt CALL CRLF ADD edx, TYPE target LOOP L1 exit main endp end main
  • 11.
  • 12.
    CMPSB / CMPSW/ CMPSD These instructions compare a memory operand pointed by ESI (source) with the memory operand pointed by EDI (destination). They actually subtract target from source and set flags according to the result like CMP instruction. It’s Like: CMP [EDI], [ESI]
  • 13.
    Example .DATA SOURCE DWORD 1234h TARGETDWORD 5678h .CODE MOV ESI, OFFSET SOURCE MOV EDI, OFFSET TARGET CMPSD ;like cmp [EDI], [ESI] JA l1 JMP l2
  • 14.
    [Solved Example] CMP2 Strings Compare two strings assuming that both strings have the same size.
  • 15.
    .data source byte 'ameen' targetbyte 'ayman' strSmall byte "source is smaller",0 strGreat byte "source is greater",0 strEqual byte "both strings are equal",0 .code main proc cld ;clear the direction flag mov esi, offset source mov edi, offset target mov ecx, lengthof source repe cmpsb ;compare the 2 arrays and stop at the first mismatch jb source_smaller ;check last char in source and last ja source_greater ;char in dest mov edx, offset strEqual jmp done
  • 16.
    source_smaller: mov edx, offsetstrSmall jmp done source_greater: mov edx, offset strGreat done: call writestring call Crlf exit main endp end main
  • 17.
    [Hands On] CMP2 Strs with Diff Len Implement the same previous example but assume the strings have different length Key Idea: 1.Loop for the length of the minimum 2.Handle case JB and JA like pervious 3.In case of having the same chars check the length of each
  • 18.
    .data source byte 'ameen' targetbyte 'ayman' strSmall byte "source is smaller",0 strGreat byte "source is greater",0 strEqual byte "both strings are equal",0 .code main proc cld ;clear the direction flag mov esi, offset source mov edi, offset target mov ecx, lengthof source mov eax, lengthof target ;EAX = length of target string
  • 19.
    .if ecx >eax mov ecx, eax .endif repe cmpsb ;compare the 2 arrays and stop at the first mismatch jb source_smaller ;check last char in source and last char in dest ja source_greater .if eax < lengthof source ;if both chars are equal then jmp source_greater ;check the length of each one .elseif eax > lengthof source jmp source_smaller .else mov edx, offset strEqual jmp done .endif source_smaller: mov edx, offset strSmall jmp done source_greater: mov edx, offset strGreat done: call writestring call Crlf exit main endp
  • 20.
    SCASB / SCASW/ SCASD Instructions Compare a value in AL/AX/EAX to a byte, word, or double word addressed by EDI respectively. They are useful when looking for a single value in an array or a string. 1. Start = EDI 2. Inversed Index = ECX 3. What to search for = AL/AX/EAX 4. Return the index if exists in ECX register  It counts from the end of the array 20
  • 21.
    [Hands On] Find‘W’ Write an assembly program the search for letter ‘w’ in a given string It’s a sequential search…
  • 22.
    .data str1 byte "helloworld",0 .code main proc cld mov edi, offset str1 mov ecx, lengthof str1 mov al, 'w' repne scasb ;scan string till 'w' is found jne not_found ;'w' is not found, jump to not_found label ;Otherwise, ecx has the index of that character but reversed ;So, make eax = lengthof(str1) - ecx - 1 mov eax, lengthof str1 - 1 sub eax, ecx jmp done not_found: mov eax, -1 done: ;eax has the index of the char OR -1 if not found call writeint exit main endp
  • 23.
  • 24.
    STOSB / STOSW/ STOSD Instructions These instructions store the content of AL/AX/EAX into memory at the offset pointed to by EDI. They are useful for filling all elements of a string or array with a single value. It’s Like MOV BYTE PTR [EDI], AL MOV WORD PTR [EDI], AX MOV DWORD PTR [EDI], EAX
  • 25.
    [Solved Example] Fillan Array Uses string primitive instructions to initialize an array by a specific value. It reminds me with DUP API ;) Use an already defined word array with length 20 Init. it with 5
  • 26.
    .data arr1 word 20dup (?) .code main proc cld mov edi, offset arr1 mov ecx, lengthof arr1 mov ax, 5 ;save number you want to initialize with in the AX rep stosw ;set all items in arr1 by AX value ;display the array elements mov ecx , lengthof arr1 mov esi, offset arr1 L1: movzx eax, WORD PTR[esi] call writeInt Call CRLF LOOP L1 exit main endp end main
  • 27.
  • 28.
    LODSB / LODSW/ LODSD Instructions These instructions load a byte, word, or double word from memory at ESI into AL/AX/EAX respectively. REP prefix is rarely used with them as each new value loaded into accumulator overwrites its previous contents. MOV AL, BYTE PTR [ESI] MOV AX, WORD PTR [ESI] MOV EAX, DWORD PTR [ESI]
  • 29.
    [Hands On] ArrayMultiplier Write an assembly program the multiply a Dword array with 10 Example You have a fixed array 1, 2, 3, 4, 5 Print 10, 20, 30, 40, 50 Key Idea 1. Load array element by element 2. Multiply loaded element by 10 3. Store element
  • 30.
    .data arr1 dword 1,2, 3, 4, 5 multiplier dword 10 .code main proc cld mov esi, offset arr1 ;initialize ESI for LODSD instruction mov edi, esi ;initialize EDI for STOSD instruction mov ecx, lengthof arr1 l1: lodsd ;mov eax, [esi] mul multiplier ;edx:eax = eax * multiplier stosd ;mov [edi], eax loop l1
  • 31.
    ;display array elements… movecx, lengthof arr1 mov esi, offset arr1 L2: mov eax, [esi] ;Or use LODSB instruction… call writeInt call crlf add esi, type arr1 Loop L2 exit main endp end main
  • 32.
  • 33.
    Two Dimensional Arrays Multi-dimensionalarrays in assembly are defined as single dimensional arrays… WHY?? For example, a 2D array can be defined as 1D array where rows are concatenated in a single row. Accessing items in 2D arrays can be done by indirect memory addressing mode using a base register and an index register like [ebx+esi]. In such addressing mode, a base register (i.e. ebx) should contain the row offset while an index register (i.e. esi) should contain the column offset.
  • 34.
    [Solved Example] Sum2D Arr Given 2D array Calculate it’s sum in the EAX Then display it Questions? 1. 2D Array how to declare? 2. How to parse/navigate from row to row?  key idea
  • 35.
    include irvine32.inc .data table1 dword1, 2, 3, 4 dword 5, 6, 7, 8 dword 9, 10, 11, 12 ;the same as: table1 dword 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ncol dword 4 .code Sum2DArr proto table: PTR DWORD, nrow:DWORD, ncol:DWORD main proc invoke Sum2DArr, offset table1, 3, 4 call writeint call CrLf exit main endp
  • 36.
    Sum2DArr proc USESesi ecx ebx edx, table: PTR DWORD, nrows:DWORD, ncols:DWORD mov esi, table ;ESI = start of 1st row mov ecx, nrows ;ECX: # of rows ; will be used as a row index mov edx, ncols shl edx, 2 ;EDX: # of bytes in each row (ncols*4) mov ebx, 0 ;col index mov eax, 0 ;EAX: accumulator for the result l1: .while ebx < ncols add eax, [esi+4*ebx] inc ebx .endw mov ebx,0 ;Reset col. Index for each row add esi, edx ;ESI: points to the next row loop l1 ret Sum2DArr endp
  • 37.
    [Hands On] Sumi Col. In 2D Arr Calculate the sum of a given column in a 2D array USING PROC  Given in .data table1 dword 1, 2, 3, 4 dword 5, 6, 7, 8 dword 9, 10, 11, 12 Col to be summed = 3 Sum = 24
  • 38.
    include irvine32.inc .data table1 dword1, 2, 3, 4 dword 5, 6, 7, 8 dword 9, 10, 11, 12 ;the same as: table1 dword 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ncol dword 4 .code SumCol proto table: PTR DWORD, nrow:DWORD, ncol:DWORD, icol:DWORD main proc invoke SumCol, offset table1, 3, 4, 3 call writeint call CrLf exit main endp
  • 39.
    SumCol proc USESesi ecx ebx edx, table: PTR DWORD, nrows:DWORD, ncols:DWORD, icol:DWORD mov esi, table ;ESI: points to the beginning of array (1st row) base reg mov ecx, nrows ;ECX: # of rows ; will be used as a row index mov edx, ncols shl edx, 2 ;EDX: # of bytes in each row (ncols*4) mov ebx, icol ;EBX: index of target column mov eax, 0 ;EAX: accmulator for the result l1: add eax, [esi+4*ebx] add esi, edx ;ESI: points to the next row loop l1 ret SumCol endp end main
  • 40.
    Assignment You Must UsePROC in Your Solution…
  • 41.
    asm_strCat 1. Write aprocedure named asm_strCat that concatenates a source string to the end of a target string. Use string primitive instructions when is possible.
  • 42.
    asm_strFind 2. Write aprocedure named asm_strFind that searches for a string inside a target string and returns the first matching position if any. Use string primitive instructions when is possible.
  • 43.
    asm_strRemove 3. Write aprocedure named asm_strRemove that removes n characters from a string. This procedure should take a pointer to a string, the position in the string where the character are to be removed and number of characters to be removed n. Use string primitive instructions when is possible.
  • 44.
  • 45.

Editor's Notes

  • #10 From register 32 bit to string 32 byte
  • #34 Why? Because we are dealing with a block of some bytes Ok, but how can I differentiate the rows and the cols? It’s your indexing problem 