[asm]lab8

Post on 23-Jan-2018

363 Views

Category:

Education

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Assembly Language (Lab 8)String Primitives Instructions

AgendaMOVSx

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 cldinstruction

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 ArrayUse string primitive instructions to copy items from

double word array to another, then display the output

.datasource dword 10,20,30,40,50target dword 5 dup(?).codemain proc

cld ;clear direction flag. Move forwardmov ecx, lengthof sourcemov esi, offset sourcemov edi, offset targetrep movsd; display the target arraymov edx, OFFSET targetmov ecx, lengthof targetL1:

MOV eax, [edx]CALL WriteIntCALL CRLFADD edx, TYPE target

LOOP L1exitmain endpend main

CMPSx (Compare)

CMPSB / CMPSW / CMPSDThese 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

.DATASOURCE DWORD 1234hTARGET DWORD 5678h

.CODEMOV ESI, OFFSET SOURCEMOV EDI, OFFSET TARGETCMPSD ;like cmp [EDI], [ESI] JA l1JMP l2

[Solved Example] CMP 2 StringsCompare two strings assuming that both strings have the

same size.

.datasource byte 'ameen'target byte 'ayman'

strSmall byte "source is smaller",0strGreat byte "source is greater",0strEqual byte "both strings are equal",0

.codemain proc

cld ;clear the direction flagmov esi, offset sourcemov edi, offset targetmov ecx, lengthof source

repe cmpsb ;compare the 2 arrays and stop at the first mismatch

jb source_smaller ;check last char in source and lastja source_greater ;char in dest

mov edx, offset strEqualjmp done

source_smaller:mov edx, offset strSmalljmp done

source_greater:mov edx, offset strGreat

done:call writestringcall Crlf

exitmain endpend 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

.datasource byte 'ameen'target byte 'ayman'

strSmall byte "source is smaller",0strGreat byte "source is greater",0strEqual byte "both strings are equal",0

.codemain proc

cld ;clear the direction flagmov esi, offset sourcemov edi, offset targetmov ecx, lengthof sourcemov eax, lengthof target ;EAX = length of target string

.if ecx > eaxmov ecx, eax

.endifrepe cmpsb ;compare the 2 arrays and stop at the first mismatchjb source_smaller ;check last char in source and last char in destja 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 strEqualjmp done

.endifsource_smaller:

mov edx, offset strSmalljmp done

source_greater:mov edx, offset strGreat

done:call writestringcall Crlf

exitmain endp

SCASB / SCASW / SCASD InstructionsCompare 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…

.datastr1 byte "hello world",0

.codemain proc

cldmov edi, offset str1mov ecx, lengthof str1mov al, 'w'repne scasb ;scan string till 'w' is foundjne 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 - 1mov eax, lengthof str1 - 1sub eax, ecxjmp donenot_found:

mov eax, -1done: ;eax has the index of the char OR -1 if not found

call writeintexitmain endp

STOSx (Store)

STOSB / STOSW / STOSD InstructionsThese 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 ArrayUses 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

.dataarr1 word 20 dup (?)

.codemain proc

cldmov edi, offset arr1mov ecx, lengthof arr1mov ax, 5 ;save number you want to initialize with in the AXrep stosw ;set all items in arr1 by AX value

;display the array elementsmov ecx , lengthof arr1mov esi, offset arr1L1:

movzx eax, WORD PTR[esi]call writeIntCall CRLF

LOOP L1exitmain endpend 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

.dataarr1 dword 1, 2, 3, 4, 5multiplier dword 10

.codemain proc

cldmov esi, offset arr1 ;initialize ESI for LODSD instructionmov edi, esi ;initialize EDI for STOSD instructionmov ecx, lengthof arr1l1:

lodsd ;mov eax, [esi]mul multiplier ;edx:eax = eax * multiplierstosd ;mov [edi], eax

loop l1

;display array elements…mov ecx, lengthof arr1mov esi, offset arr1L2:

mov eax, [esi] ;Or use LODSB instruction…call writeIntcall crlfadd esi, type arr1

Loop L2

exitmain endpend main

2D Arrays!

Two Dimensional ArraysMulti-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 ArrGiven 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, 4dword 5, 6, 7, 8dword 9, 10, 11, 12

;the same as: table1 dword 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12ncol dword 4

.codeSum2DArr proto table: PTR DWORD, nrow:DWORD, ncol:DWORDmain proc

invoke Sum2DArr, offset table1, 3, 4call writeintcall CrLfexitmain endp

Sum2DArr proc USES esi ecx ebx edx, table: PTR DWORD, nrows:DWORD, ncols:DWORD

mov esi, table ;ESI = start of 1st rowmov ecx, nrows ;ECX: # of rows

; will be used as a row indexmov edx, ncolsshl edx, 2 ;EDX: # of bytes in each row (ncols*4)

mov ebx, 0 ;col indexmov eax, 0 ;EAX: accumulator for the result

l1:.while ebx < ncols

add eax, [esi+4*ebx]inc ebx

.endwmov ebx,0 ;Reset col. Index for each rowadd esi, edx ;ESI: points to the next row

loop l1ret

Sum2DArr endp

[Hands On] Sum i Col. In 2D ArrCalculate the sum of a given column in a 2D array

USING PROC

Given in .datatable1 dword 1, 2, 3, 4

dword 5, 6, 7, 8dword 9, 10, 11, 12

Col to be summed = 3Sum = 24

include irvine32.inc.data

table1 dword 1, 2, 3, 4dword 5, 6, 7, 8dword 9, 10, 11, 12

;the same as: table1 dword 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12ncol dword 4

.code

SumCol proto table: PTR DWORD, nrow:DWORD, ncol:DWORD, icol:DWORD

main proc

invoke SumCol, offset table1, 3, 4, 3call writeintcall CrLf

exitmain 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 regmov ecx, nrows ;ECX: # of rows

; will be used as a row indexmov edx, ncolsshl edx, 2 ;EDX: # of bytes in each row (ncols*4)

mov ebx, icol ;EBX: index of target columnmov eax, 0 ;EAX: accmulator for the result

l1:add eax, [esi+4*ebx]add esi, edx ;ESI: points to the next row

loop l1retSumCol endpend main

Assignment

You Must Use PROC in Your Solution…

asm_strCat1. 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_strFind2. 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_strRemove3. 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!

top related