Search code examples
sortingassemblybubble-sort

Sorting Integers in Assembly


Project is to create a bubble sort algorithm in assembly that will sort a given list of integers. I've got ascending down and my output is correct to some extent. It seems when combining the order of numbers gets mixed up, here's what I mean:

10 -20 5 12 30 -5 -22 55 52 0

Number of integer = 10 Ascend_or_Descend = 1

0 5 10 12 30 52 55 -22 -20 -5

Here's the code including the main method which was given to test:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>

int sorter (int* list, int count, int opcode)
{
__asm
{
mov eax, 0          ; zero out the result
mov ebx, opcode     ; move opcode to ebx for comparison

mov ecx, count; //OuterLoop counter
cmp ecx, 1; //check length  
jle Return;  

OuterLoop:
   mov edi, list; //move in list    
   push ecx; 

   mov ecx, count; 
   dec ecx; //Decrement inner loop
InnerLoop:
   mov eax, [edi]; //First Value in list
   cmp ebx, 1; 
   je  Ascending; 
   cmp eax, [edi+4]; //next int is 4 bits away
   jb  Swap; 
   jmp Continue; 
Ascending:
   cmp eax, [edi+4]; //Again compare with next int
   ja  Swap; //if no swap
   jmp Continue; 
Swap:
   mov edx, [edi+4]; //Move to temp register
   mov [edi+4], eax; //Move stored value there
   mov [edi], edx; //Return temp value to list
Continue:
   add edi, 4; //Increment to move to next int
   loop InnerLoop; 
   pop ecx; //reset counter
   loop OuterLoop; 
Return:; 
}

}


int main(int argc, char** argv)
{
int numlist[1000], asc;
FILE *fptr;

int i = 0;

if (argc != 3)
{
    printf("Usage: %s filename asc_des\n", argv[0]);
    return 1;
}

asc = atoi (argv[2]);
asc = (asc == 1) ? 1 : 2;

printf("\n");

fptr = fopen((argv[1]), "rtc");
if (fptr == NULL)
  printf( "File %s was not opened\n",argv[1] );
else
{
  /* Set pointer to beginning of file: */
  fseek( fptr, 0L, SEEK_SET );

  /* Read data from file: */
  while ( fscanf(fptr, "%d", &numlist[i]) != EOF )
  {
      printf( "%d ", numlist[i] );
      i++;
  }

  printf( "\n\nNumber of integer = %d\n", i );
  printf( "Ascend_or_Descend = %d\n\n", asc );
  fclose( fptr );
  }

  sorter( numlist, i, asc);

  for (int j = 0; j < i; j++)
      printf( "%d ", numlist[j] );

  printf("\n");

  return 0;
  }

Solution

  • From Intel's manual:

    The terms “above” and “below” are associated with the CF flag and refer to the relation between two unsigned integer values. The terms “greater” and “less” are associated with the SF and OF flags and refer to the relation between two signed integer values

    By using jb and ja you're treating the result of the comparison as the result of an unsigned comparison, hence why the signed numbers end up at the end of the sorted array (e.g. -22 when interpreted as an unsigned 32-bit value is 4294967274).

    You should be using jl instead of jb, and jg instead of ja.