Search code examples
assemblymasm

MASM Sorting Array spits out junk with arrays larger than 100


I'm working on a program that fills an array with random values and then sorts them into descending order and then calculates the median. I have the program working fine except for when it receives values over 100, then the program spits out junk. I'm pretty sure the error is in my sorting procedure or my display list procedure. Here's the code for where I think the problem may lie. Full code on pastebin here: http://pastebin.com/5MdWijRa

;sort list
Sort            PROC
    push    ebp
    mov     ebp, esp
    mov     edi, [ebp + 12]
    mov     ecx, [ebp + 8]
    dec     ecx             ;outer loop is set to one less than request
    mov     ebx, 0          ;k=0

L1:
    mov     eax, ebx    ; i = k

    mov     edx, eax    
    inc     edx         ; j = k+1
    push    ecx             ;store the value of the outer loop
    mov     ecx, [ebp + 8]  ; inner loop is set to request

L2:
    cmp     ecx,0
    je      exchangeNext
    mov     esi, [edi + edx*4]  ; store element j of the array 
    cmp     esi, [edi + eax*4]  ;compare to element i 
    jg      greater             
    inc     edx
    loop    L2


greater:
    cmp     ecx,0
    je      exchangeNext
    mov     eax, edx        ; i = j
    inc     edx             ;increase j for the next iteration of the for loop
    loop    L2

exchangeNext:
    lea     esi, [edi+ebx*4]                ;saved to work like a temp variable
    push    esi             ;saved to work like a temp variable
    lea     esi, [edi+eax*4]    ; swapping array[k] and array [i]
    push    esi
    call    exchange
    pop     ecx             ;restore outer loop value
    inc     ebx             ;move forward through the outer loop
    loop    L1

    pop     ebp
    RET     8
Sort        ENDP

exchange    PROC
    pushad
    mov     edx, [edi+eax*4]    ; store the value of array[i]
    mov     esi, [edi+ebx*4]    ; store the value of array[k]
    mov     [edi+eax*4], esi    ; switch the values
    mov     [edi+ebx*4], edx
    popad

    RET     8
exchange    ENDP

;display list 
DisplayList     PROC

;Set up the stack
    push    ebp
    mov     ebp,esp
    mov     edx, [ebp + 16]     ;address of the title string
    mov     esi, [ebp + 12]     ;address of the array
    mov     ecx, [ebp + 8]      ; set request as the loop control
    mov     ebx, 0              ;keep count of how many numbers are printed

;Display the title
    call    WriteString         
    call    CrLf

;Display the numbers
Show:
    mov     eax, [esi]
    call    WriteDec
    mov     edx, OFFSET space
    call    WriteString
    add     esi, 4              ;Move to the next element in the array
    inc     ebx                 ;Counter 
    cmp     ebx, 10
    je      printLine       
    loop    Show
    cmp     ecx, 0
    jmp     endShow

printLine:
    call    CrLf            ;Print to the next line
    mov     ebx, 0          ;reset ebx
    loop    show    

endShow:
    call    CrLf
    pop     ebp
    RET     12
DisplayList     ENDP

Solution

  • This line is causing the mess:

    mov     ecx, [ebp + 8]  ; inner loop is set to request
    

    While the beginning of the inner loop increases (inc ebx and descendants), the amount of the repeats stays on [ebp+8], which shifts the end of the loop out of the bounds of the array ([ebp + 12]). The start value of the counter (ECX) should decrease as well.

    Insert that line just before the above line:

    dec     dword ptr [ebp + 8]
    

    Some might think that this is a quick and dirty solution. I "abuse" an argument to the function as local variable.