Why isn't my selection sort code working?
I'm learning assembly. I need to use selection sort to sort a list of integers. I spent hours on the swap function, but I can't figure out why my program stops compiling at the following steps: mov [eax], edx & mov [ebx], ecx. The problem is in the sort function and swap function. Can someone please take a look and give me some guidance. Thanks a lot!
(UPDATED: My code compiles now - Problem Solved)
INCLUDE Irvine32.inc
MIN_NUM = 10
MAX_NUM = 200
LOW_VAL = 100
HIGH_VAL = 999
.data
intro_1 BYTE "Sorting Random Integers", 0
intro_2 BYTE "This program generates random numbers in the range [100...999], ", 0
intro_3 BYTE "displays the original list, sorts the list, and calculate the ", 0
intro_4 BYTE "median value. Finally, it displays the list sorted in descending order.", 0
prompt_1 BYTE "How many numbers should be generated? [10 ... 200]: ", 0
error_msg BYTE "Invalid input", 0
request DWORD ?
sortArr DWORD MAX_NUM DUP(?)
cnt DWORD 0 ;count of elements in array
displayRes_1 BYTE "The unsorted random numbers:", 0
displayRes_2a BYTE "The median is ", 0
displayRes_2b BYTE ".", 0
displayRes_3 BYTE "The sorted list:",0
.code
main PROC
;introduce the program
call intro
;get data
push MIN_NUM
push MAX_NUM
push OFFSET error_msg
push OFFSET request
call getRequest
;generate random integers and put them into the array
push LOW_VAL
push HIGH_VAL
push OFFSET sortArr
push request
call fillArray
;display list
push cnt
push OFFSET sortArr
push request
push OFFSET displayRes_1
call displayList
;sort list - selection sort
push OFFSET sortArr
push request
call sortList_desc
;display median
;display list
push cnt
push OFFSET sortArr
push request
push OFFSET displayRes_3
call displayList
exit ; exit to operating system
main ENDP
; ***************************************************************
;Procedure to introduce the program.
;receives: none
;returns: none
;preconditions: none
;registers changed: edx
; ***************************************************************
intro PROC
;display introductions line 1
mov edx, OFFSET intro_1
call WriteString
call CrLf
;display introductions line 2
mov edx, OFFSET intro_2
call WriteString
call CrLf
;display introductions line 3
mov edx, OFFSET intro_3
call WriteString
call CrLf
;display introductions line 4
mov edx, OFFSET intro_4
call WriteString
call CrLf
call CrLf
ret
intro ENDP
; ***************************************************************
;Procedure to get a request from the user.
;Implementation note: This procedure accesses its parameters by setting up a
; "stack frame" and referencing parameters relative to the top of the
; system stack.
;receives: addresses of parameters on the system stack
;returns: user input values for the reference
;preconditions: none
;registers changed: eax, ebx, edx
; ***************************************************************
getRequest PROC
push ebp
mov ebp, esp
mov edx, OFFSET prompt_1
call WriteString ;prompt user
call ReadInt ;get user's request
call CrLf
call CrLf
cmp eax, [ebp+20] ;valid user input
jl input_notOK
cmp eax, [ebp+16] ;valid user input
jg input_notOK
mov ebx, [ebp+8] ;address of request in ebx
mov [ebx], eax ;store user input to the variable, request
jmp theEnd
input_notOK:
mov edx, [ebp+12] ;address of error_msg in edx
call WriteString
call CrLf
pop ebp
jmp getRequest
theEnd:
pop ebp
ret 16
getRequest ENDP
; ***************************************************************
; Procedure to put random integers into the array.
; receives: addresses of parameters on the system stack
; returns: an array of random integers
; preconditions: request is the user input we received earlier
; registers changed: eax, ecx, edi
; ***************************************************************
fillArray PROC
push ebp
mov ebp, esp
mov ecx, [ebp+8]
mov edi, [ebp+12]
call Randomize
;generate random integer for each element in the array
;adapted from Lecture 20 slides
randGen:
mov eax, [ebp+16] ;get HIGH_VAL
sub eax, [ebp+20] ;HIGH_VAL - LOW_VAL
inc eax
call RandomRange
add eax, [ebp+20]
mov [edi], eax
add edi, 4
loop randGen
endRandGen:
pop ebp
ret 16
fillArray ENDP
; ***************************************************************
; Procedure to sort the array
; receives: addresses of parameters on the system stack
; returns: an array of sorted integers
; preconditions: an array filled with random integers
; registers changed: eax, ecx, edi
; ***************************************************************
sortList_desc PROC
push ebp
mov ebp, esp
mov edi, [ebp+12] ;address of array in edi
mov ecx, [ebp+8] ;loop control in loop_1 ecx = request-1
dec ecx ;ecx-1 because single element is also maximum element
mov ebx, 0 ;"index" in ebx (index=k)
;for (int i=k, i<request-1;i++)
loop_1:
;find the index of the biggest element
;assume the first element is the biggest (i=k)
mov eax, ebx ;store biggest index in eax (eax=i=k)
;test against elements after finding the biggest
;for (j = k + 1; j < request; j++)
mov edx, eax
inc edx ;edx=j=k+1
push ecx ;save ecx register
mov ecx, [ebp+8] ;loop control in loop_2 ecx = request
loop_2:
mov esi, [edi+edx*4] ;store sortArr[j] in esi
cmp esi, [edi+eax*4] ;compare sortArr[j] and sortArr[k]
jle not_bigger
;if edx is bigger, it is the new max value
mov eax, edx ;found new biggest index, replace the old biggest index
not_bigger:
inc edx ;next element
loop loop_2
;eax is the maximum index(i), swap it with the current position (k)
;exchange (array[k], array[i])
push [edi+ebx*4]
push [edi+eax*4]
pop [edi+ebx*4]
pop [edi+eax*4]
pop ecx ;restore ecx register
inc ebx ;next iteration of loop_1
loop loop_1
pop ebp
ret 8
sortList_desc ENDP
Why do you need the swap function at all?
IMO this should also do the swap:
push [edi+ebx*4]
push [edi+eax*4]
pop [edi+ebx*4]
pop [edi+eax*4]
This will not solve your segfault, but it reduces the complexity.
Are you calling this from a C function? If yes, then this is the bug. I removed this and it works for me.
ret 8
should be:
ret
The compiler is cleaning up the stack in a C call, so you should not do this also. :)
链接地址: http://www.djcxy.com/p/72450.html上一篇: 在Assembly x86 NASM中从内存读取16位数据
下一篇: 为什么我的选择排序代码不工作?