0

I am attempting to build a bubble sort that follows this algorithm:

   iterate = 0             ; reset outer loop condition
   for i = 0 to N-2
      if X[i] > X[i+1] then
            swap X[i], X[i+1]
            iterate = 1    ; this pass did at least 1 swap: not done
Until iterate = 0

I obtained this code, but my array for X is creating Error A2042 for the large values (which are necessary in this instance), and therefore can't look into the debugger.

TITLE DISPLAY
      .MODEL SMALL
      .386
      .STACK
      .DATA
X     SWORD 4, 16, 28, 88, 100, 32766, -16374, -19650, -22926, -56, -44, -32, -20, 3282,
-6546, -9822, -13098, 22938, -116, -68, -104, -92, 40, 16, -3270, 26214, 6558,
16386, 29490, 13110, 9834, 52, -128, -80, -8, 19662, -26202, -29478, 64, 76
count EQU (LENGTHOF X)                        ;two less than X

.code
.startup
;Program
    MOV DX, count
    L0:
        MOV CX, DX
        SUB CX, 2
        LEA SI, X

        L1:
            MOV AX, WORD PTR [SI]        
            MOV BX, WORD PTR [SI+2]
            CMP AX, BX
            JLE common                 ; If AX <= BX, skip the below two lines
            MOV WORD PTR [SI+2], AX  ; Switch values: former BX to AX
            MOV WORD PTR [SI], BX    ; Switch values: former AX to BX
            common:
            ADD SI, 2
            LOOP L1

        DEC DX
        JNZ L0

.exit
end

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Jordan Means
  • 41
  • 1
  • 5
  • Your algorithm has weird indenting. `iterate = 0` should be part of the same outer loop as the `for` loop, so it should be indented to the same column as the `for i` statement. – Peter Cordes Mar 21 '20 at 01:08
  • Also, your upper bound can shrink so you don't have to loop all the way from `0` to `N-2` every outer-loop iteration. See [Bubble Sort: An Archaeological Algorithmic Analysis](https://users.cs.duke.edu/~ola/papers/bubble.pdf). See also [Assembly bubble sort swap](https://stackoverflow.com/q/11497966) for a nice bubble sort (32-bit code but could easily be ported to 16). It doesn't use the early-out check; if you want to make simple O(N^2) sorting more efficient, normally you'd use a better algorithm like InsertionSort instead of complicating BubbleSort with a "did any swaps?" check. – Peter Cordes Mar 21 '20 at 01:18
  • @PeterCordes I apologize for the indention issues. – Jordan Means Mar 21 '20 at 02:38
  • You don't need to apologize, just [edit] to fix it. – Peter Cordes Mar 21 '20 at 02:40
  • @PeterCordes Okay. I did so. I also edited the code in accordance to what zx485 suggested, yet the Error A2042 for Line 6 still remains, along with undefined symbol errors for X for anywhere X is called (lines 12 and 15). – Jordan Means Mar 21 '20 at 03:13
  • IDK, I don't see any obvious problem. What if you simplify to a much smaller list like `X SWORD 1, 2`? If that assembles, then try some of the larger values and find out which one is the problem, or if there was some other problem. If not even that works, maybe try a different name than `X`, like `arrayX` or something that's definitely not already defined by some macro or library. I'd hope that `X` would be fine, but I don't use MASM. – Peter Cordes Mar 21 '20 at 03:16
  • @PeterCordes Interestingly, I left only the first five numbers in the array, `arrayX SWORD 4, 16, 28, 88, 100`, and the code is assembled. – Jordan Means Mar 21 '20 at 03:23
  • i.e. make a [mcve] that demonstrates getting this error message. It doesn't have to be a useful program or runnable, just something you can feed to the assembler that still gives this error. – Peter Cordes Mar 21 '20 at 03:23
  • @PeterCordes So, what I'm seeing from the MRE is that the code assembles until I put in the second-to-last number in the array, 64. Then, the error pops up. – Jordan Means Mar 21 '20 at 03:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210044/discussion-between-jordan-means-and-peter-cordes). – Jordan Means Mar 21 '20 at 03:41

1 Answers1

1

The error

A2042 statement too complex

occurs because you try to fit SWORD values into your SBYTE array.

  • SBYTE can contain values from -128 to 127
  • SWORD can contain values from -32768 to 32767.

Your array X is of type SBYTE, but you try to fit SWORD values into it. Hence the error. So change your array to

X SWORD 4, 16, 28, 88, 100, ...

and adjust the indices to step by 2 bytes instead of 1. Use AX instead of AL to hold 2-byte words.


Also (some further hints - without the aspiration of completion):

  • Change your jump JNZ l0 to JNZ L0. MASM is case-sensitive (unless set otherwise).
  • Change MOV CX, count to MOV CX, DX to avoid overflow in the inner loop

This would simplify your inner loop to the following:

MOV CX, DX
SUB CX, 2
LEA SI, X

L1:
  MOV AX, WORD PTR [SI]        
  MOV BX, WORD PTR [SI+2]
  CMP AX, BX
JLE common                 ; If AX <= BX, skip the below two lines
  MOV WORD PTR [SI+2], AX  ; Switch values: former BX to AX
  MOV WORD PTR [SI], BX    ; Switch values: former AX to BX
common:
  ADD SI, 2
  LOOP L1
zx485
  • 28,498
  • 28
  • 50
  • 59
  • I changed `SBYTE` to `SWORD` and A2042 still showed up at the only error. – Jordan Means Mar 21 '20 at 02:37
  • In which line does it occur? You also need to fix this line: `CMP, [SI+1]`, because it's not a valid instruction. – zx485 Mar 21 '20 at 02:40
  • Line 9. As a result, it creates another error with an "Error A2006 undefined symbol X" on line 20. And to change the indices, do I have to do `count EQU 38` instead of `count EQU 39`, to be sure? – Jordan Means Mar 21 '20 at 02:42
  • You have the invalid directive `.startup` in your code. Remove it, or replace it by `startup:`. – zx485 Mar 21 '20 at 02:45
  • 1
    Also, see [this link](http://www.c-jump.com/CIS77/ASM/Instructions/I77_0140_type_lengthof_sizeof.htm) relating to your `count` situation. `count EQU (LENGTHOF X)` is what you want. – zx485 Mar 21 '20 at 02:46
  • I changed startup to `startup:` and the error remains. – Jordan Means Mar 21 '20 at 02:57
  • Unfortunately, I cannot test the code. And on a side note, I am very sleepy. cu tomorrow. – zx485 Mar 21 '20 at 03:01