为什么我的选择排序代码不起作用?

时间:2013-05-16 17:58:48

标签: sorting assembly x86 masm irvine32

我正在学习集会。我需要使用选择排序来对整数列表进行排序。我在交换功能上花了几个小时,但我无法弄清楚为什么我的程序在以下步骤中停止编译:mov [eax],edx& mov [ebx],ecx。问题出在sort函数和swap函数中。有人可以看看,给我一些指导。非常感谢!

(更新:我的代码现在编译 - 解决了问题)

    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

1 个答案:

答案 0 :(得分:2)

为什么你需要交换功能?

IMO这也应该进行交换:

    push [edi+ebx*4]
    push [edi+eax*4]
    pop [edi+ebx*4]
    pop [edi+eax*4]

这不会解决您的段错误,但会降低复杂性。

你是用C函数调用的吗?如果是,那么这就是错误。我删除了它,它对我有用。

ret 8

应该是:

ret

编译器正在清理C调用中的堆栈,因此您也不应该这样做。 :)