8 - Searching and Sorting Integer Arrays Flashcards
If you wanted to find the next random number in a range specified, how would you do so?
Order of parameters pushed:
- lowest acceptable value
- highest acceptable value
- address of return value
push esp mov ebp, esp mov eax, [esp+16] sub eax, [ebp+12] call RandomRange add eax, [ebp+12] mov [ebp+8], eax pop esp ret 12
What is the assembly code for bubble sort?
BubbleSort PROC USES eax ecx esi,
pArray:PTR DWORD,
Count:DWORD
mov ecx, Count dec ecx L1: push ecx ;save outer loop mov esi, pArray L2: mov eax[esi] cmp [esi+4], eax jg L3 xchg eax, [esi+4] L3: add esi, 4 loop L2 pop ecx ;retrieve outer loop loop L1 L4:ret
BubbleSort ENDP
What does the OFFSET operator do?
It returns the distance in BYTES, of a label from the beginning of its enclosing statement. (The operating system adds the segment address from the segment register).
.data (starts at 4000h)
bVal BYTE ?
wVal WORD ?
.code
mov esi, OFFSET bval ;ESI = 4000h
mov esi, OFFSET wVal ; ESI = 4001h
What does the PTR operator do?
PTR overrides the default type of a label (variable), which provides the flexibility to access part of a variable.
.data
myDouble DWORD 12345678h
.code mov ax, myDouble ; error mov ax, WORD PTR myDouble; loads 5678h mov ax, WORD PTR [myDouble+2]; AL = 1234h mov al, BYTE PTR myDouble ;AL = 78h mov al, BYTE PTR [myDouble+1]; AL = 56h mov WORD PTR myDouble ;saves 1357h
How can the PTR operator be used to combine elements?
It will combine elements and move them into a larger operand. The IA-32 CPU will automatically reverse the bytes.
.data
myBytes BYTE 12h, 34h, 56h, 78h
.code mov ax, WORD PTR myBytes ;AX = 3412h mov ax, WORD PTR [myBytes+2] ; AX = 7856h mov eax, DWORD PTR myBytes ;EAX = 78563412h
How does the TYPE operator work?
The TYPE operator returns the size, in bytes, of a single element of a data declaration.
.data var1 BYTE ? var2 WORD ? var3 DWORD ? var4 QWORD ?
.code mov eax, TYPE var1 ;1 mov eax, TYPE var2 ;2 mov eax, TYPE var3 ;4 mov eax, TYPE var4 ; 8
What does the LENGTHOF operator do?
LENGTHOF counts the number of elements in a single data declaration. (The comments are the number of elements in that data declaration).
.data byte1 BYTE 10, 20, 30 ;3 list1 WORD 30 DUP(?) ;30 list2 DWORD 30 DUP (?) ;30 list3 DWORD 1, 2, 3, 4 ;4 digitStr BYTE "1234567",0 ;8
.code
mov ecx, LENGTHOF list1 ;30
What does the SIZEOF operator do?
It returns a value that is equivalent to multiplying LENGTHOF by TYPE (i.e. size in bytes).
.data byte1 BYTE 10, 20, 30 ;3 list1 WORD 30 DUP (?) ;60 list2 DWORD 30 DUP (?) ;120 list3 DWORD 1, 2, 3, 4 ;16 digitStr BYTE "1234567",0 ;8
.code
mov ecx, SIZEOF list1 ;ecx = 60
How do the SIZEOF and LENGTHOF oeprands deal with arrays declared across multiple lines?
They still include all lines belonging to the declaration (if each line except the last ends with a comma).
.data
list DWORD 10, 20,
30, 40,
50, 60
.code
mov eax, LENGTHOF list ;6
mov ebx, SIZEOF list ;24
How can you use TYPE to do index scaling?
You can scale an indirect or indexed operand to the offset of an array element. This is done by multiplying the index by the array’s TYPE:
.data
listB BYTE 1, 2, 3, 4, 5, 6, 7
listW WORD 8, 9, 10, 11, 12, 13
listD DWORD 14, 15, 16, 17, 18, 19, 20, 21
.code mov esi, 5 mov al, listB[esi * TYPE listB] ;al = 6 mov bx, listW [esi*TYPE listW] ;bx = 13 mov edx, listD[esi*TYPE listD] ;edx = 19
How can you declare a pointer variable that contains the offset of another variable?
The effect of the following is the same as “mov esi, OFFSET list”.
***Notice that you CANNOT dereference the pointer in one statement {[ptr]) because that’s a memory-to-memory operation!
.data
list DWORD 100 DUP(?)
ptr DWORD list
.code
mov esi, ptr
mov eax, [esi] ;EAX = @list
How would you calculate the sum of an array of 32-bit integers using register indexed addressing?
.data
intList DWORD 100h, 200h, 300h, 400h
ptrD DWORD initlist
.code mov esi, ptrD ;@ initList mov ecx, LENGTHOF intList ;loop counter mov eax, 0 L1: add eax, [esi] ;add an integer add esi, TYPE intList ;point to next integer loop L1
How would you calculate the sum of an array of 32-bit integers in indexed mode (multiples)?
.data
intList DWORD 100h, 200h, 300h, 400h
.code mov esi, 0 mov eax, 0 ;zero the accumulator L1: add eax, intList[esi*TYPE intList] inc esi loop L1
What are the five groups of string primitives?
- Move string data: MOVSB, MOVSW, MOVSD - these copy data from memory addressed by EDI.
- Compare strings: CMPSB, CMPSW, CMPSD - compare the contents of 2 memory locations addressed by EDI and ESI.
- Scan string - SCASB, SCASW, SCASD - compare the accumulator (AL, AX, or EAX) to the contents of memory addressed by ESI.
- Store string data: STOSB, STOSW, STOSD - store the accumulator contents into memory addressed by EDI.
- Load accumulator from string: LODSB, LODSW, LODSD - load memory addressed by ESI into the accumulator.
What is a repeat prefix and what does it do?
The instruction repeats, using ECS as a counter. It permits you to process an entire array using a single instruction.
REP - Repeat while ECX > 0
REPZ, REPE - Repeat while zero flag is set and ECX > 0
REPNZ, REPNE - Repeat while the zero flag is clear and ECX > 0.
How would you copy a 10-byte string from string1 to string2?
The repeat prefix first tests ECX>0 before executing MOVSB instruction. ESI and EDI are automatically incremented when MOVSB repeats (this behavior is controlled by the CPU’s direction flag)
cld ;clear direction flag
mov esi, OFFSET string1 ; ESI points to source
mov edi, OFFSET string 2 ; EDI points to target
mov ecx, 10 ; set counter to 10
rep movesb ;move 10 bytes
How does the direction flag work?
ALWAYS set the direction flag before using string primitive instructions!
CLD clears the direction flag (forward direction), increments ESI and EDI, goes from low to high addresses.
STD sets the direction flag (reverse direction), decrements ESI and EDI, going from high to low addresses.
How do MOVSB, MOVSW, and MOVSD work?
MOVSB, MOVSW, and MOVSD copy data from the memory location pointed to by ESI to the memory location pointed to by EDI. The two registers are either incremented or decremented automatically (based on the value of the direction flag).
MOVSB - 1
MOVSW -2
MOVSD - 4
How would you copy 20 DWORD integers from source to target?
.data
source DWORD 20 DUP (0FFFFFFFFh)
target DWORD 20 DUP(?)
.code
cld ; direction = forward
mov ecx, LENGTHOF source ;set REP counter
mov esi, OFFSET source ; ESI points to source
mov edi, OFFSET target ; EDI points to target
rep movsd ;copy doublewords
After the array is copied, ESI and EDI point one position (4 bytes) beyond the end of each array.
How do CMPSB, CMPSW, and CMPSD work?
Each compare a memory operand pointed to by ESI to a memory operand pointed to by EDI.
CMPSB - compare bytes
CMPSW - compare words
CMPSD - compare doublewords
You can use repeat prefixes, and the direction flag will determine whether ESI increments or decrements.
How would you using CMPSD to jmp to L1 if source has a larger value than target?
.data
source DWORD 1234h
target DWORD 5678h
.code mov esi, OFFSET source mov edi, OFFSET target cmpsd ;compare doublewords ja L1 ;jmp if source > target
How would you compare multiple DWORDS?
The REPE prefix repeats the comparing (incrementing ESI and EDI until ECX equals zero or a pair of doublewords are different).
.data
source DWORD 1234h
target DWORD 5678h
.code mov esi, OFFSET source mov edi, OFFSET target cld mov ecx, LENGTHOF source ; repetition counter repe cmpsd ; repeat while equal
How to the SCASB, SCASW, and SCASD work?
SCASB, SCASW, and SCAWD compare a value in AL/AX/EAX to a byte, word, or doubleword addressed by EDI.
You can use these to search for a value in a string or array. Combined with REPE/REPZ, it’s scanned while ECX>0 and the value in AL/AX/EAX matches each subsequent value in memory.
Combined with REPNE, it scans until either AL/AX/EAX match a value in memory or ECX = 0.