为啥我的选择排序代码不起作用?
Posted
技术标签:
【中文标题】为啥我的选择排序代码不起作用?【英文标题】:Why isn't my selection sort code working?为什么我的选择排序代码不起作用? 【发布时间】:2013-05-16 17:58:47 【问题描述】:我正在学习汇编。我需要使用选择排序来对整数列表进行排序。我在交换函数上花了几个小时,但我无法弄清楚为什么我的程序在以下步骤停止编译:mov [eax]、edx & mov [ebx]、ecx。问题在于排序功能和交换功能。有人可以看看并给我一些指导。非常感谢!
(更新:我的代码现在可以编译 - 问题已解决)
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
【问题讨论】:
它是停止编译,还是在该行运行时崩溃? @MichaelDorgan 它给了我一条错误消息:Project.exe 已停止工作。一个问题导致程序停止正常工作。 【参考方案1】:为什么需要交换功能?
IMO 这也应该进行交换:
push [edi+ebx*4]
push [edi+eax*4]
pop [edi+ebx*4]
pop [edi+eax*4]
这不会解决您的段错误,但会降低复杂性。
你是从 C 函数中调用它吗?如果是,那么这就是错误。我删除了它,它对我有用。
ret 8
应该是:
ret
编译器在 C 调用中清理堆栈,所以你也不应该这样做。 :)
【讨论】:
欢迎您。是一个很好的练习,因为我多年来没有做太多的组装。 :) 我还有一个问题。不知道能不能解释清楚。当我打印排序列表时,一切看起来都很好,直到我要求我的程序打印 110 个排序整数。我开始收到一些看起来像地址的奇怪数字(例如,543516754 等)。当我打印 200 个排序列表时,我得到的只是一堆“笑脸”符号。无论如何,你能想到会导致这种情况的任何事情吗?我正在使用 Microsoft Visual Studio。 将其作为第二个问题发布,您将获得更多关注。以上是关于为啥我的选择排序代码不起作用?的主要内容,如果未能解决你的问题,请参考以下文章