Sorting Arrays and Processing their Sizes and Addresses as Stack Arguments

Sorting arrays in x86 assembly assignment help

INCLUDE Irvine32.inc .DATA header1 BYTE "Data for Array1 ", 0dh, 0ah, 0 header2 BYTE "Data for Array2", 0dh, 0ah, 0 msg1 BYTE "----------------", 0dh, 0ah, "Initial array:", 0dh, 0ah, 0 msg2 BYTE "Sorted array:", 0dh, 0ah, 0 msg3 BYTE "Number of comparisons: ", 0 msg4 BYTE 0dh, 0ah, "Number of swaps: ", 0 separator BYTE ", ",0 array1 DWORD 20 DUP(0) ; array of pointers to strings array2 DWORD 20 DUP(0) buffer BYTE 300 DUP(0) ; place to save generated strings bufpos DWORD 0 ; current free position in buffer min DWORD 0 ; stats data swaps DWORD 0 comps DWORD 0 .CODE main PROC call Randomize ; initialize random generator ; Fill first arrray mov eax, 20 ; pass size of array to fill push eax mov eax, OFFSET array1 ; pass array to fill push eax call FillRandomArray ; fill the array with random strings add esp, 8 ; remove arguments from stack mov edx, OFFSET header1 ; load header string address call WriteString ; print on screen mov edx, OFFSET msg1 ; load initial array message address call WriteString ; print on screen ; Print first arrray mov eax, 20 ; pass size of array to print push eax mov eax, OFFSET array1 ; pass array to print push eax call PrintArray ; print the array add esp, 8 ; remove arguments from stack mov eax, 20 ; pass size of array to sort push eax mov eax, OFFSET array1 ; pass array to sort push eax call PairBubbleSort ; sort using pair bubble sort add esp, 8 ; remove arguments from stack mov edx, OFFSET msg2 ; load sorted array message address call WriteString ; print on screen ; Print sorted first array mov eax, 20 ; pass size of array to print push eax mov eax, OFFSET array1 ; pass array to print push eax call PrintArray ; print the array add esp, 8 ; remove arguments from stack ; Print statistics for first array mov edx, OFFSET msg3 ; load comparison stats string address call WriteString ; print on screen mov eax, [comps] ; load comparisons call WriteDec ; print on screen mov edx, OFFSET msg4 ; load swap stats string address call WriteString ; print on screen mov eax, [swaps] ; load swaps call WriteDec ; print on screen call CrLF call CrLF ; Fill second arrray mov eax, 20 ; pass size of array to fill push eax mov eax, OFFSET array2 ; pass array to fill push eax call FillRandomArray ; fill the array with random strings add esp, 8 ; remove arguments from stack mov edx, OFFSET header2 ; load header string address call WriteString ; print on screen mov edx, OFFSET msg1 ; load initial array message address call WriteString ; print on screen ; Print second arrray mov eax, 20 ; pass size of array to print push eax mov eax, OFFSET array2 ; pass array to print push eax call PrintArray ; print the array add esp, 8 ; remove arguments from stack mov eax, 20 ; pass size of array to sort push eax mov eax, OFFSET array2 ; pass array to sort push eax call ListBubbleSort ; sort using list bubble sort add esp, 8 ; remove arguments from stack mov edx, OFFSET msg2 ; load sorted array message address call WriteString ; print on screen ; Print sorted second array mov eax, 20 ; pass size of array to print push eax mov eax, OFFSET array2 ; pass array to print push eax call PrintArray ; print the array add esp, 8 ; remove arguments from stack ; Print statistics for second array mov edx, OFFSET msg3 ; load comparison stats string address call WriteString ; print on screen mov eax, [comps] ; load comparisons call WriteDec ; print on screen mov edx, OFFSET msg4 ; load swap stats string address call WriteString ; print on screen mov eax, [swaps] ; load swaps call WriteDec ; print on screen call CrLF exit ; exit the program main ENDP ; Fill an array with random strings ; Prototype: FillRandomArray(array, n) FillRandomArray PROC push ebp ; save frame pointer mov ebp, esp ; create new stack frame push ecx ; save used registers push esi mov esi, [ebp + 8] ; load array pointer mov ecx, [ebp + 12] ; load array size fill_loop: call GenerateRandomStr ; generate a random string mov [esi], eax ; save pointer in array add esi, 4 ; advance to next position loop fill_loop ; repeat for all entries pop esi ; restore used registers pop ecx pop ebp ; restore frame pointer ret FillRandomArray ENDP ; Generates a random string of length 2 to 7 ; Prototype: char *GenerateRandomStr() ; uses the global buffer and bufpos GenerateRandomStr PROC push ecx ; save used registers push esi push edi mov eax, 6 ; generate number between 0 and 5 for length call RandomRange add eax, 2 ; add 2 to get range 2 to 7 mov edi, OFFSET buffer ; point to start of buffer add edi, [bufpos] ; advance to current position in array mov esi, edi ; save start position in esi mov ecx, eax ; copy to loop counter gen_loop: mov eax, 62 ; generate number between 0 and 61 for character call RandomRange cmp eax, 26 ; if number is between 0 and 26 jl saveLo ; save lowercase cmp eax, 52 ; if number is between 26 and 52 jl saveHi ; save uppercase saveDigit: sub eax, 52 ; subtract 52 to get value 0-9 add eax, 48 ; convert to ascii jmp save saveLo: add eax, 'a' ; convert number to lowercase letter jmp save saveHi: sub eax, 26 ; subtract 26 to get value 0-25 add eax, 'A' ; convert number to lowercase letter jmp save save: mov [edi], al ; save char in string inc edi ; advance to next position in buffer inc [bufpos] ; increment global buffer position loop gen_loop ; loop for the length of the string mov BYTE PTR [edi], 0 ; save end of string inc [bufpos] ; increment global buffer position mov eax, esi ; return the initial pointer pop edi ; restore used registers pop esi pop ecx ret GenerateRandomStr ENDP ; Sorts an array using pairwise bubble sort ; Prototype: PairBubbleSort(array, n) PairBubbleSort PROC push ebp ; save frame pointer mov ebp, esp ; create new stack frame push ebx ; save used registers push ecx push edx push esi mov DWORD PTR [swaps], 0 ; reset swap count mov DWORD PTR [comps], 0 ; reset comparison count mov esi, [ebp + 8] ; load array pointer mov ecx, [ebp + 12] ; load array size n in j index dec ecx ; use j = n - 1 for_j: mov edx, 0 ; load 0 in i index for_i: cmp edx, ecx ; compare i with j jge end_for_i ; if i >= j, end loop inc DWORD PTR [comps] ; increment comparisons mov eax, [esi + edx*4 + 4] ; load array[i + 1] push eax ; pass as second argument mov eax, [esi + edx*4] ; load array[i] push eax ; pass as first argument call Str_compare ; compare strings jle for_i_next ; if array[i] <= array[i + 1], skip inc DWORD PTR [swaps] ; increment swaps ; swap values array[i] and array[i + 1] mov eax, [esi + edx*4 + 4] ; load array[i + 1] mov ebx, [esi + edx*4] ; load array[i] mov [esi + edx*4 + 4], ebx ; save swapped array[i + 1] mov [esi + edx*4], eax ; save swapped array[i] for_i_next: inc edx ; i++ jmp for_i end_for_i: loop for_j ; j--, repeat while j>0 pop esi ; restore used registers pop edx pop ecx pop ebx pop ebp ; restore frame pointer ret PairBubbleSort ENDP ; Sorts an array using listwise bubble sort ; Prototype: ListBubbleSort(array, n) ListBubbleSort PROC push ebp ; save frame pointer mov ebp, esp ; create new stack frame push ebx ; save used registers push ecx push edx push esi mov DWORD PTR [swaps], 0 ; reset swap count mov DWORD PTR [comps], 0 ; reset comparison count mov esi, [ebp + 8] ; load array pointer mov ecx, [ebp + 12] ; load array size n dec ecx ; use n - 1 mov edi, 0 ; load 0 in index i fori: cmp edi, ecx ; compare i with j jge end_fori ; if i >= n-1, end loop mov [min], edi ; min = i mov edx, edi ; j = i+1 inc edx forj: cmp edx, ecx ; compare j with n-1 jg end_forj ; if j > n-1, end loop inc DWORD PTR [comps] ; increment comparisons mov eax, [min] mov eax, [esi + eax*4] ; load array[min] push eax ; pass as second argument mov eax, [esi + edx*4] ; load array[j] push eax ; pass as first argument call Str_compare ; compare strings jge forj_next ; if array[j] >= array[min], skip mov [min], edx ; min = j forj_next: inc edx ; j++ jmp forj end_forj: inc DWORD PTR [swaps] ; increment swaps ; swap values array[min] and array[i] mov edx, [min] mov eax, [esi + edx*4] ; load array[min] mov ebx, [esi + edi*4] ; load array[i] mov [esi + edx*4], ebx ; save swapped array[min] mov [esi + edi*4], eax ; save swapped array[i] inc edi ; i++ jmp fori end_fori: pop esi ; restore used registers pop edx pop ecx pop ebx pop ebp ; restore frame pointer ret ListBubbleSort ENDP ; Prints an array on the screen ; Prototype: PrintArray(array, n) PrintArray PROC push ebp ; save frame pointer mov ebp, esp ; create new stack frame push ecx ; save used registers push esi mov esi, [ebp + 8] ; load array pointer mov ecx, [ebp + 12] ; load array size print_loop: mov edx, [esi] ; load string pointer from array call WriteString ; generate a random string cmp ecx, 1 ; if this is the last entry je print_skip ; don't print separator mov edx, OFFSET separator ; load address of separator string call WriteString ; print separator on screen print_skip: add esi, 4 ; advance to next position loop print_loop ; repeat for all entries call CrLF ; jump to next line call CrLF ; jump to next line pop esi ; restore used registers pop ecx pop ebp ; restore frame pointer ret PrintArray ENDP END main