Sort Array (Smallest->Largest) (NASM - Beginner)

Viewed 274

Hey guys I'm completely new to NASM I've made about 5 projects before in this and this one is my most complicated. I'm trying to accomplish sorting an array from lowest value to highest value. Currently I'm running into a few issues. I'm learning under someone at the moment so there will be some custom stuff that I'll explain before I present the code:

I'm using a template provided for each file, so there will be some instructions that are unused. Specifically the ones above "Code starts here" and below "code ends here"

call read_int takes input from terminal and puts the value into eax.

call print_int prints the value of eax into the terminal.

call print_char prints the value of al into the terminal.

Current issues with the code

I believe the main issue why this code doesn't work is due to the way I handled the comparison between the index of the smallest value and the current value.

what is currently occuring

Example Input

1
2
3
4
5
6
7
8
9
10

Example Output

1 1 1 1 1 1 1 1 1 1 

Example Input

235
5476
567
124
6543
75
214
6754
865
143

Example Output

75 124 124 235 235 235 999999999 999999999 999999999 999999999

what is intended

Example Input: 1 2 3 4 5 6 7 8 9 10
Example Output: 1 2 3 4 5 6 7 8 9 10

Example Input

235
5476
567
124
6543
75
214
6754
865
143

Example Output

75
124
143
214
235
567
865
5476
6543
6754

Explanation Notes

edi's starting value is set as a large number in order to be small for the first comparison.

indexSmall's values are all set to -1 to avoid having the smallest index line with the first comparison

My indentation is probably terrible, but this method helps my brain figure out what's going on better.

When I finish this I'll be cleaning up some labels and other variable names, so don't pull your hair out! :)

Any help would be amazing, I've been stuck on this for a while.

EDIT: To clarify, I'm requesting help on setting up the indexing check for this sorting algorithm correctly. I believe that it is not set up correctly and is giving me garbage info as output when currently used. Here is the current setup for the program:

Step 1 Get user input.

Step 2 Find smallest value.

Step 3 Check to see if the smallest value's index matches with an index in the array indexSmall. If it does, skip that value. If it doesn't push that value to the label Smaller.

Step 4 The label Smaller will check to see if that value is less than the current smallest value stored. edi is used to store the current smallest value in the loop.

Step 5 EndSearch stores all my variables and info into the correct arrays. EndSearch is looped 10 times to go through the entire array.

Step 6 Each variable is printed by walking through the sortedArray with a space between each one.

I believe the issue with the current set up is the implementation of the index check, but I could be wrong. I was hoping someone could help clarify what might be going wrong with my program here. Thanks!

%include "/usr/local/share/csc314/asm_io.inc"

segment .data

    sortedArray DD 0,0,0,0,0,0,0,0,0,0
    inputArray DD 0,0,0,0,0,0,0,0,0,0,
    indexSmall DD -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
    arrayCount DD 11
    counter DD 0
    indexHolder DD 0
    

segment .bss

segment .text
    global  asm_main

asm_main:
    push    ebp
    mov     ebp, esp
    ; ********** CODE STARTS HERE **********

    mov edx, 0
    ReadInt:
        call read_int
        mov DWORD [inputArray + edx * 4], eax
        add edx, 1
        CMP edx, 10
        JE EndReadInt
        JMP ReadInt
    EndReadInt:

    mov esi, 0
    Start:
        mov edx, -1
        mov ecx, 0
        mov edi, 999999999
        FindSmallest:
            add edx, 1
            add ecx, 1
            CMP ecx, DWORD [arrayCount]
            JGE EndSearch
            mov eax, DWORD [inputArray + edx * 4]
            mov ebx, DWORD [inputArray + ecx * 4]
            CMP edx, DWORD [indexSmall + esi*4]
            JE Skip
            JMP NoSkip
            Skip:
                JMP FindSmallest
            NoSkip:
                CMP eax, ebx
                JLE Smaller
                JMP FindSmallest
            Smaller:
                CMP eax, edi
                JLE Smallest
                JMP FindSmallest
                Smallest:
                    mov edi, eax
                    sub DWORD [arrayCount], 1
                    mov DWORD [indexHolder], edx
                    JMP FindSmallest
    EndSearch:
        mov eax, DWORD [counter]
        mov DWORD [sortedArray +  eax* 4], edi
        mov eax, DWORD [indexHolder]
        mov DWORD [indexSmall + esi*4], eax
        add esi, 1
        add DWORD [counter], 1
        mov eax, DWORD [counter]
        CMP eax, 10
        JE End
        JMP Start
    End:

    mov edx, 0
    mov al, ' '
    PrintInt:
        mov eax, DWORD [sortedArray + edx*4]
        call print_int
        mov al, ' '
        call print_char
        add edx, 1
        CMP edx, 10
        JE EndPrintInt
        JMP PrintInt
    EndPrintInt:

        

    ; *********** CODE ENDS HERE ***********
    mov     eax, 0
    mov     esp, ebp
    pop     ebp
    ret

EDIT 2: Contents of asm.io

    extern  read_int, print_int, print_string
    extern  read_char, print_char, print_nl
    extern  sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack

%macro  dump_regs 1
    push      dword %1
    call      sub_dump_regs
%endmacro


;
; usage: dump_mem label, start-address, # paragraphs
%macro  dump_mem 3
    push     dword %1
    push     dword %2
    push     dword %3
    call     sub_dump_mem
%endmacro

%macro  dump_math 1
    push     dword %1
    call     sub_dump_math
%endmacro

%macro  dump_stack 3
    push     dword %3
        push     dword %2
    push     dword %1
        call     sub_dump_stack
%endmacro
1 Answers

Solved.

Below is code for sorting an array of 10 digits from smallest to greatest.

x86 NASM

Debugged with SASM.

Thanks for the help y'all. Great recommendation to install some debuggers and run through the code. Typically I'm not the type to use a debugger but this one really helped!


segment .data

ints DD 61,61,75,14,11,77,100,9,39,39
counts DD 1000

segment .bss

segment .text

global _main
_main:
    mov ebp, esp; for correct debugging
    push    ebp
    mov     ebp, esp
    ; ********** CODE STARTS HERE **********

    mov eax, 9
    mov ebx, 8
    MinFinder:
    sub DWORD [counts], 1
    CMP DWORD [counts], 0
    JE Print
    CMP ebx, -1
    JE EndRead
    mov ecx, [ints + eax*4]
    mov edx, [ints + ebx*4]
    CMP ecx, edx
    JL LessThan
    sub eax, 1
    sub ebx, 1
    JMP MinFinder

    LessThan:
    mov [ints + eax*4], edx
    mov [ints + ebx*4], ecx
    sub eax, 1
    sub ebx, 1
    JMP MinFinder

    ; *********** CODE ENDS HERE ***********
    mov     eax, 0
    mov     esp, ebp
    pop     ebp
    ret
Related