0

I am new to assembly and I am trying to write a program that gets five user inputed numbers, stores them in variables num1-num5, sorts them(without using arrays) with num5 having the greatest value and num1 having the lowest value, and then displays the sorted numbers. I am having trouble figuring out how to approach this. I got the 5 numbers and stored them in the variables but I am confused as to how to start with sorting. I have tried a few things but I keep getting errors. This is my code that I can actually get running but it isn't working the way I want it to.

  TITLE MASM Template        (main.asm) 

   INCLUDE Irvine32.inc 
 .data 



  getnumber byte "Please enter a number between 0 and 20",0ah,0dh,0 




 num1 byte  0
 num2 byte  0
 num3 byte  0
 num4 byte  0
 num5 byte  0 


 .code 
  main PROC 
call Clrscr 
;************* get the information from the user******************* 


mov edx, offset getnumber      ;ask to input number 
call writestring 
call readint 
mov bl, al  
mov num1, bl               ;get the number and move to num1 variable 

mov edx, offset getnumber      ;ask to input number 
call writestring 
call readint 
mov bl, al
mov num2, bl                ;get the number and move to num2 variable

mov edx, offset getnumber      ;ask to input number 
call writestring 
call readint 
mov bl, al 
mov num3, bl                ;get the number and move to num3 variable


    mov edx, offset getnumber    ;ask to input number
call writestring 
call readint 
mov bl,al
mov num4, bl             ;get the number and move to num4 variable

mov edx, offset getnumber      ;ask to input number 
call writestring 
call readint 
mov bl, al
mov num5, bl              ;get the number and move to num5 variable



;***show the user inputed numbers****
mov al, num1 
call writeint 

mov al, num2 
call writeint 

mov al,num3 
call writeint 

mov al, num4 
call writeint 

mov al,num5 
call writeint 

;*****start comparing***
cmp bl,num5
jl jumptoisless
    jg jumptoisgreater

jumptoisless:

call writeint

jumptoisgreater:
mov bl, num5
mov dl, num4

mov num5, dl
mov num4,  bl

call writeint 

jmp imdone


    imdone:
    call dumpregs

     exit 
    main ENDP 

    END main
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
KidKool
  • 43
  • 4
  • I assume you need to swap values in addition to comparing values. Try something simpler first, use compares and swaps to get the largest value into num5. Next try getting largest value into num5 and smallest value into num1. – rcgldr Oct 29 '16 at 00:04
  • why don't you want to use arrays? (I'm curious) – Ped7g Oct 29 '16 at 01:11
  • 2
    "I have tried a few things but I keep getting errors" is not a [mcve]. If you're just asking about algorithms for comparison-based sorting, those are easy to google. – Peter Cordes Oct 29 '16 at 06:03
  • defacing your question is not ok. People put effort into answering it. – Peter Cordes Nov 02 '16 at 02:58

1 Answers1

2

Some notes to your code:

call readint 
mov bl, al
mov num2, bl

Why don't you simply store al directly to memory, as: mov [num2],al? You don't use the bl anyway.


Except here:

;*****start comparing***
cmp bl,num5
jl jumptoisless
jg jumptoisgreater

Where I would be afraid what call writeint does to ebx (or you did your homework, and you know from head that call writeint preserves ebx content?).

And if the ebx is preserved, then bl contains still num5 from the input, so it will be equal.

Funnily enough, when equal, you will continue with jumptoisless: part of code, which will output some leftover in al, and then it will continue to jumptoisgreater: part of code, so effectively executing all of them.

Can you watch the CPU for a while in debugger, while single stepping over the instructions, to understand a bit better how it works? It's a state machine, ie. based on the current values in registers, and content of memory, it will change the state of registers and memory in the deterministic way.

So unless you jump away, next instructions is executed after the current one, and jl + jg doesn't cover "equal" state (at least you do cmp only once, so hopefully you understand the jcc instructions don't change flags and both jl/jg operate on the same result of cmp in flags). The Assembler doesn't care about name of your labels, and it will not warn you the "isgreater" code is executed even when "isless" was executed first.

About how to solve your task:

Can't think of anything reasonably short, unless you start to work with num1-num5 memory as array, so you can address it in generic pointer way with index. So I will gladly let you try on your own, just a reminder you need at least n*log_n compares to sort n values, so if you would write very effective sort code, you would need at least 5*3 = 15 cmp instructions (log2(5) = 3, as 23 = 8).

On the other hand an ineffective (but simple to write and understand) bubble sort over array can be done with single cmp inside two loops.


rcgldr made me curious, so I have been trying few things...

With insertion sort it's possible to use only 8x (at most) cmp (I hope the pseudo-syntax is understandable for him):

Insert(0, num1)
// ^ no cmp
Insert((num2 <= [0] ? 0 : 1), num2)
// ^ 1x cmp executed
Insert((num3 <= [0] ? 0 : (num3 <= [1] ? 1 : 2)), num3)
// ^ at most 2 cmp executed
Insert((num4 <= [1] ? (num4 <= [0] ? 0 : 1) : (num4 <= [2] ? 2 : 3)), num4)
// ^ always 2 of 3 cmp executed
Insert((num5 <= [1] ? (num5 <= [0] ? 0 : 1) : (num5 <= [2] ? 2 : (num5 <= [3] ? 3 : 4))), num5)
// ^ at most 3 of 4 cmp executed

=> total at most 8 cmp executed.

Of course doing the "insert" with "position" over fixed variables would be total PITA... ;) So this is half-joke proposal just to see if 8x cmp is enough.

("6 compares" turned out to be my brain-fart, not possible AFAIK)

Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • 5 numbers can be sorted using 9 compare / swaps sequences. – rcgldr Oct 29 '16 at 01:46
  • @rcgldr: oh, I mixed element accesses with compares, so actually there may be only 8 compare solution? Whatever, I'm not going even to think about breaking the generic algorithm down into specific steps and verify it's 9, I will gladly believe you. :) – Ped7g Oct 29 '16 at 02:04
  • @rcgldr: I don't see it. I think I can sort 5 numbers in 6 compares. I will add it to answer for fun in few minutes... – Ped7g Oct 29 '16 at 02:15
  • I was thinking compare / swap sequences, not insertion sort type sequence where multiple values are shifted after a single compare. The compares can be done like binary search. Worst case total number of operations (read, write, compare) is less using insertion sort method versus compare swap, except I didn't count branches. However, 9 compare/swaps would take less code. – rcgldr Oct 29 '16 at 04:26
  • With only 5 numbers, they fit in registers with 2 left over (beyond ESP) so you can use cmp/cmov to implement comparators for a sorting network. There is no 8-bit CMOVcc, so you can't easily take advantage of AH/CH/DH. – Peter Cordes Oct 29 '16 at 05:59
  • @PeterCordes - a sorting network would take 9 compare / swaps, just one less than the 10 compare / swaps that a conventional bubble sort would require. For an intro assembler class, a bubble sort approach should be good enough (using a sorting network might look like the student got too much help). – rcgldr Oct 30 '16 at 22:46
  • @rcgldr I'm not interested at all in "too much help"; Once a question is asked, if I'm going to spend time thinking about it, I'm interested in the optimal solution (either speed or code-size). A merely good-enough solution to a question like this isn't interesting. A 5-integer insertion-sort implementation based on pseudocode from wikipedia is pretty easy for anyone that knows the language in question. – Peter Cordes Oct 31 '16 at 01:08
  • 1
    @PeterCordes while I'm certainly interested in good solutions too, I think the different sort algorithms are well known. And I don't think specialization for 5 items is worth of the effort, especially with no-array constraint. If I would ever need 5 item sort, I bet I would be able to somehow vectorize the data into array. Then I would dig into sort. You know for performance there's no other way around anyway, first the locality of data and structure must be optimized, then number of compares and writes... – Ped7g Oct 31 '16 at 01:40
  • 1
    Oh right, I forgot about the no-array constraint here. Since you couldn't loop over an array anyway, might as well just load them all into registers. (Of course I agree, in real code you'd probably want those named globals to be contiguous, or at least have constant stride, so you could index into them, if you didn't want a fully-unrolled sorting network.) – Peter Cordes Oct 31 '16 at 01:51
  • 2
    @Ped7g - [sorting networks](http://en.wikipedia.org/wiki/Sorting_network) are known (for up to 17 elements), but not well known, so I'm not sure how to classify them. Outside of hardware, sorting networks aren't that practical for 8 or more elements. Producing an optimal length (fewest number of comparators) sorting network is complex once at 5 or so elements. – rcgldr Oct 31 '16 at 01:51
  • @rcgldr: right, that's why you use http://pages.ripco.net/~jgamble/nw.html (first google hit for `sorting network generator`) to generate a sorting network for you instead of doing it yourself. There are a few algorithms to choose from for generating sorting networks. Since we're not using SIMD here, there are no considerations like trying to work in groups of 4, or minimizing shuffles within vectors. The traditional criteria of depth and number of comparisons map exactly to ILP and instruction count. – Peter Cordes Oct 31 '16 at 03:08
  • @rcgldr There has been some interesting work on SIMD sorting networks. (esp. with shufps for moving data between vectors). See the [list of links at the bottom of this answer](http://stackoverflow.com/a/35960856/224132), and also [Furtak's 2007 paper](https://webdocs.cs.ualberta.ca/~amaral/papers/furtak-spaa07.pdf). I haven't looked at this for a while, so I forget if there were other good links somewhere. But yeah, you typically only use a SIMD sorting network for the small sub-problems of a merge-sort or something. – Peter Cordes Oct 31 '16 at 03:17